面向對象三大特徵
一、面向對象和面向過程的區別
1、面向過程(Procedure Oriented 簡稱PO)
看名字它是注重過程的。當解決一個問題的時候,面向過程會把事情拆分成: 一個個函數和 數據(用於方法的參數) 。然後按照一定的順序,執行完這些方法(每個方法看作一個個過程),等方法執行完了,事情就搞定了。
舉例: 大象裝冰箱
1、打開冰箱門
2、將大象放進冰箱
3、關閉冰箱門
2、面向對象(Object Oriented簡稱OO)
看名字它是注重對象的。當解決一個問題的時候,面向對象會把事物抽象成對象的概念,就是說這個問題裡面有哪些對象,然後給對象賦一些屬性和方法,然後讓每個對象去執行自己的方法,問題得到解決。
舉例: 大象裝冰箱
1、對象:冰箱
方法:打開門(),關閉門()
2、對象:大象
方法:進入()
3、demo(主方法)
4、執行:.冰箱.打開(),大象.進入(),冰箱.關閉(冰箱)
二、面向對象三大特徵
1、封裝
a、定義
將程式碼通過許可權修飾符來限定甚至隱藏起來,起到部分程式碼不可見從而減少被外部類對象調用修改的風險。
許可權修飾範圍如下:

從表格中可以看出從上到下封裝性越來越差
b、this關鍵字
this關鍵字代表當前對象,採取this.屬性,this.方法可以來進行操作當前的屬性和方法
c、內部類(Inner Class)
定義在一個類(A)中的一個類(B),可以對程式碼進行有效的封裝,且相對於內部類(B)來說A就是外部類,內部類B可以 調用外部類中的一切屬性和一切方法,不包括匿名方法,和程式碼塊
2、繼承
a、定義
類與類之間達成 “is a” 的關係,比如:A繼承B,那麼A就是父類(基類),B就是子類(派生類)
註:1、java中類的繼承是單繼承的,即一個類的父類只能有一個
2、java中類的繼承可以傳遞,C繼承B,B繼承A,那麼C可以間接的繼承了A,C中擁有A中的屬性和方法(不包括 私有)
b、繼承的好處
子類可以擁有父類除了private修飾的所有的屬性和方法,從而實現了程式碼的復用
c、繼承類載入執行順序
B繼承A
0)、載入A的類模板
1)、A產生靜態區,載入A的靜態方法,靜態屬性和靜態程式碼塊即:static 修飾的屬性,static修飾的方法,static修飾的程式碼塊
2)、載入B的類模板
3)、B產生靜態區,載入B的靜態方法,靜態屬性和靜態程式碼塊即:static 修飾的屬性,static修飾的方法,static修飾的程式碼塊
4)、堆記憶體開闢空間,載入父類A的非靜態元素(屬性,方法,程式碼塊,構造方法)
5)、執行父類A程式碼塊/執行父類A構造函數
6)、堆記憶體開闢空間,載入子類B的非靜態元素(屬性,方法,程式碼塊,構造方法)
7)、執行子類B程式碼塊/執行子類B構造函數
8)、將堆記憶體的地址引用傳遞給占記憶體開闢的變數
d、final修飾符
修飾類:即為最終的類,不可被繼承
修飾方法:即為最終的方法,不可被重寫
修飾屬性:即為最終的屬性,
當屬性為基本類型,則在聲明時必須賦值,且屬性不可修改。
當屬性為引用類型,則聲明時可以不複製,但僅保留一次賦值機會,且賦值後,屬性的值(地址)不可被修改
e、super關鍵字
在子類對象內部使用,可以代替父類對象
super.屬性–>調用父類的屬性
super.方法–>調用父類的方法
備註:
子類在調用構造函數時,會默認調用super.父類構造函數(隱式構造函數)。
若是子類調用構造函數時,自己寫super.父類構造函數,那麼super.父類構造函數必須寫在子類構造函數中的第一行
如果子類構造方法中既沒有顯式調用父類的構造方法,而父類沒有無參的構造方法,則編譯出錯。
3、多態
a、定義
父類引用指向子類的對象,此時形成多態的效果
b、舉例說明
定義一個animal類如下:
1 public class Animal { 2 3 /** 4 * 定義一個animal父類 5 * 添加一個屬性為name 6 * 添加一個方法為eat() 7 */ 8 9 public String name; 10 11 public void eat(){ 12 System.out.println("動物正在進食"); 13 } 14 15 }
定義一個dog類,且dog類繼承animal
1 public class Dog extends Animal { 2 3 /** 4 * 定義一個dog類來繼承animal 5 */ 6 7 }
此時我們在主方法中進行new 一個dog對象來看下
1 public class TestMain { 2 3 /** 4 * 定義一個測試類 5 * 類中定義一個主方法 6 * @param args 7 */ 8 9 public static void main(String[] args) { 10 11 Dog dog = new Dog(); 12 dog.eat(); 13 14 } 15 16 }
執行結果為:

由此可知子類繼承父類,也就繼承了父類的所有的非private修飾的方法和屬性,我們在dog類中重寫父類的eat()方法
1 public class Dog extends Animal { 2 3 /** 4 * 定義一個dog類來繼承animal 5 */ 6 7 public void eat(){ 8 System.out.println("狗狗正在進食"); 9 } 10 }
此時我們在主方法中再次運行一下,結果如下:

由此我們可以知道當子類繼承父類時,子類若是重寫了父類的eat()方法,運行的結果是執行子類的方法,若是子類沒有重寫方法,那麼就會直接調用父類的eat()方法
以下為多態的演示:
我們在dog類中在定義一個方法,且new Dog對象時,我們用父類來接收,程式碼如下:
1 public class Dog extends Animal { 2 3 /** 4 * 定義一個dog類來繼承animal 5 */ 6 7 public void eat(){ 8 System.out.println("狗狗正在進食"); 9 } 10 11 //新寫一個dog類獨有的方法 12 public void run(){ 13 System.out.println("狗狗正在奔跑"); 14 } 15 }
此時我們在用父類來接受子類的對象
你會發現,我們找尋不到Dog類中獨有的run()方法,接著我們在執行一下eat()方法

輸出的是Dog類中重寫的eat()方法,是不是很神奇,那麼此時我們在縱向思考下,假設我們現在有一個Cat類也繼承Animal類並且重寫了eat()方法,那麼我們若是在定義一個Cat類繼承Animal並且重寫eat()方法
1 Animal animal = new Cat(); 2 animal.eat();
此時執行出的結果就會是 「貓咪正在進食」,我都是用Animal類型接受的,但是我new的對象不同,我就會輸出不同的結果,這就是多態;
那我們要執行dog的獨有run()方法怎麼辦呢?此時就要進行向下轉型

進行向下轉型後就會出現Dog獨有的run()方法,由此我們總結以下墮胎的特性:
1、必需存在繼承關係
2、子類必需重寫了父類的方法
3、父類來收子類的對象 Animal animal = new Dog() 此處就是向上轉型。我new出一個狗的對象,用Animal動物來接受,相當於我說狗是一種動物,這是完全合理的。 總結為接受的類的類型必需大於或者等於子類
4、父類接受子類對象後,調用的方法或者屬性都是父類中擁有的方法或者屬性,但是執行的結果若是子類有重寫,那就執行執行子類重寫的方法,若是子類沒有重寫方法,那麼執行父類自己的方法
5、父類接受子類對象後,若是調用子類獨有的方法或者屬性,必需要將父類類型向下轉型為子類類型
以上就是面向對象的三大特性,到此結束!!!