目錄
一、面向對象的概述:
二、封裝:
1、封裝概述
2、封裝原則
3、封裝好處
4、封裝壞處
5、封裝代碼展示
三、繼承:
1、概念:
2、實現格式:
3、特點:
4、好處:
5、弊端:
6、應用場景
7、繼承中變量的訪問特點:
8、關鍵字
9、方法重寫
10、 Java繼承中的注意事項:
11、代碼演示:
(貓狗類繼承動物類的案例,大家就自己試試吧?給大家演示一個完整例題。)
四、多態:
1、概念:
2、前提條件:
3、多態中成員變量的訪問特點是什么?
4、多態中成員方法的訪問特點是什么?
5、好處與弊端
6、類形態的轉換
7、形式分類:
8、多態的優點:
9、什么是虛擬方法調用?
五、補充之六大原則:
1、單一職責原則 (SRP)(Single Responsibility Principle)
2、開放封閉原則OCP(Open-Close Principle)
3、里式替換原則LSP(the Liskov Substitution Principle LSP)
4、依賴倒置原則DIP(the Dependency Inversion Principle DIP)
5、接口分離原則ISP(the Interface Segregation Principle ISP)
6、迪米特法則(Law of Demeter,簡稱LoD)
一、面向對象的概述:
面向對象簡單來說就是將功能封裝到對象(數據和操作結合)里,我們面向對象,讓對象去完成這些功能。
什么是對象?萬物皆對象,客觀存在的事物皆是對象。
面向對象(Object Oriented,OO)是軟件開發的方法。而面向對象的概念和應用已超脫于程序設計和軟件開發,擴展到如數據庫系統、交互式界面、應用結構、應用平臺、分布式系統、網絡管理結構、CAD技術、人工智能等領域。
面向對象是一種對現實世界理解和抽象的方法,是計算機編程技術發展到一定階段后的產物。
JAVA是一門面向對象的語言,那么其面向對象主要有以下幾個特性和原則:
三大特性:封裝、繼承、多態。
六大原則:SPR,CCP,LSP,DIP,ISP,LoD
今天我們主要來說一下面向對象的三大特性。
二、封裝:
1、封裝概述
是面向對象三大特征之一(封裝,繼承,多態)
是面向對象編程語言對客觀世界的模擬,客觀世界里成員變量都是隱藏在對象內部的,外界是無法直接操作的。
2、封裝原則
將類的某些信息隱藏在類內部,不允許外部程序直接訪問,而是通過該類提供的方法來實現對隱藏信息的操作和訪問
成員變量private,提供對應的getXxx()/setXxx()方法
3、封裝好處
通過方法來控制成員變量的操作,提高了代碼的安全性
把代碼用方法進行封裝,提高了代碼的復用性。
4、封裝壞處
如果封裝的方法出現問題,或者修改,對于其所引用的對象,則需要大量的修改。
5、封裝代碼展示
package sort; public class Customer { private String name; private String id_card; private String number; private String home_address; public Customer() { super(); } public Customer(String name, String id_card, String number, String home_address) { this.name = name; this.id_card = id_card; this.number = number; this.home_address = home_address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId_card() { return id_card; } public void setId_card(String id_card) { this.id_card = id_card; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public String getHome_address() { return home_address; } public void setHome_address(String home_address) { this.home_address = home_address; } public String say() { String info = "姓名:" + name + "\n身份證號:" + id_card + "\n電話:" + number + "\n家庭住址:" + home_address; return info; }}
成員屬性,構造方法(構造器),get/set方法,命令方法。一個簡單完整的封裝就可以了。
封裝可以使我們容易地修改類的內部實現,而無需修改使用了該類的客戶代碼。就可以對成員變量進行更精確的控制。
比如:
public String getSexName() { if("0".equals(sex)){ sexName = "女"; }else if("1".equals(sex)){ sexName = "男"; }else{ sexName = "人妖"; } return sexName; }
三、繼承
1、概念:
繼承也是面向對象三大特征之一。
可以使得子類具有父類的屬性和方法,還可以在子類中重新定義,
以及追加屬性和方法。
2、實現格式:
通過extends關鍵字實現繼承
?? ?格式: class 子類 extends 父類 { }
3、特點:
子類可以有父類的內容,子類還可以有自己特有的內容
4、好處:
提高了代碼的復用性(多個類相同的成員可以放到同一個類中)
提高了代碼的維護性(如果方法的代碼需要修改,修改一處即可)
5、弊端:
繼承讓類與類之間產生了關系,類的耦合性增強了,當父類發生變化時子類實現也不得不跟著變化,削弱了子類的獨立性。
6、應用場景
使用繼承,需要考慮類與類之間是否存在is..a的關系,不能盲目使用繼承
is..a的關系:誰是誰的一種,例如:老師和學生是人的一種,那人就是父類,學生和老師就是子類。
例如:假設我有兩個類A和B,如果滿足A是B的一種,或者B是A的一種,就說明他們存在繼承關系,這個時候就可以考慮使用繼承來體現,否則就不能濫用繼承。
7、繼承中變量的訪問特點:
在子類方法中訪問一個變量,采用的是就近原則。
子類局部范圍找
子類成員范圍找
父類成員范圍找
如果都沒有就報錯(不考慮父親的父親…)
8、關鍵字
this關鍵字:this:代表本類對象(成員變量)的引用。
super關鍵字:super:代表父類存儲空間的標識(可以理解為父類對象引用)。
this和super的使用區別(三種訪問方法):
成員變量:
?? ?this.成員變量 ? ?- ? 訪問本類成員變量
?? ?super.成員變量 - ? 訪問父類成員變量
成員方法:
?? ?this.成員方法?? ?- 訪問本類成員方法
?? ?super.成員方法 - 訪問父類成員方法
構造方法:
?? ?this(…)?? ?- ?訪問本類構造方法
?? ?super(…)?? ?- ?訪問父類構造方法
9、方法重寫
概念:子類出現了和父類中一模一樣的方法聲明(方法名一樣,參數列表也必須一樣).
應用場景:當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容。
@Override:注解:用來檢測當前的方法,是否是重寫的方法,起到【校驗】的作用。
方法重寫的注意事項:
1. 私有方法不能被重寫(父類私有成員子類是不能繼承的)
2. 子類方法訪問權限不能更低(public > 默認 > 私有)
10、 Java繼承中的注意事項:
java中,類支持單繼承,不支持多繼承,支持多層繼承。
錯誤范例:class A extends B, C { }
Java中類支持多層繼承
正確范例:
?? ?class A {} ??
?? ?class B extends A{ } ??
?? ?class C extends B{ }
11、代碼演示:
(貓狗類繼承動物類的案例,大家就自己試試吧?給大家演示一個完整例題。)
1、這是一個封裝類
package inherit01; /*(1)定義一個ManKind類,包括?成員變量int sex和int salary;?方法void manOrWoman():根據sex的值顯示“man”(sex==1)或者“woman”(sex==0);?方法void employeed():根據salary的值顯示“no job”(salary==0)或者“ job”(salary!=0)。 */ public class ManKind { public int sex; public int salary; public ManKind() { } public ManKind(int sex, int salary) { this.sex = sex; this.salary = salary; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public void manOrWoman(int sex){ if(sex == 1){ System.out.println("man"); }else if(sex == 0){ System.out.println("woman"); } } public void employeed(int salary){ if(salary == 0){ System.out.println("no job"); }else { System.out.println("job"); } }}
2、這是繼承了上一個封裝的類
package inherit01; /*(2)定義類Kids繼承ManKind,并包括?成員變量int yearsOld;?方法printAge()打印yearsOld的值。 */public class Kids extends ManKind{ public int yearsOld; public Kids() { } public Kids(int yearsOld) { this.yearsOld = yearsOld; } public int getYearsOld() { return yearsOld; } public void setYearsOld(int yearsOld) { this.yearsOld = yearsOld; } public void printAge(int yearsOld){ System.out.println("yearsOld: "+yearsOld); }}
?最后定義一個測試類
package inherit01;/*(3)定義類KidsTest,在類的main方法中實例化Kids的對象someKid,用該對象訪問其父類的成員變量及方法。 */public class KidsTest { public static void main(String[] args) { Kids someKid=new Kids(); someKid.setSex(1); someKid.setSalary(6666); someKid.setYearsOld(25); someKid.manOrWoman(someKid.getSex()); someKid.employeed(someKid.salary); someKid.printAge(someKid.yearsOld); }}
四、多態
1、概念:
同一個對象,在不同時刻表現出來的不同形態。(多態性:多態性是對象多種表現形式的體現)
(例如:我們可以說貓是貓,貓 cat = new cat(); ? ? ? ? 我們也可以說貓是動物:動物 animal = new 貓(); ? ? ? ?這時,貓在不同時刻表現出來了不同的形態,這就是多態。)
2、前提條件:
要有繼承/實現關系
要有方法重寫
要有父(類/接口)引用指向子(子/實現)類對象
3、多態中成員變量的訪問特點是什么?
(編譯看左邊、運行看左邊)
舉例:比如還是貓,我們創建對象,Animal a=new Cat(); ? ?當我們編譯(sout(a.屬性)),這時我們會發現,這里的屬性,尋找的是Animal類中的屬性,而不是Cat中的屬性。 ? ? ? 同理,運行時(即控制臺輸出時的值),我們會發現也看的Animal類中的數據屬性。
4、多態中成員方法的訪問特點是什么?
(編譯看左邊、運行看右邊)
同上,編譯時看創建對象的左邊,即Animal父類,而不是貓Cat類。而此時的運行,卻是看右邊的方法里數據內容了。
(為什么成員變量和成員方法的訪問不一樣呢?因為成員方法有重寫,而成員變量沒有。)
5、好處與弊端
好處:提高了代碼的擴展性。
? ? ? ?定義方法時,如果將父類型作為參數,在使用方法時,可以傳遞任意子類對象。
弊端:不能使用子類特有的成員,不能使用子類的特有功能,比如特有的方法。
6、類形態的轉換
向上轉型:父類引用指向子類對象其實就是向上轉型。例如:
? ? ? ?Animal a = new Dog(); ? Animal是父類, Animal a中的a就是父類引用,new Dog就是子類對象。
向下轉型:將父類型的引用轉換成具體的子類對象。轉換格式:
? ? ? ?子類 對象名 = (子類)父類引用; ? ?例如:Cat c= (Cat)a;
7、形式分類:
(1):具體類多態(幾乎是不用的)
(2):抽象類多態
(3):接口多態
8、多態的優點:
(1). 消除類型之間的耦合關系
(2). 可替換性
(3). 可擴充性
(4). 接口性
(5). 靈活性
(6). 簡化性
9、什么是虛擬方法調用?
1.子類中定義了與父類同名同參數的方法,在多態情況下,將此時父類的方法稱為虛擬方法,父類根據賦給它的不同子類對象,動態調用屬于子類的該方法。這樣的方法調用在編譯期是無法確定的。
2.多態是運行時行為,不是編譯時行為。
10、代碼演示
(1).我們定義一個父類:Animal
public class Animal { public void eat() { System.out.println("動物吃東西"); } }
? ? (2).我們再定義一個子類繼承父類:Cat extends Animal
public class Cat extends Animal { @Override public void eat() { System.out.println("貓吃魚"); } }
(3)最后我們再定義一個測試類,實現多態
多態: 同一個對象,在不同時刻表現出來的不同形態 舉例:貓 我們可以說貓是貓:貓 cat = new 貓(); 我們也可以說貓是動物:動物 animal = new 貓(); 這里貓在不同的時刻表現出來了不同的形態,這就是多態 多態的前提和體現 有繼承/實現關系 有方法重寫 有父類引用指向子類對象 */public class AnimalDemo { public static void main(String[] args) { //有父類引用指向子類對象 Animal a = new Cat(); }}
五、補充之六大原則:
總述:面向對象的六大原則
六大原則指的是單一職責原則、開閉式原則、里氏替換原則、依賴倒置原則、接口隔離原則以及迪米特原則。
1、單一職責原則 (SRP)(Single Responsibility Principle)
就一個類而言,應該只有一個引起它變化的原因。簡單來說,一個類應該是一組相關性很高的函數和數據的封裝。因為單一職責的劃分界限并不是那么清晰,每個人的理解不一樣,這就導致了不同的人劃分的類承擔的職責也不一樣,就圖片加載的例子來說,可能有的人就認為整個圖片加載是一組相關性很高的功能,于是將其放入在一個類中處理。一般來說,我們首先需要具備單一職責原則的思想,如果發現一個類承擔了太多的功能,這個時候就要考慮將某些功能劃分到其他類中去處理,具體的劃分細節要平開發者的個人經驗。
2、開放封閉原則OCP(Open-Close Principle)
軟件中的對象應該對擴展是開放的,但是,對修改是關閉的。軟件開發過程中,需求是不斷變化的,因為變化、升級和維護等原因需要對原有的軟件代碼進行修改,而一旦對原有的代碼進行修改,就有可能影響到原有的模塊,引起bug,因此,在軟件開發過程中,我們應該盡可能通過擴展的方式實現變化,而不是修改原有的代碼,當然,這是一種理想的情況,在實際的軟件開發中,完全通過擴展的方式實現變化是不現實的。
3、里式替換原則LSP(the Liskov Substitution Principle LSP)
所有引用基類的地方都必須能夠透明的使用其子類。通過建立抽象,讓高層次模塊依賴于抽象類,在運行時在替換成具體的實現類,保證了系統的擴展性和靈活性。
4、依賴倒置原則DIP(the Dependency Inversion Principle DIP)
依賴倒置原則指的是高層次模塊不應該依賴于低層次模塊的具體實現,兩者都應該依賴其抽象,具體如下:
1、高層次模塊不應該依賴低層次模塊的具體實現,兩者都應該依賴其抽象;
2、抽象不應該依賴細節;
3、細節應該依賴抽象。
在面向對象語言中,抽象指的是接口或者抽象類,兩者都不能被實例化,而細節指的是具體的實現類。其實一句話就可以概括,面向接口編程,或者說面向抽象編程,試想一下,如果類和類之間之間依賴細節,那么這兩個類將會緊緊的耦合在一起,這就意味著,修改了其中一個類,很可能需要對另外一個類也需要進行修改,并且這樣也大大限制了系統的可擴展性。依賴倒置原則提供了一種解耦方式,通過抽象讓類和類之間不再依賴細節,而是在具體運行時再進行替換。
5、接口分離原則ISP(the Interface Segregation Principle ISP)
類間的依賴關系應該建立在最小的接口之上。接口隔離原則將非常龐大、臃腫的接口拆分成更小更具體的接口。
一個接口定義的過于臃腫,則代表它的每一個實現類都要考慮所有的實現邏輯。如果一個類實現了某個接口,也就是說這個類承載了這個接口所有的功能,維護這些功能成為了自己的職責。這就無形中增加了一個類的負擔。
這里有一點需要說明,接口定義要小,但是要有限度,對接口細化可以增加靈活性,但是過度細化則會使設計復雜化。同時接口的使用率不高,提高了代碼的維護成本。這種極端的體現就是每個接口只含有一個方法,這顯然是不合適的。
6、迪米特法則(Law of Demeter,簡稱LoD)
一個對象應該對其他對象有最小的了解。迪米特原則也稱作最小知道原則,即類和類直接應該建立在最小的依賴之上,一個類應該對其依賴的類有最小的了解,即只需要知道其所需要的方法即可,至于其內部具體是如何實現的則不用關心。迪米特原則的目的是減少類和類之間的耦合性,類和類之間的耦合性越大,當一個類發生修改后,會其他類造成的影響也越大。
以上,就是今天小知識課堂的全部了,咚咚咚(敲黑板),下課。
---------------------
作者:IT_ZI-O
來源:CSDN
原文:https://blog.csdn.net/Lee0620/article/details/120270751?utm_medium=distribute.pc_category.none-task-blog-hot-10.nonecase&depth_1-utm_source=distribute.pc_category.none-task-blog-hot-10.nonecase
版權聲明:本文為作者原創文章,轉載請附上博文鏈接!
內容解析By:CSDN,CNBLOG博客文章一鍵轉載插件