1 定義類(lèi),成員變量和方法
類(lèi)和對(duì)象
定義類(lèi)
java的類(lèi)名由一個(gè)或者多個(gè)有意義的單詞組合而成,每個(gè)單詞的首字母大寫(xiě),其他的全部消協(xié),并且單詞之間沒(méi)有分隔符。
成員變量:用于定義該類(lèi)或者實(shí)例的所包含的狀態(tài)數(shù)據(jù)。
方法:用于定義該類(lèi)或者實(shí)例所包含的功能實(shí)現(xiàn)和行為特征。
構(gòu)造器:用于構(gòu)造該類(lèi)的實(shí)例。
- 定義成員變量的語(yǔ)法格式:
[修飾符] 類(lèi)型 成員變量名;
1,修飾符可以沒(méi)有,也可以是public ,protected,private,static,final.前三個(gè)最多出現(xiàn)一個(gè),可以與static final組合起來(lái)修飾成員變量
2,類(lèi)型:任何類(lèi)型,
3,成員變量名,第一個(gè)單詞的首字母小寫(xiě),其他的大寫(xiě),用英文名詞
4,默認(rèn)值:定義成員變量可以指定一個(gè)可選的默認(rèn)值。 - 定義方法的語(yǔ)法格式
[修飾符]返回值類(lèi)型 方法名(形參列表)
{
//由0條或者多條可執(zhí)行的語(yǔ)句構(gòu)成的方法體
}
1,修飾符:可以省略,public protected private static final abstract 前三個(gè)可以出現(xiàn)一個(gè),final和abstract 只能出現(xiàn)其中之一,他們與static組合起來(lái)修飾方法
2,返回值類(lèi)型:任何類(lèi)型。如果生命了返回值類(lèi)型,必須有有效的return語(yǔ)句,否則用void.
3,方法名 ,基本和成員變量的一樣,最好用英文動(dòng)詞。
4,形參列表:0組到多組的“參數(shù)類(lèi)型 形參名,參數(shù)類(lèi)型 形參名,,,” - static關(guān)鍵字
static修飾的成員表示他是屬于類(lèi)的,類(lèi)變量類(lèi)方法。也叫靜態(tài)。靜態(tài)成員不能直接訪問(wèn)非靜態(tài)成員。
static真正的作用是用來(lái)區(qū)分成員變量,方法,內(nèi)部類(lèi),初始化塊屬于類(lèi)本身還是屬于實(shí)例。 - 定義構(gòu)造器語(yǔ)法格式
[修飾符] 構(gòu)造器名 (形參列表)
{
}
1,修飾符可以是省略,public protected private其中之一
2,構(gòu)造器名必須與類(lèi)名相同
3,與方法的相同 - java類(lèi)的大致作用
定義變量
創(chuàng)建對(duì)象
調(diào)用類(lèi)的類(lèi)方法,或者訪問(wèn)類(lèi)的類(lèi)變量
創(chuàng)建并使用對(duì)象
對(duì)象的產(chǎn)生和使用
Person p=new Person();
p.say("你真棒");
p.name(“李剛”);//直接給成員變量賦值
對(duì)象和引用
堆里面的對(duì)象可以有多個(gè)引用。
Person p1=p;
這時(shí)p1和p指向同一個(gè)對(duì)象。
如果希望通知垃圾回收機(jī)制回收某個(gè)對(duì)象,把引用變量賦值為null
this
this關(guān)鍵字總是指向調(diào)用該方法的對(duì)象,誰(shuí)調(diào)用它,他就指向誰(shuí),就可以獲取成員變量和方法。
public class Dog {
public void jump()
{
System.out.println("正在執(zhí)行jump方法");
}
public void run()
{
//如果想在這個(gè)方法里面調(diào)用另一個(gè)方法
//如果沒(méi)有this,則必須再創(chuàng)建一個(gè)對(duì)象
//有了this,就不需要?jiǎng)?chuàng)建了,因?yàn)閠his就是指向調(diào)用該方法的對(duì)象
this.jump();
jump();
}
static修飾的方法,是用類(lèi)來(lái)直接調(diào)用的,因此不需要再創(chuàng)建一個(gè)對(duì)象,因此也就不使用this,因此static對(duì)象不能訪問(wèn)非靜態(tài)成員
public class StaticAccessNonStatic {
public void info()
{
System.out.println("簡(jiǎn)單的方法");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new StaticAccessNonStatic().info();
}
}
大部分時(shí)候,普通方法訪問(wèn)其他方法,成員變量無(wú)需使用this,但是如果方法里面有局部變量和成員變量同名,但是又需要在方法里面訪問(wèn),則必須適應(yīng)this
this也可以用于構(gòu)造器作為默認(rèn)引用。代表構(gòu)造器正在初始化的對(duì)象。
public class ThisInConstructor {
//定義一個(gè)名為foo的成員變量
public int foo;
public ThisInConstructor ()
{
// 在構(gòu)造器中又定義了一個(gè)foo
//this代表正在初始化的對(duì)象,把他的foo成員變量設(shè)為6
int foo=0;
this.foo=6;
}
this還可以作為普通方法的返回值,表示返回調(diào)用該方法的對(duì)象
方法必須屬于類(lèi)或者對(duì)象
java里面的類(lèi)不能獨(dú)立存在,必須放在類(lèi)里面
方法的所屬性
2 java方法的參數(shù)傳遞機(jī)制
值傳遞
參數(shù)傳遞方式是一種值傳遞方式。也就是實(shí)參的副本保存在形參中。如果形參是基本類(lèi)型,那么方法中對(duì)形參的修改不會(huì)改變實(shí)參;如果形參是引用類(lèi)型,仍然是指?jìng)鬟f,由于引用類(lèi)型是指針,保存的是地址,所以方法中對(duì)形參的修改會(huì)改變實(shí)參的值,但是如果在方法中把形參的引用賦值為null,則實(shí)參不會(huì)改變。
class DataWrap
{
int a;
int b;
}
public class ReferenceTransferTest {
public static void swap(DataWrap dw)
{
int temp=dw.a;
dw.a=dw.b;
dw.b=temp;
System.out.println("在swap方法里面a是"+dw.a+"b是"+dw.b);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ReferenceTransferTest rf=new ReferenceTransferTest();
DataWrap dw=new DataWrap();
dw.a=9;
dw.b=4;
rf.swap(dw);
System.out.println("交換結(jié)束后a是"+dw.a+"b是"+dw.b);
}
}
參數(shù)個(gè)數(shù)可變的方法
在最后一個(gè)形參的類(lèi)型后面加上"...", 表示形參可以接受多個(gè)參數(shù)。本質(zhì)上就是一個(gè)數(shù)組類(lèi)型的形參。傳入的實(shí)參可以是多個(gè)參數(shù),也可以是一個(gè)數(shù)組。
但是參數(shù)個(gè)數(shù)可變的形參必須處于形參列表的最后,且只能有一個(gè)。
如果形參是數(shù)組的話,傳遞的方式是
test(new String[]{"abs","cps"});
如果形參時(shí)參數(shù)可變的,傳遞方式除了上邊的方式,還可以是
test("abs","cds");
public class Varargs {
//定義一個(gè)參數(shù)可變的方法
public static void test(int a,String ...books)
{
//books被當(dāng)作數(shù)組處理
for(String tmp:books)
{
System.out.println(tmp);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
test(4,"ans","csd");
}
}
3 遞歸方法
定義:一個(gè)方法體內(nèi)調(diào)用自身。
只要一個(gè)方法的方法體實(shí)現(xiàn)中再次調(diào)用了自身方法,就是遞歸。遞歸必須向已知方向遞歸
public class Recursive {
public static int fn(int n)
{
if(n==1)
{
return 1;
}else if(n==2)
{
return 2;
}
else
{
//方法中調(diào)用自身
return 2*fn(n-1)+fn(n-2);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(fn(10));
}
}
4 方法的重載
“兩同一不同”
同一個(gè)類(lèi)中方法名相同,參數(shù)列表不同。
注意被重載的方法里面包含了參數(shù)可變的形參。
public class OverloadVarargs {
public void test(String msg)
{
System.out.println("只有一個(gè)形參的test方法");
}
public void test(String ... books)
{
System.out.println("多個(gè)形參的test方法");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
OverloadVarargs olV =new OverloadVarargs();
olV.test("aa");
olV.test("bb","cc","dd");
olV.test();
olV.test(new String[]{"aa"});
}
}
5 成員變量和局部變量
必須先給方法局部變量和代碼塊局部變量現(xiàn)實(shí)初始化,即指定初始值。否則不可以訪問(wèn)。
一個(gè)類(lèi)不能有兩個(gè)同名的成員變量,一個(gè)方法也不能有兩個(gè)同名的方法局部變量。但是兩個(gè)代碼塊里面的代碼塊局部變量可以同名。
如果先定義代碼塊局部變量,后定義方法局部變量。代碼塊和方法里面的局部變量也可以同名。
允許局部變量和成員變量同名。此時(shí)局部變量覆蓋成員變量,如果想訪問(wèn)成員變量,要用this。
成員變量的初始化和內(nèi)存中的運(yùn)行機(jī)制
類(lèi)變量和成員變量都在堆中保存。只是不再同一個(gè)地方。成員變量屬于實(shí)例,類(lèi)變量屬于類(lèi)。
局部變量的初始化和內(nèi)存中的運(yùn)行機(jī)制
局部變量保存在棧中,不需要垃圾回收,占的內(nèi)存很小。直到被付初值才會(huì)被分配內(nèi)存
變量的使用規(guī)則
成員變量的使用情形
- 某個(gè)類(lèi)或者實(shí)例的固有信息。如果個(gè)個(gè)實(shí)例都是一樣的,用類(lèi)變量。如果不是一樣的,用實(shí)例變量。
- 保存該類(lèi)或者實(shí)例運(yùn)行時(shí)候的狀態(tài)信息。
- 多個(gè)方法都要用到。
6 實(shí)現(xiàn)良好的封裝
理解封裝
通過(guò)訪問(wèn)控制符把該隱藏的隱藏起來(lái),該暴露的暴露出來(lái)。
使用訪問(wèn)控制符
private 類(lèi)訪問(wèn)權(quán)限
default 包訪問(wèn)權(quán)限
protected 子類(lèi)訪問(wèn)權(quán)限
public 公共訪問(wèn)權(quán)限
關(guān)于訪問(wèn)控制符的使用
- 絕大部分成員變量都用private,只有少部分用static,類(lèi)似全局變量的成員變量用public。除此之外,輔助實(shí)現(xiàn)該類(lèi)的其他方法的工具類(lèi)也用private。
- 如果某個(gè)類(lèi)主要做其他類(lèi)的父類(lèi),則用protected.
- 構(gòu)造器用public。大部分外部類(lèi)用public。
7 使用package和import
package ,import,import static
- 同一個(gè)包下的類(lèi)可以自由訪問(wèn),但是子包里面的還是必須要寫(xiě)全名
- import可以導(dǎo)入包下面的全部類(lèi),子包單獨(dú)import
- import static導(dǎo)入靜態(tài)成員變量,方法
java 常用包
8 構(gòu)造器的作用和構(gòu)造器重載
8.1使用構(gòu)造器執(zhí)行初始化
在系統(tǒng)執(zhí)行構(gòu)造器的執(zhí)行體之前,系統(tǒng)已經(jīng)創(chuàng)建了一個(gè)對(duì)象,只是還不能被外部訪問(wèn)。
9 繼承的特點(diǎn)和用法
9.1繼承的特點(diǎn)
java是單繼承,只能有一個(gè)直接父類(lèi),但是可以有多個(gè)間接父類(lèi)。
子類(lèi)是父類(lèi)的擴(kuò)展。子類(lèi)不能獲得父類(lèi)的構(gòu)造函數(shù)。
10 重寫(xiě)父類(lèi)方法
如果子類(lèi)對(duì)于繼承下來(lái)的父類(lèi)的方法不滿意,可以重寫(xiě)這個(gè)方法。
‘兩同兩小一大原則’
“兩同” 方法名相同,參數(shù)列表相同
“兩小” 返回值類(lèi)型要小,拋出的異常要小
“一大” 權(quán)限要大
重載和重寫(xiě):是兩個(gè)東西。重載是一個(gè)類(lèi)的多個(gè)方法,由于形參列表不同所以不同;重寫(xiě)是子類(lèi)又寫(xiě)了一個(gè)和父類(lèi)對(duì)應(yīng)的方法。
11 super關(guān)鍵字的用法
super用來(lái)限定該對(duì)象調(diào)用父類(lèi)被覆蓋的實(shí)例方法。不能夠用于static修飾的方法中,因?yàn)閟tatic是作用于類(lèi)的。
創(chuàng)建一個(gè)子類(lèi)對(duì)象時(shí),系統(tǒng)會(huì)給該類(lèi)中定義的實(shí)例變量和父類(lèi)繼承來(lái)的實(shí)力變量分配內(nèi)存,即使二者同名。
11.2調(diào)用父類(lèi)構(gòu)造器
用super可以顯式調(diào)用父類(lèi)構(gòu)造器。必須出現(xiàn)在子類(lèi)構(gòu)造器執(zhí)行體的第一行,因此不能和this同時(shí)出現(xiàn)。
當(dāng)調(diào)用子類(lèi)構(gòu)造器初始化子類(lèi)對(duì)象,父類(lèi)構(gòu)造器一定會(huì)在子類(lèi)構(gòu)造器之前執(zhí)行。
12 繼承和多態(tài)
12.1多態(tài)性
java引用變量有兩個(gè)類(lèi)型,一個(gè)是編譯時(shí)候的類(lèi)型,一個(gè)是運(yùn)行時(shí)候的類(lèi)型。編譯時(shí)候的類(lèi)型和聲明的類(lèi)型相同,運(yùn)行時(shí)候的類(lèi)型由實(shí)際賦給該變量的對(duì)象決定。稱為多態(tài)。
相同類(lèi)型的變量,調(diào)用同一個(gè)方法時(shí)呈現(xiàn)出多種不同的行為特征,這就是多態(tài)。
成員變量不具有多態(tài)性。
12.2 引用變量的強(qiáng)制類(lèi)型轉(zhuǎn)換
如果想讓引用變量調(diào)用它運(yùn)行時(shí)的類(lèi)型的方法,則需要強(qiáng)制類(lèi)型轉(zhuǎn)換。只能是具有繼承關(guān)系的兩個(gè)類(lèi)型之間。如果是兩個(gè)沒(méi)有任何關(guān)系的,無(wú)法通過(guò)編譯。如果父類(lèi)實(shí)例轉(zhuǎn)化成子類(lèi)實(shí)例,則這個(gè)對(duì)象在運(yùn)行時(shí)候必須是子類(lèi)實(shí)例才行,否則會(huì)有異常。用instanceof處理。
12.3 instanceof運(yùn)算符
instanceof運(yùn)算符前一個(gè)是引用變量,后一個(gè)是一個(gè)類(lèi)型。用于判斷前面的對(duì)象是不是后面的類(lèi),或者是不是他的子類(lèi),或者實(shí)現(xiàn)類(lèi)的實(shí)例。如果是,返回true
前面操作數(shù)的編譯時(shí)候的類(lèi)型要么和后面的類(lèi)型相同,要么和后面的有父子繼承關(guān)系(不一定是子類(lèi),可以是父類(lèi)),否則編譯有錯(cuò)誤。
編譯想通過(guò)的話,只要有繼承關(guān)系就行。想返回true,前面的不能是后 面的父類(lèi)。
13 繼承和組合的關(guān)系
13.1 使用繼承的注意點(diǎn)
- 盡量隱藏父類(lèi)的內(nèi)部數(shù)據(jù)
- 不要讓子類(lèi)可以隨便訪問(wèn)更改父類(lèi)的方法。輔助方法設(shè)置成private;
如果父類(lèi)中的方法需要被外部類(lèi)調(diào)用,但是又不想讓子類(lèi)重寫(xiě)這個(gè)方法,可以加final;
如果希望子類(lèi)重寫(xiě)該方法,但是不希望其他類(lèi)自由調(diào)用,用protected - 父類(lèi)的構(gòu)造器里面不要有子類(lèi)會(huì)修改的方法。否則容易出現(xiàn)空指針。
因?yàn)閯?chuàng)建子類(lèi)的對(duì)象的時(shí)候,一定會(huì)先調(diào)用父類(lèi)的構(gòu)造器,構(gòu)造器里面調(diào)用的方法已經(jīng)被子類(lèi)覆蓋,所以運(yùn)行時(shí)用的方法是子類(lèi)的方法。但是子類(lèi)還沒(méi)有創(chuàng)建,因此會(huì)有空指針的可能性。
什么時(shí)候從父類(lèi)派生子類(lèi)?
- 增加了新的屬性
- 增加了新的方法
使用組合來(lái)實(shí)現(xiàn)復(fù)用
組合是一種“has”的關(guān)系,譬如人有胳膊,腿。
組合和繼承的開(kāi)銷(xiāo)一樣。
至于怎么用的,書(shū)里面寫(xiě)的太少了。沒(méi)有看明白
先定義private的父類(lèi)的成員變量,然后在子類(lèi)的構(gòu)造器的形參中加入這個(gè)成員變量。然后把父類(lèi)里面所有的public再寫(xiě)一次。(父類(lèi)子類(lèi)并不是這樣,只是我不知道怎么能夠說(shuō)清楚)
13 構(gòu)造器和初始化塊的作用及區(qū)別
13.1 使用初始化塊
java類(lèi)里面可以出現(xiàn)的第四種成員。修飾符只能是static。當(dāng)創(chuàng)建java對(duì)象時(shí),總是先調(diào)用該類(lèi)里面定義的初始化模塊,再調(diào)用構(gòu)造函數(shù)。
13.2 初始化塊和構(gòu)造器
如果兩個(gè)構(gòu)造器里面有相同的代碼初始化代碼,且這些初始化代碼無(wú)需接受參數(shù),就可以把它們放在初始化塊中定義。
13.3 靜態(tài)初始化塊
如果希望加載類(lèi)時(shí),對(duì)整個(gè)類(lèi)進(jìn)行某些初始化操作,使用static關(guān)鍵字來(lái)修飾初始化模塊。叫做類(lèi)初始化塊。