Java基础:面向对象
1.1 面向?qū)ο笏枷胍?/strong>
面向?qū)ο蟮木幊趟枷?#xff0c;力圖讓程序中對事物的描述與該事物在現(xiàn)實中的形態(tài)保持一致。為了做到這一點,面向?qū)ο蟮乃枷胫刑岢隽藘蓚€概念,即類和對象。其中,類是對某一類事物的抽象描述,而對象用于表示現(xiàn)實中該類事物的個體。
前面我們講過數(shù)組,當(dāng)有多個數(shù)組都需要遍歷時,我們可以將遍歷的代碼封裝到方法中,需要遍歷時,就調(diào)用相應(yīng)的方法即可,提高代碼的復(fù)用性。在對數(shù)組遍歷的基礎(chǔ)上繼續(xù)增加需求,比如獲取最值,數(shù)值逆序等,同樣需要將這些功能封裝到相應(yīng)的方法中。這樣繼續(xù)封裝會發(fā)現(xiàn)方法越來越多,于是就想能不能將這些方法繼續(xù)進行封裝呢?通過前面的講解我們知道類是可以存放方法的,所以,我們就考慮使用類封裝來這多個方法,將來再做數(shù)組的操作時,不用去找具體的方法,先找到這個類,然后使用這個類中的方法。這就是面向?qū)ο笏枷氲木幊谭绞健?/p>
1.2 面向過程思想概述
我們來回想一下,這幾天我們完成一個需求的步驟:首先是搞清楚我們要做什么,然后在分析怎么做,最后我們再代碼體現(xiàn)。一步一步去實現(xiàn),而具體的每一步都需要我們?nèi)崿F(xiàn)和操作。這些步驟相互調(diào)用和協(xié)作,完成我們的需求。
在上面的每一個具體步驟中我們都是參與者,并且需要面對具體的每一個步驟和過程,這就是面向過程最直接的體現(xiàn)。
那么什么是面向過程開發(fā)呢? 面向過程開發(fā),其實就是面向著具體的每一個步驟和過程,把每一個步驟和過程完成,然后由這些功能方法相互調(diào)用,完成需求。
面向過程的代表語言:C語言,強調(diào)的是每一個功能的步驟
1.4 面向?qū)ο箝_發(fā),設(shè)計,特征
面向?qū)ο箝_發(fā):就是不斷的創(chuàng)建對象,使用對象,指揮對象做事情。
面向?qū)ο笤O(shè)計:其實就是在管理和維護對象之間的關(guān)系。
面向?qū)ο筇卣?/p>
- 封裝(encapsulation)
- 繼承(inheritance)
- 多態(tài)(polymorphism)
2. 類與對象及其使用
2.1 類與對象的關(guān)系
我們學(xué)習(xí)編程語言,就是為了模擬現(xiàn)實世界的事物,實現(xiàn)信息化。比如:去超市買東西的計費系統(tǒng),去銀行辦業(yè)務(wù)的系統(tǒng)。
我們?nèi)绾伪硎疽粋€現(xiàn)實世界事物呢:
- 屬性 就是該事物的描述信息
- 行為 就是該事物能夠做什么
- 舉例:學(xué)生事物
我們學(xué)習(xí)的Java語言最基本單位是類,所以,我們就應(yīng)該把事物用一個類來體現(xiàn)。
類:是一組相關(guān)的屬性和行為的集合
對象:是該類事物的具體體現(xiàn)
舉例:類 學(xué)生,對象班長就是一個對象
PS
類:可以理解為構(gòu)造對象的一個藍(lán)圖或者模版,是抽象的概念
對象:是以類為模型創(chuàng)建的具體實例,是對類的一種具體化。
2.2 類的定義
現(xiàn)實世界的事物有屬性(人的身高,體重等)和行為(人可以學(xué)習(xí),吃飯等)
Java中用class描述事物也是如此,成員變量 就是事物的屬性,成員方法 就是事物的行為
定義類其實就是定義類的成員(成員變量和成員方法)
/**事物:屬性 事物的信息描述行為 事物的功能類:成員變量 事物的屬性成員方法 事物的行為定義一個類,其實就是定義該類的成員變量和成員方法。案例:我們來完成一個學(xué)生類的定義。學(xué)生事物:屬性:姓名,年齡,地址...行為:學(xué)習(xí),吃飯,睡覺...把事物要轉(zhuǎn)換為對應(yīng)的類:學(xué)生類:成員變量:姓名,年齡,地址...成員方法:學(xué)習(xí),吃飯,睡覺...成員變量:和以前變量的定義是一樣的格式,但是位置不同,在類中方法外。成員方法:和以前的方法定義是一樣的格式,但是今天把static先去掉。首先我們應(yīng)該定義一個類,然后完成類的成員。
*/
//這是我的學(xué)生類
class Student {//定義變量String name;//姓名int age;//年齡String address;//地址//定義方法//學(xué)習(xí)的方法public void study() {System.out.println("學(xué)生愛學(xué)習(xí)");}//吃飯的方法public void eat() {System.out.println("學(xué)習(xí)餓了,要吃飯");}//睡覺的方法public void sleep() {System.out.println("學(xué)習(xí)累了,要睡覺");}
}
2.3 對象內(nèi)存圖
1個對象的內(nèi)存圖:一個對象的基本初始化過程
2個對象的內(nèi)存圖:方法的共用
3個對象的內(nèi)存圖:其中有兩個引用指向同一個對象
2.4 成員變量和局部變量的區(qū)別
注意事項:局部變量名稱可以和成員變量名稱一樣,在方法中使用的時候,采用的是就近原則。
class Varialbe {//成員變量//int num = 10;int num; //0public void show() {//int num2 = 20; //局部變量//可能尚未初始化變量num2//int num2; //沒有默認(rèn)值int num2 = 20;System.out.println(num2);//int num = 100;System.out.println(num);}
}class VariableDemo {public static void main(String[] args) {Varialbe v = new Varialbe();System.out.println(v.num); //訪問成員變量v.show(); }
}
2.5 形式參數(shù)問題
基本類型作為形式參數(shù):形式參數(shù)的改變不影響實際參數(shù)
引用類型作為形式參數(shù):形式參數(shù)的改變直接影響實際參數(shù)
/**形式參數(shù)的問題:基本類型:形式參數(shù)的改變不影響實際參數(shù)引用類型:形式參數(shù)的改變直接影響實際參數(shù)
*/
//形式參數(shù)是基本類型
class Demo {public int sum(int a,int b) {return a + b;}
}//形式參數(shù)是引用類型
class Student {public void show() {System.out.println("我愛學(xué)習(xí)");}
}class StudentDemo {//如果你看到了一個方法的形式參數(shù)是一個類類型(引用類型),這里其實需要的是該類的對象。public void method(Student s) { //調(diào)用的時候,把main方法中的s的地址傳遞到了這里 Student s = new Student();s.show();}
}class ArgsTest {public static void main(String[] args) {//形式參數(shù)是基本類型的調(diào)用Demo d = new Demo();int result = d.sum(10,20);System.out.println("result:"+result);System.out.println("--------------");//形式參數(shù)是引用類型的調(diào)用//需求:我要調(diào)用StudentDemo類中的method()方法StudentDemo sd = new StudentDemo();//創(chuàng)建學(xué)生對象Student s = new Student();sd.method(s); //把s的地址給到了這里}
}
運行結(jié)果:
2.6 匿名對象
匿名對象:就是沒有名字的對象。是對象的一種簡化表示形式
匿名對象的兩種使用情況:對象調(diào)用方法僅僅一次的時候;作為實際參數(shù)傳遞。
/**匿名對象:就是沒有名字的對象。匿名對象的應(yīng)用場景:A:調(diào)用方法,僅僅只調(diào)用一次的時候。注意:調(diào)用多次的時候,不適合。那么,這種匿名調(diào)用有什么好處嗎?有,匿名對象調(diào)用完畢就是垃圾。可以被垃圾回收器回收。B:匿名對象可以作為實際參數(shù)傳遞
*/
class Student {public void show() {System.out.println("我愛學(xué)習(xí)");}
}class StudentDemo {public void method(Student s) {s.show();}
}class NoNameDemo {public static void main(String[] args) {//帶名字的調(diào)用Student s = new Student();s.show();s.show();System.out.println("--------------");//匿名對象//new Student();//匿名對象調(diào)用方法new Student().show();new Student().show(); //這里其實是重新創(chuàng)建了一個新的對象System.out.println("--------------");//匿名對象作為實際參數(shù)傳遞StudentDemo sd = new StudentDemo();//Student ss = new Student();//sd.method(ss); //這里的s是一個實際參數(shù)//匿名對象sd.method(new Student());//在來一個new StudentDemo().method(new Student());}
}
運行結(jié)果:
2.7 封裝(private)
封裝概述:是指隱藏對象的屬性和實現(xiàn)細(xì)節(jié),僅對外提供公共訪問方式。
封裝的好處:
- 隱藏實現(xiàn)細(xì)節(jié),提供公共的訪問方式
- 提高了代碼的復(fù)用性
- 提高安全性。
封裝原則:
- 將不需要對外提供的內(nèi)容都隱藏起來。
- 把屬性隱藏,提供公共方法對其訪問。
private關(guān)鍵字:
- 是一個權(quán)限修飾符。
- 可以修飾成員(成員變量和成員方法)
- 被private修飾的成員只在本類中才能訪問。
private最常見的應(yīng)用:
- 把成員變量用private修飾
- 提供對應(yīng)的getXxx()/setXxx()方法
- 一個標(biāo)準(zhǔn)的案例的使用
/**封裝和private的應(yīng)用:A:把成員變量用private修飾B:提高對應(yīng)的getXxx()和setXxx()方法
*/
//定義學(xué)生類
class Student {//姓名private String name;//年齡private int age;//姓名獲取值public String getName() {return name;}//姓名設(shè)置值public void setName(String n) {name = n;}//年齡獲取值public int getAge() {return age;}//年齡賦值public void setAge(int a) {age = a;}
}//測試類
class StudentTest {public static void main(String[] args) {//創(chuàng)建學(xué)生對象Student s = new Student();//使用成員變量//錯誤:被私有修飾了,外界不能直接訪問了//System.out.println(s.name+"---"+s.age);System.out.println(s.getName()+"---"+s.getAge());//給成員變量賦值//s.name = "林青霞";//s.age = 27;//通過方法給賦值s.setName("林青霞");s.setAge(27);System.out.println(s.getName()+"---"+s.getAge());}
}
運行結(jié)果:
2.8 this關(guān)鍵字
this:代表所在類的對象引用
記住:方法被哪個對象調(diào)用,this就代表那個對象
什么時候使用this呢?
- 局部變量隱藏成員變量
- 其他用法后面和super一起講解
/** 我們曾經(jīng)曰:起名字要做到見名知意。this:是當(dāng)前類的對象引用。簡單的記,它就代表當(dāng)前類的一個對象。注意:誰調(diào)用這個方法,在該方法內(nèi)部的this就代表誰。this的場景:解決局部變量隱藏成員變量this:哪個對象調(diào)用那個方法,this就代表那個對象
*/
class Student {private String name;private int age;public String getName() {return name; //這里其實是隱含了this}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}class StudentTest2 {public static void main(String[] args) {//創(chuàng)建一個對象Student s1 = new Student();s1.setName("林青霞");s1.setAge(27);System.out.println(s1.getName()+"---"+s1.getAge());//創(chuàng)建第二個對象Student s2 = new Student();s2.setName("劉意");s2.setAge(30);System.out.println(s2.getName()+"---"+s2.getAge());}
}
運行結(jié)果:
this關(guān)鍵字的內(nèi)存圖解:
2.9 構(gòu)造方法
構(gòu)造方法作用概述:給對象的數(shù)據(jù)進行初始化
構(gòu)造方法格式
- 方法名與類名相同
- 沒有返回值類型,連void都沒有
- 沒有具體的返回值
構(gòu)造方法注意事項
- 如果你不提供構(gòu)造方法,系統(tǒng)會給出默認(rèn)構(gòu)造方法
- 如果你提供了構(gòu)造方法,系統(tǒng)將不再提供
- 構(gòu)造方法也是可以重載的
給成員變量賦值有兩種方式:
- setXxx()
- 構(gòu)造方法
PS:
1、一般函數(shù)和構(gòu)造函數(shù)什么區(qū)別呢?
構(gòu)造函數(shù):對象創(chuàng)建時,就會調(diào)用與之對應(yīng)的構(gòu)造函數(shù),對對象進行初始化。
一般函數(shù):對象創(chuàng)建后,需要函數(shù)功能時才調(diào)用。
構(gòu)造函數(shù):對象創(chuàng)建時,會調(diào)用并且只調(diào)用一次。
一般函數(shù):對象創(chuàng)建后,可以被調(diào)用多次。
2、創(chuàng)建對象都必須要通過構(gòu)造函數(shù)初始化。
一個類中如果沒有定義過構(gòu)造函數(shù),那么該類中會有一個默認(rèn)的空參數(shù)構(gòu)造函數(shù)。
如果在類中定義了指定的構(gòu)造函數(shù),那么類中的默認(rèn)構(gòu)造函數(shù)就沒有了。
3、多個構(gòu)造函數(shù)是以重載的形式存在的。
/**我們一直在使用構(gòu)造方法,但是,我們確沒有定義構(gòu)造方法,用的是哪里來的呢?構(gòu)造方法的注意事項:A:如果我們沒有給出構(gòu)造方法,系統(tǒng)將自動提供一個無參構(gòu)造方法。B:如果我們給出了構(gòu)造方法,系統(tǒng)將不再提供默認(rèn)的無參構(gòu)造方法。注意:這個時候,如果我們還想使用無參構(gòu)造方法,就必須自己給出。建議永遠(yuǎn)自己給出無參構(gòu)造方法給成員變量賦值有兩種方式:A:setXxx()B:構(gòu)造方法
*/class Student {private String name;private int age;public Student() {//System.out.println("我給了,你還給不");System.out.println("這是無參構(gòu)造方法");}//構(gòu)造方法的重載格式public Student(String name) {System.out.println("這是帶一個String類型的構(gòu)造方法");this.name = name;}public Student(int age) {System.out.println("這是帶一個int類型的構(gòu)造方法");this.age = age;}public Student(String name,int age) {System.out.println("這是一個帶多個參數(shù)的構(gòu)造方法");this.name = name;this.age = age;}public void show() {System.out.println(name+"---"+age);}
}class ConstructDemo2 {public static void main(String[] args) {//創(chuàng)建對象Student s = new Student();s.show();System.out.println("-------------");//創(chuàng)建對象2Student s2 = new Student("林青霞");s2.show();System.out.println("-------------");//創(chuàng)建對象3Student s3 = new Student(27);s3.show();System.out.println("-------------");//創(chuàng)建對象4Student s4 = new Student("林青霞",27);s4.show();}
}
2.10 類的成員方法
成員方法其實就是我們前面講過的方法
方法具體劃分:
- 根據(jù)返回值:有明確返回值方法;返回void類型的方法
- 根據(jù)形式參數(shù):無參方法;帶參方法
一個基本類的標(biāo)準(zhǔn)代碼寫法
/**一個標(biāo)準(zhǔn)代碼的最終版。學(xué)生類:成員變量:name,age構(gòu)造方法:無參,帶兩個參成員方法:getXxx()/setXxx()show():輸出該類的所有成員變量值給成員變量賦值:A:setXxx()方法B:構(gòu)造方法輸出成員變量值的方式:A:通過getXxx()分別獲取然后拼接B:通過調(diào)用show()方法搞定
*/
class Student {//姓名private String name;//年齡private int age;//構(gòu)造方法public Student() {}public Student(String name,int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}//輸出所有的成員變量值public void show() {System.out.println(name+"---"+age);}
}//測試類
class StudentTest {public static void main(String[] args) {//方式1給成員變量賦值//無參構(gòu)造+setXxx()Student s1 = new Student();s1.setName("林青霞");s1.setAge(27);//輸出值System.out.println(s1.getName()+"---"+s1.getAge());s1.show();System.out.println("----------------------------");//方式2給成員變量賦值Student s2 = new Student("劉意",30);System.out.println(s2.getName()+"---"+s2.getAge());s2.show();}
}
運行結(jié)果:
2.11 類的初始化過程
Student s = new Student();在內(nèi)存中做了哪些事情?
- 加載Student.class文件進內(nèi)存
- 在棧內(nèi)存為s開辟空間
- 在堆內(nèi)存為學(xué)生對象開辟空間
- 對學(xué)生對象的成員變量進行默認(rèn)初始化
- 對學(xué)生對象的成員變量進行顯示初始化
- 通過構(gòu)造方法對學(xué)生對象的成員變量賦值
- 學(xué)生對象初始化完畢,把對象地址賦值給s變量
2.12 static關(guān)鍵字
static關(guān)鍵字可以修飾成員變量和成員方法
static關(guān)鍵字特點
- 隨著類的加載而加載
- 優(yōu)先于對象存在
- 被類的所有對象共享
- 這也是我們判斷是否使用靜態(tài)關(guān)鍵字的條件
- 可以通過類名調(diào)用
static關(guān)鍵字注意事項
- 在靜態(tài)方法中是沒有this關(guān)鍵字的
- 靜態(tài)方法只能訪問靜態(tài)的成員變量和靜態(tài)的成員方法
靜態(tài)的內(nèi)存圖
靜態(tài)變量和成員變量的區(qū)別
2.13 main方法是靜態(tài)的
public static void main(String[] args) {}
- public 被jvm調(diào)用,訪問權(quán)限足夠大。
- static 被jvm調(diào)用,不用創(chuàng)建對象,直接類名訪問
- void被jvm調(diào)用,不需要給jvm返回值
- main 一個通用的名稱,雖然不是關(guān)鍵字,但是被jvm識別
- String[] args 以前用于接收鍵盤錄入的
- 靜態(tài)什么時候用?
靜態(tài)變量
當(dāng)分析對象中所具備的成員變量的值都是相同時,這時這個成員就可以被靜態(tài)修飾。
只要數(shù)據(jù)在對象中都是不同的,就是對象的特有數(shù)據(jù),必須存儲在對象中,是非靜態(tài)的。
如果是相同的數(shù)據(jù),對象不需要做修改,只需要使用即可,不需要存儲在對象中,定義成靜態(tài)的。
靜態(tài)函數(shù)
函數(shù)是否用靜態(tài)修飾,就參考一點,就是該函數(shù)功能是否需要訪問到對象中的特有數(shù)據(jù)。
簡單點說,從源代碼看,該功能是否需要訪問非靜態(tài)的成員變量,如果需要,該功能就是非靜態(tài)的。
如果不需要,就可以將該功能定義成靜態(tài)的。當(dāng)然,也可以定義成非靜態(tài),但是非靜態(tài)需要被對象調(diào)用。
如果沒有訪問特有數(shù)據(jù)的方法,該對象的創(chuàng)建是沒有意義。
/*main方法的格式講解:public static void main(String[] args) {...}public:公共的,訪問權(quán)限是最大的。由于main方法是被jvm調(diào)用,所以權(quán)限要夠大。static:靜態(tài)的,不需要創(chuàng)建對象,通過類名就可以。方便jvm的調(diào)用。void:因為我們曾經(jīng)說過,方法的返回值是返回給調(diào)用者,而main方法是被jvm調(diào)用。你返回內(nèi)容給jvm沒有意義。main:是一個常見的方法入口。我見過的語言都是以main作為入口。String[] args:這是一個字符串?dāng)?shù)組。值去哪里了?這個東西到底有什么用啊?怎么給值啊?這個東西早期是為了接收鍵盤錄入的數(shù)據(jù)的。格式是:java MainDemo hello world java
*/
class MainDemo {public static void main(String[] args) {//System.out.println(args); //[Ljava.lang.String;@175078b//System.out.println(args.length); //0//System.out.println(args[0]); //ArrayIndexOutOfBoundsException//接收數(shù)據(jù)后System.out.println(args); System.out.println(args.length); //System.out.println(args[0]); for(int x=0; x<args.length; x++) {System.out.println(args[x]);}}
}
運行結(jié)果:
3. 修飾符
4. 關(guān)鍵字
總結(jié)
以上是生活随笔為你收集整理的Java基础:面向对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
面向?qū)ο笤O(shè)計:其實就是在管理和維護對象之間的關(guān)系。
對象:是該類事物的具體體現(xiàn)
舉例:類 學(xué)生,對象班長就是一個對象
類:可以理解為構(gòu)造對象的一個藍(lán)圖或者模版,是抽象的概念
對象:是以類為模型創(chuàng)建的具體實例,是對類的一種具體化。
引用類型作為形式參數(shù):形式參數(shù)的改變直接影響實際參數(shù)
匿名對象的兩種使用情況:對象調(diào)用方法僅僅一次的時候;作為實際參數(shù)傳遞。
記住:方法被哪個對象調(diào)用,this就代表那個對象
- setXxx()
- 構(gòu)造方法
1、一般函數(shù)和構(gòu)造函數(shù)什么區(qū)別呢?
一般函數(shù):對象創(chuàng)建后,需要函數(shù)功能時才調(diào)用。
一般函數(shù):對象創(chuàng)建后,可以被調(diào)用多次。
- 根據(jù)返回值:有明確返回值方法;返回void類型的方法
- 根據(jù)形式參數(shù):無參方法;帶參方法
- 上一篇: Java基础:动态代理
- 下一篇: Java基础:类加载器