一、生成隨機(jī)數(shù)的方法
第一種:new Random();
第一種需要借助java.util.Random類來產(chǎn)生一個隨機(jī)數(shù)發(fā)生器,也是最常用的一種,構(gòu)造函數(shù)有兩個,Random()和Random(long seed)。第一個就是以當(dāng)前時間為默認(rèn)種子,第二個是以指定的種子值進(jìn)行。產(chǎn)生之后,借助不同的語句產(chǎn)生不同類型的數(shù)。種子就是產(chǎn)生隨機(jī)數(shù)的第一次使用值,機(jī)制是通過一個函數(shù),將這個種子的值轉(zhuǎn)化為隨機(jī)數(shù)空間中的某一個點(diǎn)上,并且產(chǎn)生的隨機(jī)數(shù)均勻的散布在空間中。以后產(chǎn)生的隨機(jī)數(shù)都與前一個隨機(jī)數(shù)有關(guān)。
Random 對象的 nextInt(int) 方法,這個方法將生成 0 ~ 參數(shù)int之間隨機(jī)取值的整數(shù)
? 下面以獲取5-10之間的隨機(jī)數(shù)為例:
import java.util.Random;
public class random {
public static void main(String[] args){
? ? Random rand = new Random();
? ? System.out.println(rand.nextInt(6) + 5);
}
}
同理:下列為獲取隨機(jī)兩位數(shù),隨機(jī)三位數(shù)的方法:
rand.nextInt(90) + 10; //隨機(jī)兩位數(shù)
rand.nextInt(900) + 100;//隨機(jī)三位數(shù)
總結(jié):想要得到某個范圍內(nèi)的隨機(jī)數(shù):
Random rand = new Random();
? int randomFigure=rand.nextInt(MAX - MIN + 1) + MIN; // randomFigure將被賦值為一個 MIN 和 MAX 范圍內(nèi)的隨機(jī)數(shù) 。
Random類提供的方法: API
- nextBoolean()
- 返回均勻分布的 true 或者 false
- nextBytes(byte[] bytes)
- nextDouble()
- 返回 0.0 到 1.0 之間的均勻分布的 double
- nextFloat()
- 返回 0.0 到 1.0 之間的均勻分布的 float
- nextGaussian()
- 返回 0.0 到 1.0 之間的高斯分布(即正態(tài)分布)的 double
- nextInt()
- 返回均勻分布的 int
- nextInt(int n)
- 返回 0 到 n 之間的均勻分布的 int (包括 0,不包括 n)
- nextLong()
- 返回均勻分布的 long
- setSeed(long seed)
- 設(shè)置種子
只要種子一樣,產(chǎn)生的隨機(jī)數(shù)也一樣: 因?yàn)榉N子確定,隨機(jī)數(shù)算法也確定,因此輸出是確定的!
Random random1 = new Random(10000);Random random2 = new Random(10000); for (int i = 0; i < 5; i++) {? ? System.out.println(random1.nextInt() + " = " + random2.nextInt());}
結(jié)果:
-498702880 = -498702880 -858606152 = -858606152 1942818232 = 1942818232 -1044940345 = -1044940345 1588429001 = 1588429001
第二種:Math.random();
第二種方法返回的數(shù)值是[0.0,1.0)的double型數(shù)值,由于double類數(shù)的精度很高,可以在一定程度下看做隨機(jī)數(shù),借助(int)來進(jìn)行類型轉(zhuǎn)換就可以得到整數(shù)隨機(jī)數(shù)了。
下面以獲取5-10之間的隨機(jī)數(shù)為例:
? public static void main(String[] args)
{? ?
? ? int randomFigure = (int) (5+Math.random()*6);
? ? System.out.println(randomFigure);
}
總結(jié):想要得到某個范圍內(nèi)的隨機(jī)數(shù):
(數(shù)據(jù)類型)(MIN+Math.random()*(MAX-MIN+1))。
實(shí)現(xiàn)原理:
當(dāng)?shù)谝淮握{(diào)用 Math.random() 方法時,自動創(chuàng)建了一個偽隨機(jī)數(shù)生成器 ,實(shí)際上用的是 new java.util.Random()。當(dāng)接下來繼續(xù)調(diào)用 Math.random() 方法時,就會使用這個新的偽隨機(jī)數(shù)生成器 。
源碼如下:
public static double random() {? ? ? ?
Random rnd = randomNumberGenerator;? ? ? ?
if (rnd == null)
rnd = initRNG(); // 第一次調(diào)用,創(chuàng)建一個偽隨機(jī)數(shù)生成器? ? ? ?
return rnd.nextDouble();? ? ? ?
}
private static synchronized Random initRNG() {
? ? ? ? Random rnd = randomNumberGenerator;? ? ? ?
? ? ? ? return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd; // 實(shí)際上用的是new java.util.Random()? ? ? ?
? ? ? ? }
initRNG() 方法是 synchronized(同步)的,因此在多線程情況下,只有一個線程會負(fù)責(zé)創(chuàng)建偽隨機(jī)數(shù)生成器 (使用當(dāng)前時間作為種子),其他線程則利用該偽隨機(jī)數(shù)生成器 產(chǎn)生隨機(jī)數(shù)。
因此 Math.random() 方法是線程安全的。
第三種:currentTimeMillis();
至于第三種方法雖然不常用,但是也是一種思路。方法返回從1970年1月1日0時0分0秒(這與UNIX系統(tǒng)有關(guān))到現(xiàn)在的一個long型的毫秒數(shù),取模之后即可得到所需范圍內(nèi)的隨機(jī)數(shù)。
? 下面以獲取5-10之間的隨機(jī)數(shù)為例:
public class random {
public static void main(String[] args){
long l = System.currentTimeMillis();
int randomFigure = (int)l%6+5;
System.out.println(randomFigure);
}
}
總結(jié):想要得到某個范圍內(nèi)的隨機(jī)數(shù):
long l = System.currentTimeMillis();
int randomFigure = (int) (l%(MAX-MIN)+MIN);
二、變量的定義
1.整數(shù)類型變量
字節(jié)型(byte)、短整型(short)、整形(int)和長整形(long)
4中類型變量所占存儲空間的大小及取值范圍如表2-1所示。
在表2-1中,占用空間是指不同類型的變量占用的內(nèi)存大小,例如,一個int類型的變量會占用4個字節(jié)大小的內(nèi)存空間;取值范圍是指變量存儲的值不能超出的范圍
需要注意的是,在為一個long類型的變量賦值時,所賦值的后面要加上字母L(或小寫字母1)。具體示例如下:
long num =2200000000L;? ?
//所賦的值超出了int類型的取值范圍,后面必須加上字母L
//所賦的值沒有超出int類型的取值范圍,可加可不加
long num =198L;? ? ? ? ?
//所賦的值未超出int類型的取值范圍,后面可以加上字母L
long num =198;? ? ? ? ? ?
//所賦的值未超出int類型的取值范圍,后面可以省略字母L
2.浮點(diǎn)類型變量
浮點(diǎn)類型變量用于存儲小數(shù)數(shù)值。
double類型所表示的浮點(diǎn)數(shù)比float類型更精確,兩種浮點(diǎn)類型變量所占存儲空間的大小及取值范圍如表2-2所示
在表2-2中,取值范圍中的E(也可寫為小寫字母e)表示以10為底的指數(shù),E后面的“+”和“-”代表正指數(shù)和負(fù)指數(shù)。
在Java中,小數(shù)會被默認(rèn)為double類型的值,因此在為一個float類型的變量賦值時,在所賦值的后面一定要加上字母F(或者小寫字母f),而為double類型的變量賦值時,可以在所賦值的后面加上字母D(或者小寫字母d),也可以不加。具體示例如下:
float f = 123.4f;? ? //為一個float類型的變量賦值,后面必須加上字母f
double d1 =100.1;? ? //為一個double類型的變量賦值,后面可以省略字母d
double d2 =199.3d;? //為一個double類型的變量賦值,后面可以加上字母d
在程序中也可以為一個浮點(diǎn)數(shù)類型變量賦予一個整數(shù)數(shù)值。例如,下面的寫法也是可以的。
float f =100;? //聲明一個float類型的變量并賦整數(shù)值
double d =100; //聲明一個double類型的變量并賦整數(shù)值
3.字符類型變量
在Java中,字符類型變量用char表示,用于存儲一字符。
Java中每個char類型的字符變量都會占用2個字節(jié)。
在給char類型的變量賦值時,需要用一對英文半角格式的單引號(' ')把字符括起來,如'a'。
在計算機(jī)的世界里,所有文字、數(shù)值都只是一連串的0與1,這些0與1是機(jī)器語言,人類難以理解,于是就產(chǎn)生了各種方式的編碼,使用一個數(shù)值代表某個字符,如常用的字符編碼系統(tǒng)ASCII。
雖然各類編碼系統(tǒng)加起來有數(shù)百種之多,卻沒有一種包含足夠多的字符、標(biāo)點(diǎn)符號和常用的專業(yè)技術(shù)符號。這些編碼系統(tǒng)之間可能還會相互沖突。也就是說,不同的編碼系統(tǒng)可能會使用相同的數(shù)值標(biāo)識不同的字符,這樣在數(shù)據(jù)跨平臺時就會發(fā)生錯誤。Unicode就是為了避免上述情況而產(chǎn)生的,它為每個字符制定了一個唯一的數(shù)值,因此,在任何語言、平臺、程序中都可以安心地使用。Java使用的就是Unicode字符嗎系統(tǒng),Unicode中的小寫字母a是用97表示的,在計算時,計算機(jī)會自動將字符轉(zhuǎn)換為所對應(yīng)的數(shù)值。
定義字符型變量的具體示例如下:
char c='a';? ? ? //為一個char類型的變量賦值字符a
char ch =97;? ? //為一個char類型的變量賦值整數(shù)97,相當(dāng)于賦值字符a
4.布爾類型變量
在Java中,使用boolean定義布爾類型變量,布爾類型變量只有true和false兩個值。定義布爾類型變量的具體示例如下:
boolean flag = false;? ? //定義一個boolean類型的比那里flag,初始值為false
flag =true;? ? ? ? ? ? ? //改變變量flag的值為true
三、StringBuilder
1.追加字符串 append()
StringBuilder sb = new StringBuilder("x");
sb.append("a"); // 在當(dāng)前字符串的尾部追加字符串a(chǎn) // xa
sb.append("b"); // 在當(dāng)前字符串的尾部追加字符串a(chǎn) // xab
2.替換字符串 replace(int start,int end,替換的內(nèi)容)
StringBuilder sb = new StringBuilder("天王蓋地虎");
sb.replace(1, 3, "博愛他"); // 替換下標(biāo)1-3的位置不包含3
sb.replace(0, 1, ""); // 替換下標(biāo)0-1的位置不包含1
System.out.println(sb); // 替換會產(chǎn)生新內(nèi)容
3.刪除字符串 delete(int start,int end)
StringBuilder sb = new StringBuilder();
sb.append("巴山楚水凄涼地,responsebility").delete(10, 12) // 按照下標(biāo)內(nèi)容刪除
.deleteCharAt(0); // 刪除指定位置內(nèi)容
System.out.println(sb);
4.指定下標(biāo)新內(nèi)容 insert(int start,任意數(shù)據(jù)類型)
StringBuilder sb = new StringBuilder("abcd");
// insert():在指定下標(biāo)位置,插入新內(nèi)容
sb.insert(2, "123")
.insert(2, true)
.insert(2, Math.PI);
5.字符串逆序 reverse()
// 字符串逆序
StringBuilder sb=new StringBuilder("甲乙丙丁");
sb.reverse(); // 逆序反轉(zhuǎn)
System.out.println(sb);
6.設(shè)置分隔符
// StringJoiner joiner = new StringJoiner("#"); // 設(shè)置分隔符
StringJoiner joiner = new StringJoiner("#", "@", "@"); // 設(shè)置分隔符
文章知識點(diǎn)與官方知識檔案匹配,可進(jìn)一步學(xué)習(xí)相關(guān)知識
四、面向?qū)ο笕筇匦?/p>
封裝其實(shí)是對外隱藏復(fù)雜細(xì)節(jié),提供簡單易用的接口,便于外界調(diào)用,從而提高系統(tǒng)的可擴(kuò)展性、可維護(hù)性。在Java中這種隱藏或公開是通過權(quán)限修飾符來實(shí)現(xiàn)的。
Java中類就是對具體事物的一種封裝,類中的方法等等也是一種封裝。我們把數(shù)據(jù)、一系列操作數(shù)據(jù)的函數(shù)封裝到方法中,然后通過權(quán)限修飾符控制哪些方法可以讓外知道,哪些只能自己知道,這樣就能減少核心的數(shù)據(jù)被外界獲取甚至破壞。
我們最初學(xué)習(xí)Java時,往往都是把代碼直接寫在main方法中的,但是隨著學(xué)習(xí)的深入,遇到的邏輯越來越復(fù)雜,我們發(fā)現(xiàn)只靠main方法是不能滿足全部需要的,這時候,我們開始在類中擴(kuò)展其他方法,最后通過main方法調(diào)用運(yùn)行。再后來我們逐漸開始去寫不同的類,甚至不同的業(yè)務(wù)模塊。這時候就會發(fā)現(xiàn),一個簡單的封裝能帶來多大的好處。
封裝的優(yōu)點(diǎn):
1.通過封裝,我們可以保護(hù)代碼被破壞,提高數(shù)據(jù)安全性。
2.使用者只能通過事先定制好的方法來訪問數(shù)據(jù),可以方便地加入控制邏輯限制對屬性的不合理操作。
3.通過封裝,我們提高了代碼的復(fù)用性(有些方法、類在很多地方都能多次反復(fù)使用)
4.通過封裝,帶來的高內(nèi)聚和低耦合,使用不同對象、不同模塊之間能更好的協(xié)同,同時便于修改,增強(qiáng)代碼的可維護(hù)性
5.高內(nèi)聚 :類的內(nèi)部數(shù)據(jù)操作細(xì)節(jié)自己完成,不允許外部干涉;
6.低耦合 :僅對外暴露少量的方法用于使用
比如說一個類最簡單的封裝就是把屬性隱藏起來,只提供 get和set 方法進(jìn)行操作:
public class Student {
//姓名
private String name;
//年齡
private int age;
//get方法獲取年齡
public int getAge() {
? ? return age;
}
//set方法修改年齡
public void setAge(int age) {
? ? if(age<0 ||age>100){
? ? ? ? return;
? ? }
? ? this.age = age;
}
//get方法獲取姓名
public String getName() {
? ? return name;
}
//set方法修改年齡
public void setName(String name) {
? ? this.name = name;
}
這樣在操作的時候外部通過 get和set 修改和獲取屬性,這樣的好處是我可以在get和set方法中隱藏一些其他的處理邏輯(比如在setAge里添加一些年齡的限制條件),且屬性沒有對外部暴露,也可以進(jìn)一步提高安全性。如果沒有進(jìn)行封裝,那任意調(diào)用屬性會導(dǎo)致數(shù)據(jù)的錯誤、混亂或安全性問題(比如年齡:如果所以調(diào)用沒有驗(yàn)證,那可能出現(xiàn)負(fù)數(shù)出現(xiàn))。
另外我們對一些邏輯的封裝可以極大的提高此段代碼的復(fù)用性,比方一個求和的方法:
public static void main(String[] args) {
? ? //求和
? ? int sum = 0;
? ? for(int i=1; i<=10 ; i++){
? ? ? ? sum = sum+i;
? ? }
? ? System.out.println(sum);
//封裝成方法后可以隨意調(diào)用,實(shí)現(xiàn)代碼的復(fù)用,如果不封裝,需要寫多段求和代碼才能實(shí)現(xiàn)
? ? System.out.println(getSum(10));
? ? System.out.println(getSum(100));
? ? System.out.println(getSum(20));
}
//把求和的邏輯封裝成一個方法
public static int getSum(int num){
? ? int sum = 0;
? ? for(int i=1; i<=num ; i++){
? ? ? ? sum = sum+i;
? ? }
? ? return sum;
}
3.2、 繼承
類和類之間有些也會具有一定的關(guān)系。比方說四邊形,可以分為正方形、長方形、菱形,他們不但繼承了四邊形的特征,也具有屬于自己的特征,這就是一種繼承的關(guān)系。
有時候我們希望基于某一個類進(jìn)行擴(kuò)展,使一個新類直接擁有基類的基本特征,而不需要重復(fù)去寫,這就是繼承的思想。比如說手機(jī)的逐步發(fā)展,最早的大哥大只有通話功能,后來的按鍵手機(jī)增加則界面等操作,再到現(xiàn)在的智能手機(jī),它們不是一蹴而就的,而是通過在原有的功能上再增加新功能而逐漸演變過來的,就其實(shí)就是一種繼承的直觀體現(xiàn)。繼承原有的功能,增加自己新的功能,實(shí)現(xiàn)了拓展和復(fù)用。
在Java繼承可以使用 extends 關(guān)鍵字來實(shí)現(xiàn),其中Java規(guī)定了java.lang.Object 類作為所有的類直接或間接的父類(當(dāng)類沒有繼承其他類時,java默認(rèn)繼承Object類,當(dāng)類繼承了其他類時,可以向上追溯,最終繼承的類就是Object類)。java規(guī)定類只能繼承一個類,但是一個類可以被多個類繼承(一個子類只能有一個直接父類,一個父類可以有多個子類),類之間可以有多層的繼承關(guān)系,直接繼承的是直接父類,父類的父類就是間接父類,而最上層就是Object。
Object類:
Object類提供的方法:
子類不會繼承父類的構(gòu)造方法,但是會調(diào)用(子類初始化前會先初始化父類)。如果父類的構(gòu)造器帶有參數(shù),則必須在子類的構(gòu)造器中顯式地通過 super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表(這就是Java要設(shè)置一個默認(rèn)的無參構(gòu)造的緣故,方便初始化)。
如果要初始化父類中的字段,可以在子類的構(gòu)造方法中通過關(guān)鍵字super調(diào)用父類的構(gòu)造方法;且該super語句必須在構(gòu)造方法中的第一行。
如果父類構(gòu)造器沒有參數(shù),則在子類的構(gòu)造器中不需要使用 super 關(guān)鍵字調(diào)用父類構(gòu)造器,系統(tǒng)會自動調(diào)用父類的無參構(gòu)造器。
如果父類的構(gòu)造器帶有參數(shù),則必須在子類的構(gòu)造器中顯式地通過 super 關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表;
使用繼承時,需要注意繼承是受權(quán)限修飾符影響的。
1.子類無法繼承 private 修飾的屬性和方法
2.子類和父類在同一包下,可以繼承 default 權(quán)限的屬性方法
3.子類可以對父類進(jìn)行擴(kuò)展,擁有自己的屬性和方法
4.子類可以重寫父類的方法(前提是可以繼承到這個方法)(多態(tài)的體現(xiàn))
雖然繼承可以極大的提高代碼的復(fù)用性,但是不能盲目的去繼承,比如你讓一個Dog類繼承Person類,比如僅僅為了一個類中的某個功能,就直接使用繼承。所以繼承需要根據(jù)實(shí)際需要來選擇是否使用。
繼承中的關(guān)鍵字:extends、super 、this、final
1.extends:單一繼承,可以讓一個類繼承一個父類
2.super:我們可以通過super關(guān)鍵字來實(shí)現(xiàn)對父類成員的訪問,用來引用當(dāng)前對象的父類。
3.this:指向自己的引用。引用自身的屬性和方法。
4.final:
-? 當(dāng)用final修飾類時,是把類定義為不能繼承的,即最終類;
-? 用于修飾方法時,該方法不能被子類重寫:
-? 用于修飾屬性時,和static一起使用,表明為一個常量,各類的所有對象共用一個值
3、 多態(tài)
多態(tài)指同一個實(shí)體同時具有多種形式。同字面意思,即一個對象在不同的情況下會有不同的體現(xiàn)。(主要體現(xiàn)在對象和方法上,在子父類中不要定義同名的屬性)
3.1、對象的多態(tài)
類的多態(tài)其實(shí)就是一繼承關(guān)系。
1、向上轉(zhuǎn)型
向上轉(zhuǎn)型其實(shí)就是父類對子類的引用。等邊三角形是一種特殊的三角形,但是不管再怎么特殊它也是一個三角形。不管什么品種的狗我們都可以說它是一只動物。
這個特點(diǎn)其實(shí)就是設(shè)計原則中的里式替換原則的原理。子類至少是一個父類,所以父類出現(xiàn)的地方,其子類一定可以出現(xiàn)。
//狗繼承與Animals ,所以可以向上轉(zhuǎn)型,用Animals引用Dog類
//能引用是因?yàn)楣分辽偈且环N動物,它有動物類所有屬性和方法
Animals animals= new Dog();
向上轉(zhuǎn)型的概念使用的地方很多,尤其是在框架學(xué)習(xí)階段,會大量使用(在抽象類、接口等方面會大量的使用)。
子類中如果定義了與父類同名同參數(shù)的方法,在多態(tài)情況下,將此時父類的方法稱為虛擬方法,父類根據(jù)賦給它的不同子類對象,動態(tài)調(diào)用屬于子類的該方法。這樣的方法調(diào)用在編譯期是無法確定的(多態(tài)是在方法調(diào)用時,才會明確具體的方法)。
public class Test {
? ? public static void main(String[] args) {
? ? ? ? Random random = new Random();
? ? ? ? int choose = random.nextInt(3);
? ? ? ? System.out.println(choose);
? ? ? ? //編譯期間是不會知道實(shí)例化那個對象的,需要在運(yùn)行期間確定
? ? ? ? Animal animal = switch (choose) {
? ? ? ? ? ? case 1 -> new Animal();
? ? ? ? ? ? case 2 -> new Dog();
? ? ? ? ? ? default -> new Cat();
? ? ? ? };
? ? ? ? //而且傳遞的是哪個對象就調(diào)用那個對象的say方法
? ? ? ? animal.say();
? ? }
}
class Animal{
? ? public void say(){
? ? ? ? System.out.println("動物的叫聲");
? ? }
}
class Dog extends Animal{
? ? @Override
? ? public void say() {
? ? ? ? System.out.println("汪汪汪!??!");
? ? }
}
class Cat extends Animal{
? ? @Override
? ? public void say() {
? ? ? ? System.out.println("喵喵喵?。?!");
? ? }
}
如果使用了向上轉(zhuǎn)型,聲明為父類類型,雖然內(nèi)存中實(shí)際加載的是子類對象,但是由于變量時父類的類型,會導(dǎo)致在編譯時,只能使用父類聲明的屬性和方法,子類特有的屬性和方法是不能調(diào)用的。所以父類還可以向下轉(zhuǎn)型。
2、向下轉(zhuǎn)型
向下轉(zhuǎn)型是將父類轉(zhuǎn)型為子類,這種轉(zhuǎn)型如果直接轉(zhuǎn)化,通常會出現(xiàn)問題(如:ClassCastException異常),所以在具體使用向下轉(zhuǎn)型的時候需要使用顯式類型轉(zhuǎn)換。(使用的較少)
向下轉(zhuǎn)型的前提:
undefined.父類對象指向的是子類對象(實(shí)際上還是得先向上轉(zhuǎn)型一下),如果指向的不是子類對象,是沒法向下轉(zhuǎn)型的。
undefined.有了1的前提,才能使用強(qiáng)制類型轉(zhuǎn)換進(jìn)行轉(zhuǎn)型
向下轉(zhuǎn)型通常配合 instanceof關(guān)鍵字使用,用于判斷一個實(shí)例對象是否屬于某個類,判斷一個類是否實(shí)現(xiàn)了某個接口。
a instanceof B? :判斷對象a是否是類B的一個實(shí)例(或類a是否實(shí)現(xiàn)了接口B)
當(dāng)我們使用向下轉(zhuǎn)型時,可能會出現(xiàn)一些問題,所以在之前需要先判斷一下。
class Animals {
? ? public void sound(){
? ? ? ? System.out.println("動物叫聲");
? ? }
}
class Dog extends Animals{
? ? @Override
? ? public void sound() {
? ? ? ? System.out.println("狗叫聲");
? ? }
? ? public void eat(){
? ? ? ? System.out.println("狗在吃骨頭");
? ? }
}
class Cat extends Animals{
? ? @Override
? ? public void sound() {
? ? ? ? System.out.println("喵喵喵");
? ? }
? ? public void play(){
? ? ? ? System.out.println("貓在玩耍");
? ? }
}
class Test{
? ? public static void main(String[] args) {
? ? ? ? //向上轉(zhuǎn)型
? ? ? ? Animals a = new Dog();
? ? ? ? // Animals a = new Cat();
? ? ? ? a.sound();
? ? ? ? //a.eat()方法時無法調(diào)用的,如果使用需要向下轉(zhuǎn)型
? ? ? ? //向下轉(zhuǎn)型,先判斷屬于Dog還是Cat的實(shí)例,屬于誰的實(shí)例就轉(zhuǎn)型成誰
? ? ? ? if(a instanceof Dog){
? ? ? ? ? ? Dog dog = (Dog) a;
? ? ? ? ? ? dog.eat();
? ? ? ? } else if (a instanceof Cat) {
? ? ? ? ? ? Cat cat = (Cat)a;
? ? ? ? ? ? cat.play();
? ? ? ? }
? ? }
}
3.3.2、方法的多態(tài)
1、重寫
重寫父類的方法,方法名字、參數(shù)、返回值相同
public class Persion {
public void say(String name){
? ? ? System.out.println("名字是:"+name);
? ? }
}
public class Student extends Persion{
? ? public void say(String name) { //重寫了父類的方法,方法名和參數(shù)相同
? ? ? ? System.out.println(name+"是一個學(xué)生");
? ? }
}
2、重載
同一個類中的相同名字不同參數(shù)的方法,調(diào)用時根據(jù)傳遞的參數(shù)不同來區(qū)分是哪個方法
public class Persion{
? ? public void say(String name , String sex){}
? ? public void say(String name,int age){} //重載方法,名字相同,但是傳遞參數(shù)的類型必須有不同?
? ? //重載的參數(shù)類型不能相同
? ? public void say(String sex,String name){} //和第一個say具有相同類型的參數(shù),所以系統(tǒng)無法判定,就會出現(xiàn)錯誤? ?
}
3、重寫和重載區(qū)別
1、重寫(Override)
重寫是子類對父類允許訪問的方法進(jìn)行重寫, 返回類型與被重寫方法的返回類型可以不相同,但是必須是父類返回值的派生類
子類和父類在同一個包中,那么子類可以重寫父類除了聲明為 private 和 final 的方法外的所有方法
子類和父類不在同一個包中,那么子類只能夠重寫父類的聲明為 public 和 protected 的非 final 方法。
訪問權(quán)限不能比父類中被重寫的方法的訪問權(quán)限更低。
父類的成員方法只能被它的子類重寫,子類能夠根據(jù)需要實(shí)現(xiàn)父類的方法
重寫方法拋出的異常范圍不能大于父類。異常也有繼承關(guān)系,所以子類能拋出的異常不能高于父類
參數(shù)列表與被重寫方法的參數(shù)列表必須完全相同。
聲明為 final 的方法不能被重寫。聲明為 static 的方法不能被重寫,但是能夠被再次聲明。
構(gòu)造方法不能被重寫。
如果不能繼承一個類,則不能重寫該類的方法。
2、重載(Overload)
重載是在一個類里面,方法名字必須相同,而參數(shù)必須不同。返回類型可以相同也可以不同。
被重載的方法可以改變返回類型;
被重載的方法可以改變訪問修飾符;
被重載的方法可以聲明新的或更廣的檢查異常;
無法以返回值類型作為重載函數(shù)的區(qū)分標(biāo)準(zhǔn)。
3、方法的重寫(Overriding)和重載(Overloading)是java多態(tài)性的不同表現(xiàn),重寫是父類與子類之間多態(tài)性的一種表現(xiàn),重載可以理解成多態(tài)的具體表現(xiàn)形式。
方法重載是一個類中定義了多個同名的方法,而他們的參數(shù)的數(shù)量不同或數(shù)量相同而類型和次序不同,則稱為方法的重載
方法重寫是在子類存在方法與父類同名的方法,而且參數(shù)的個數(shù)與類型一樣,就稱為重寫
方法重載是一個類的多態(tài)性表現(xiàn),而方法重寫是子類與父類的一種多態(tài)性表現(xiàn)。
五、訪問權(quán)限修飾符
六、二維數(shù)組的遍歷
forfor循環(huán)
方法解析:
//外循環(huán)遍歷有幾個一維數(shù)組
for(;;;){
//內(nèi)循環(huán)遍歷每一個一維數(shù)組的元素
for(;;;){
? ...
}
}
foreach循環(huán)
形式
for(元素類型 x: 遍歷對象 obj){
引用了x的java的語句;
}
應(yīng)用
public static void main(String[] args) {
//每個一維數(shù)組的元素? 對應(yīng)的數(shù)組值長度不一致 非對稱數(shù)組
int [][]num= {? {2,5}, {5,7,9} ,{9}, {8,9,3,56}};
? ? //foreach遍歷
? ? for(int []tmp:num) {
? ? ? ? //tmp是個數(shù)組
? ? ? ? for(int i:tmp) {
? ? ? ? ? ? System.out.print(i+" ");
? ? ? ? }
? ? System.out.println();
? ? }
}
七、字符串轉(zhuǎn)整數(shù)類型
1、Integer.valueOf()
此方法是返回的Integer類型
? ? String str="123";
? ? Integer num = Integer.valueOf(str);
2、Integer.parseInt()
此方法是返回的int類型
? ? String str="123";
? ? int num = Integer.parseInt(str);
八、整數(shù)轉(zhuǎn)字符串
1、String.valueOf()
此方法可以將Integer和int類型的轉(zhuǎn)為String類型的
? ? int num = 8;
? ? String str = String.valueOf(num);
? ? Integer num = 8;
? ? String str = String.valueOf(num);
2、toString()
? ? int num = 8;
? ? String str = Integer.toString(num);
注意對于Integer類型的可以直接用toString方法
? ? Integer num = 8;
? ? String str = num.toString();
九、抽象類
1.什么是抽象類?
undefined.類和類之間具有共同特征,將這些共同特征抽取出來,形成的就是抽象類。
undefined.如果一個類沒有足夠的信息來描述一個具體的對象,這個類就是抽象類。
undefined.因?yàn)轭惐旧砭褪遣淮嬖诘?,所以抽象類無法創(chuàng)建對象,也就是無法實(shí)例化。
問題:既然抽象類是無法創(chuàng)建對象,無法實(shí)例化,那是用來干嘛的???
抽象類是用來被子類繼承的。
2.抽象類屬于什么類型?
抽象類屬于引用數(shù)據(jù)類型
3. 抽象類怎么定義?
關(guān)鍵字:abstract
語法:【修飾符列表】 abstract class 類名{
類體
}
4.思考?
4.1 final和abstract能聯(lián)合使用嗎?
不能聯(lián)合使用,因?yàn)楸籪inal關(guān)鍵字修飾過的類是無法繼承的,而前面說到abstract就是用來被子類繼承的。這兩個關(guān)鍵字是對立的。
//會報錯,因?yàn)閒inal和abstract不能聯(lián)合使用
//final abstract class Person{
//}
4.2 抽象類的子類還可以是抽象類嗎?
可以是抽象類
//定義一個抽象類Person
abstract class Person{
}
//抽象類Student繼承抽象父類Person
abstract class Student extends Person{
}
4.3 抽象類中有構(gòu)造方法嗎?
抽象類雖然不能實(shí)例化,但是抽象類有構(gòu)造方法,這個構(gòu)造方法是給子類提供的。因?yàn)槌橄缶褪潜挥脕砝^承的,子類繼承父類,子類的構(gòu)造方法中的第一句默認(rèn)是super();
//定義一個抽象類Person
abstract class Person {
//父類無參構(gòu)造
Person() {
}
}
//抽象類Student繼承抽象父類Person
abstract class Student extends Person {
//子類無參構(gòu)造
Student() {
//默認(rèn)第一句就是調(diào)用父類的無參構(gòu)造
super();
}
}
二:抽象方法
1.什么是抽象方法?
抽象方法就是在抽象類中沒有實(shí)現(xiàn)的方法,沒有方法體的方法。
沒有方法體,以分號結(jié)尾;
方法中有abstract關(guān)鍵字
//定義一個抽象方法eat();
public abstract void eat();
2. 思考?
2.1 抽象類中一定要有抽象方法嗎?
抽象類中不一定有抽象方法,但是有抽象方法必須得在抽象類中。 抽象方法中還可以有非抽象方法
//定義一個抽象類Person01
abstract class Person01{
//定義一個抽象方法eat();
public abstract void eat();
//非抽象方法
public void sleep(){
}
}
2.2 如何調(diào)用?
使用多態(tài)的方式調(diào)用,父類的引用指向子類的對象。
public class AbstractTest02 {
public static void main(String[] args) {
//使用多態(tài)的方式創(chuàng)建對象
Person01 person01 = new Ceshi();
//調(diào)用eat方法【編譯看左,運(yùn)行看右】
person01.eat();? ? //吃
}
}
//定義一個抽象類Person01
abstract class Person01{
//定義一個抽象方法eat();
public abstract void eat();
}
//非抽象類繼承抽象類
class Ceshi extends Person01{
//覆蓋重寫抽象類中的抽象方法
@Override
public void eat() {
System.out.println("吃");
}
}
2.3 什么是面向抽象編程?
顧名思義,面向抽象編程也就是不在面向具體的類,而是面向抽象類,讓設(shè)計者不在關(guān)心具體的實(shí)現(xiàn)??梢越档统绦虻鸟詈隙?,提高程序的擴(kuò)展力。
結(jié)論:
3.1 非抽象類繼承抽象類,必須實(shí)現(xiàn)/重寫抽象類中的抽象方法。
實(shí)現(xiàn)格式: 去掉 abstract 加上 方法體
//定義一個抽象類Person01
abstract class Person01{
//定義一個抽象方法eat();
public abstract void eat();
}
//非抽象類繼承抽象類
class Ceshi extends Person01{
//實(shí)現(xiàn)抽象類中的抽象方法
@Override
public void eat() {
}
}
3.2 抽象類不能被實(shí)例化,只有抽象類的非抽象子類可以創(chuàng)建對象。
public class AbstractTest03 {
public static void main(String[] args) {
// 抽象類不能實(shí)例化,如果實(shí)例化就會報錯
// Test test = new Test();? ? //報錯
}
}
//定義一個抽象類Test
abstract class Test{
}
3.3 抽象類中不一定包含抽象方法,但是有抽象方法的類必定是抽象類。
//定義一個非抽象類Test1
//class Test1{
//定義一個抽象方法method,一個類中如果有抽象方法那么這個類必須是抽象類
//public abstract void method();? ? //報錯
//}
4. 權(quán)限修飾符
? ? ? ? ? ? ? ? ? ? 本類 ? ? 同一個包下的類 不同包下的子類 ? ? 不同包下的無關(guān)類
private ? ? √
默認(rèn) ? ? √ ? ? ? ? ? √
protected ? ? √ ? ? ? ? ? √ ? ? √
public ? ? √ ? ? ? ? ? √ ? ? √ ? ? ? √
5. 面試題:
java語言中凡是沒有方法體的方法都是抽象方法嗎?【判斷題】
不對,錯誤的。Object類中有很多方法都沒有方法體,都是以;結(jié)尾的,但是他們都不是抽象方法
例如: public native int hashCode(); 這個方法底層調(diào)用了C++寫的動態(tài)鏈接程序,修飾符中沒有abstract,有一個native,表示調(diào)用JVM本地程序。
三:思維導(dǎo)圖
十、抽象類和接口的區(qū)別
Java中接口和抽象類的定義語法分別為interface與abstract關(guān)鍵字。
相同點(diǎn)
都不能被實(shí)例化,接口的實(shí)現(xiàn)類或抽象類的子類都只有實(shí)現(xiàn)了接口或抽象類中的方法后才能實(shí)例化。
不同點(diǎn)
undefined.抽象類中的抽象方法的修飾符只能為public或者protected,默認(rèn)為public;接口中的方法默認(rèn)使用public修飾
undefined.接口成員變量默認(rèn)為public static final,必須賦初值,不能被修改。抽象類中成員變量默認(rèn)default,可在子類中被重新定義,也可被重新賦值;
undefined.實(shí)現(xiàn)接口的關(guān)鍵字為implements,繼承抽象類的關(guān)鍵字為extends。一個類可以實(shí)現(xiàn)多個接口,但一個類只能繼承一個抽象類。所以,使用接口可以間接地實(shí)現(xiàn)多重繼承。
undefined.接口強(qiáng)調(diào)特定功能的實(shí)現(xiàn),而抽象類強(qiáng)調(diào)所屬關(guān)系。
undefined.抽象類可以包含方法、構(gòu)造方法,方法可以實(shí)現(xiàn),但是構(gòu)造方法不能用于實(shí)例化,主要用途是被子類調(diào)用。接口只有定義,不能有方法的實(shí)現(xiàn),java 1.8中可以定義default方法體
十一、成員變量和局部變量的區(qū)別
一、成員變量是獨(dú)立于方法外的變量,局部變量是類的方法中的變量;
- 成員變量:包括實(shí)例變量和類變量,用static修飾的是類變量,不用static修飾的是實(shí)例變量,所有類的成員變量可以通過this來引用。
- 局部變量:包括形參,方法局部變量,代碼塊局部變量,存在于方法的參數(shù)列表和方法定義中以及代碼塊中。
二、成員變量可以被public,protect,private,static等修飾符修飾,而局部變量不能被控制修飾符及 static修飾;兩者都可以定義成final型。
三、成員變量存儲在堆,局部變量存儲在棧。局部變量的作用域僅限于定義它的方法,在該方法的外部無法訪問它。成員變量的作用域在整個類內(nèi)部都是可見的,所有成員方法都可以使用它。如果訪問權(quán)限允許,還可以在類的外部使用成員變量。
四、局部變量的生存周期與方法的執(zhí)行期相同。當(dāng)方法執(zhí)行到定義局部變量的語句時,局部變量被創(chuàng)建;執(zhí)行到它所在的作用域的最后一條語句時,局部變量被銷毀。類的成員變量,如果是實(shí)例成員變量,它和對象的生存期相同。而靜態(tài)成員變量的生存期是整個程序運(yùn)行期。
五、成員變量在累加載或?qū)嵗粍?chuàng)建時,系統(tǒng)自動分配內(nèi)存空間,并在分配空間后自動為成員變量指定初始化值,初始化值為默認(rèn)值,基本類型的默認(rèn)值為0,復(fù)合類型的默認(rèn)值為null。(被final修飾且沒有static的必須顯式賦值),局部變量在定義后必須經(jīng)過顯式初始化后才能使用,系統(tǒng)不會為局部變量執(zhí)行初始化。
六、局部變量可以和成員變量 同名,且在使用時,局部變量具有更高的優(yōu)先級,直接使用同名訪問,訪問的是局部變量,如需要訪問成員變量可以用 this.變量名 訪問。
十二、構(gòu)造方法的特點(diǎn)
十三、代碼塊的加載順序
執(zhí)行順序:靜態(tài)代碼塊? > 構(gòu)造塊? > 構(gòu)造方法。
父類靜態(tài)代碼塊 > 子類靜態(tài)代碼塊 > 父類構(gòu)造塊 > 父類構(gòu)造方法 > 子類構(gòu)造塊 > 子類構(gòu)造方法
十四、內(nèi)部類
在類的內(nèi)部編寫的類就叫內(nèi)部類!即一個類的內(nèi)部又完整的嵌套了另一個類結(jié)構(gòu),被嵌套的類稱為內(nèi)部類(inner class),嵌套其他類的類稱為外部類(outer class)。
內(nèi)部類是類的第五大成員→【提示:類的五大成員是哪些?[屬性、方法、構(gòu)造器、代碼塊、內(nèi)部類]】
內(nèi)部類一般來說包括這四種:成員內(nèi)部類、局部內(nèi)部類、匿名內(nèi)部類和靜態(tài)內(nèi)部類。
內(nèi)部類優(yōu)點(diǎn)如下:
1.每個內(nèi)部類都能獨(dú)立的繼承一個接口的實(shí)現(xiàn),所以無論外部類是否已經(jīng)繼承了某個(接口的)實(shí)現(xiàn),對于內(nèi)部類都沒有影響。內(nèi)部類使得多繼承的解決方案變得完整;
2.方便將存在一定邏輯關(guān)系的類組織在一起,又可以對外界隱藏;
3.方便編寫事件驅(qū)動程序;
4.方便編寫線程代碼。
一、成員內(nèi)部類:(在類的內(nèi)部方法的外部編寫的類就是成員內(nèi)部類)
成員內(nèi)部類特點(diǎn):
1.成員內(nèi)部類可以無條件訪問外部類的所有成員屬性和成員方法(包括private成員和靜態(tài)成員);
2.同名的屬性名/方法名訪問外部類時 → 外部類.this.成員名
Outer.this.name
成員內(nèi)部類是依附外部類而存在的,也就是說,如果要創(chuàng)建成員內(nèi)部類的對象,前提是必須存在一個外部類的對象。所以在外部類訪問內(nèi)部類的時候必須先實(shí)例化外部類對象
Outer outer= new outer();
Inner inner = outer.new Inner();
? ? //或者如下一句代碼:
? ? Outer.Inner inner = new Outer().new Inner();
注意:
1.成員內(nèi)部類可以使用四種權(quán)限修飾符進(jìn)行修飾(四種權(quán)限修飾符:public(公有的) >protected(受保護(hù)的) > (default)(缺省/默認(rèn)的) > private(私有的));
2.成員內(nèi)部類中不能書寫靜態(tài)變量和方法。
詳見案例演示:
public class Outer {
String name = "外部類的類名";
static String type = "外部類的type屬性";
private int item = 1;
public static void show() {
? ? System.out.println("掉用外部類中的show方法");
}
public void print() {
? ? System.out.println("調(diào)用外部類中的打印方法");
}
//成員內(nèi)部類 可以使用權(quán)限修飾符進(jìn)行修飾
public class Inner{
? ? //static double weight = 1.8;? //成員內(nèi)部類中不能使用static修飾變量和方法
? ? String name = "內(nèi)部類的類名";
? ? public void innerShow(){
? ? ? ? //成員內(nèi)部類可以直接訪問外部類的屬性和方法
? ? ? ? show();
? ? ? ? print();
? ? ? ? System.out.println(type);
? ? ? ? System.out.println(item);
? ? ? ? System.out.println("我是:" + name);
? ? ? ? //進(jìn)行特指訪問時 使用類名.this.變量名進(jìn)行訪問
? ? ? ? System.out.println("我是:" + Outer.this.name);
? ? }
}
public static void main(String[] args) {
? ? //成員內(nèi)部類對象的創(chuàng)建步驟
? ? //1.第一步需要實(shí)例化外部類對象
? ? //2.第二步正常實(shí)例化內(nèi)部類對象 但是new關(guān)鍵字要改成 外部類對象名.new
? ? ? /*Outer outer = new Outer();
? ? ? ? Inner inner = outer.new Inner();*/
? ? //或者這樣創(chuàng)建
? ? Outer.Inner inner = new Outer().new Inner();
? ? inner.innerShow();
}
}
二、局部內(nèi)部類 (編寫在方法的內(nèi)部的類稱之為局部內(nèi)部類,也可以稱為方法內(nèi)部類)
局部內(nèi)部類的特點(diǎn)
1.局部內(nèi)部類是定義在一個方法或者一個作用域里面的類,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的訪問僅限于方法內(nèi)或者該作用域內(nèi);
2.局部內(nèi)部類不可使用權(quán)限修飾符 靜態(tài)(static)修飾符進(jìn)行修飾 同局部變量相同;
3.局部內(nèi)部類可以直接訪問方法中的屬性;
4.局部內(nèi)部類 可以直接訪問方法外部類中屬性和方法;
5.局部內(nèi)部類 創(chuàng)建對象 要在方法內(nèi)部 局部內(nèi)部類的外部聲明。
詳見案例演示:
public class Partial {
String name = "外部類的類名";
String type = "外部類的type屬性";
private int item = 1;
public static void show() {
? ? System.out.println("掉用外部類中的show方法");
}
public void print() {
? ? System.out.println("調(diào)用外部類中的打印方法");
}
public void demo(){
? ? String name = "外部類方法deme()內(nèi)部的方法名";
? ? String type = "外部類方法deme()內(nèi)部的type屬性";
? ? /*編寫在方法的內(nèi)部的類稱之為局部內(nèi)部類
? ? 局部內(nèi)部類不可使用權(quán)限修飾符 靜態(tài)修飾符進(jìn)行修飾 同局部變量相同
? ? 局部內(nèi)部類與局部變量使用范圍一樣 在此方法內(nèi)部
? ? 局部內(nèi)部類可以直接訪問方法中的屬性 重名時使用參數(shù)傳遞完成訪問*/
? ? class Inner{
? ? ? ? //局部內(nèi)部類 可以訪問方法外部類中屬性和方法
? ? ? ? String name = "局部類的類名";
? ? ? ? public void showInner(String name){
? ? ? ? ? ? show();
? ? ? ? ? ? print();
? ? ? ? ? ? System.out.println("我是:"+ type);
? ? ? ? ? ? System.out.println("我是:"+ Partial.this.type);
? ? ? ? ? ? System.out.println(item);
? ? ? ? ? ? System.out.println("我是:" + this.name);
? ? ? ? ? ? System.out.println("我是:" + name);
? ? ? ? ? ? System.out.println("我是:" + Partial.this.name);
? ? ? ? }
? ? }
? ? //局部內(nèi)部類 創(chuàng)建對象 要在方法內(nèi)部 局部內(nèi)部類的外部聲明
? ? Inner inner = new Inner();
? ? inner.showInner(name);
}
public static void main(String[] args) {
? ? Partial partial = new Partial();
? ? partial.demo();
}
}
三、匿名內(nèi)部類(注意:匿名內(nèi)部類只是沒有類名,其他的都是具備的)
匿名內(nèi)部類特點(diǎn)
匿名內(nèi)部類不能定義任何靜態(tài)成員、方法和類,只能創(chuàng)建匿名內(nèi)部類的一個實(shí)例。一個匿名內(nèi)部類一定是在new的后面,用其隱含實(shí)現(xiàn)一個接口或?qū)崿F(xiàn)一個類。
詳見案例演示:
// 實(shí)現(xiàn)關(guān)系下的匿名內(nèi)部類:
interface Dao {
void show();
}
public class AnonymousDemo {
//編寫回調(diào)方法 :callInner
public void callInner(){
// 接口關(guān)系下的匿名內(nèi)部類
new Dao(){
//實(shí)現(xiàn)子類 但是沒有名字 所以叫匿名內(nèi)部類
@Override
public void show() {
System.out.println("接口方法...");
}
}.show();
}
}
// 測試:
public class Demo {
public static void main(String[] args) {
AnonymousDemo anonymousDemo = new AnonymousDemo();
anonymousDemo.callInner();
}
}
匿名內(nèi)部類可用于給方法傳遞實(shí)參,演示如下:
interface Dao {
void show();
}
public class AnonymousDemo {
//編寫回調(diào)方法:callInner 參數(shù)類型為接口Dao
private static void callInner(Dao d) {
d.show();
}
public static void main(String[] args) {
? ? callInner(new Dao() {//接口回調(diào)
? ? ? ? //實(shí)現(xiàn)子類 但是沒有名字 所以叫匿名內(nèi)部類
? ? ? ? @Override
? ? ? ? public void show() {
? ? ? ? ? ? System.out.println("匿名內(nèi)部類用于給方法傳遞實(shí)參");
? ? ? ? }
? ? });
}
}
或許有些難以理解,其實(shí)過程并不復(fù)雜。
說明:首先有一個接口,然后在使用的類中編寫了一個方法(參數(shù)類型是接口對象),并使用接口中未實(shí)現(xiàn)的方法。
我們調(diào)用此方法直接構(gòu)造一個接口對象傳入,此時會自動生成一個此接口的子類(匿名內(nèi)部類)實(shí)現(xiàn)接口中的方法。本質(zhì)傳入的類便是此時的匿名內(nèi)部類。
四、靜態(tài)內(nèi)部類(在類中編寫的以static修飾的類稱為靜態(tài)內(nèi)部類)
靜態(tài)內(nèi)部類特點(diǎn)
1.靜態(tài)內(nèi)部類也是定義在另一個類里面的類,只不過在類的前面多了一個關(guān)鍵字static;
2.靜態(tài)內(nèi)部類是不需要依賴于外部類的,這點(diǎn)和類的靜態(tài)成員屬性有點(diǎn)類似,并且它不能使用外部類的非static成員變量或者方法;
3.靜態(tài)內(nèi)部類中既能聲明靜態(tài)成員也可以聲明非靜態(tài)成員。
詳見案例演示:
public class Static {
static String name = "外部類的類名";
//靜態(tài)內(nèi)部類中不能訪問外部類非靜態(tài)成員
String type = "外部類的type屬性";
public static class Inner{
? ? //四種權(quán)限修飾符可以修飾靜態(tài)內(nèi)部類
? ? public String name = "靜態(tài)內(nèi)部類的類名";
? ? static double weight = 1.8;
? ? String type = "靜態(tài)內(nèi)部類的type屬性";
? ? public void show(){
? ? ? ? System.out.println("我是:" + weight);
? ? ? ? System.out.println("我是:" + type);
? ? ? ? System.out.println("我是:" + name);
? ? ? ? //System.out.println("我是:" + Static.type);//靜態(tài)內(nèi)部類中不能訪問外部類非靜態(tài)成員
? ? ? ? System.out.println("我是:" + Static.name);
? ? }
}
public static void main(String[] args) {
? ? //靜態(tài)內(nèi)部類可以直接實(shí)例化 不需要依附于外部類
? ? Inner inner = new Inner();
? ? inner.show();
}
}
十五、返回值的作用
十六、命名
標(biāo)識符命名規(guī)范
在Java中,標(biāo)識符是指用來標(biāo)識程序中各種變量、方法、類等的名稱。標(biāo)識符的命名規(guī)則如下:
1.標(biāo)識符必須以字母、下劃線(_)或美元符號($)開頭,不能以數(shù)字開頭。
2.標(biāo)識符可以包含字母、數(shù)字、下劃線(_)或美元符號($)。
3.標(biāo)識符是區(qū)分大小寫的。
4.標(biāo)識符不能使用Java中的關(guān)鍵字和保留字。
需要注意的是,雖然Java中允許使用下劃線(_)和美元符號($)作為標(biāo)識符的一部分,但是在實(shí)際編程中,建議使用駝峰命名法來命名標(biāo)識符,這樣可以提高代碼的可讀性和可維護(hù)性。
大小駝峰命名法? ? ?
通常使用小駝峰命名法來命名變量、方法、屬性等成員變量,而使用大駝峰命名法來命名類和接口。
1.大駝峰命名法(也稱為大寫駝峰命名法或帕斯卡命名法)是一種命名規(guī)范,它主要用于命名類、接口、枚舉等 Java 元素。具體來說,大駝峰命名法是指將多個單詞組合起來構(gòu)成一個復(fù)合詞,其中每個單詞的首字母都大寫,以此類推。
以下是一些使用大駝峰命名法的示例:
類名:Person, Student, Book, CustomerOrder
接口名:Runnable, Comparable, Serializable
枚舉名:DayOfWeek, Color, Size
2.小駝峰命名法(也稱為小寫駝峰命名法)是一種命名規(guī)范,它主要用于命名變量、方法、屬性等 Java 元素。具體來說,小駝峰命名法是指將多個單詞組合起來構(gòu)成一個復(fù)合詞,其中第一個單詞的首字母小寫,后面的每個單詞的首字母大寫,以此類推。
以下是一些使用小駝峰命名法的示例:
變量名:firstName, lastName, age, emailAddress
方法名:getFirstName(), setLastName(String lastName), calculateAge(int birthYear), sendEmail(String recipient, String subject, String body)
屬性名:firstName, lastName, age, emailAddress
--------------------------------------------------------------------------------
類,對象,包的命名
1.類的命名:
? 類名應(yīng)該以大寫字母開頭,采用大駝峰命名法,例如:Person、Student、Account。類名應(yīng)該具有描述性,能夠清晰地表達(dá)類的作用和含義。
2.對象的命名:
? 對象的命名應(yīng)該以小寫字母開頭,采用小駝峰命名法,例如:person、student、account。對象的命名應(yīng)該具有描述性,能夠清晰地表達(dá)對象的作用和含義。
3.包的命名:
? 包名應(yīng)該全部小寫,采用點(diǎn)(.)分隔符分隔各級包名,包名一般采用公司或組織的域名倒序命名,例如:com.example、org.apache。如果是個人或者小團(tuán)隊開發(fā)的項(xiàng)目,也可以使用自己的域名作為包名的一部分? 例如:io.github.username
? 包名的命名應(yīng)該具有唯一性,能夠清晰地表達(dá)包的作用和含義。