Java 面向物件有哪些知識點(整理精選)
一、過載、重寫和隱藏
1、過載(overload):
方法過載就是多個方法名稱相同但是引數型別或者引數個數不同的方法,與返回值型別和修飾符無關
class Test { public int test(int a) { return a; } public String test(String a) { return a; } public float test(int a, String b) { return 0f; } public float test(String a, int b) { return 1.0f; } String test(float a) { return ""; } String test(int a) {//該方法不是過載 return ""; } }
前面五個互為過載,第一個和第六個雖然返回值型別不同,但引數相同,所以第一個和第六個引數不是過載
2、重寫(override):
子類繼承父類時,子類的方法名稱、引數型別、引數個數與父類完全相同,則認為子類重寫了父類的方法。
方法重寫規則:
引數列表和原方法完全相同
返回值型別和原方法相同或者為父類返回值型別的子型別
不能比原方法限制更嚴格的訪問級別(舉例:父類方法為public,那麼子類不能為protected、private)
父類方法被定義為final時,則不能被重寫
父類方法被定義為static時,不能被重寫,但是可以重寫宣告一個相同的方法(參考隱藏)
不能丟擲新的異常或比原方法更廣泛的異常(父類丟擲IOException,重寫方法不能丟擲Exception只能丟擲IOException或者IOException子類異常)
3、隱藏:
隱藏是針對於父類的成員變數和靜態方法而言的。子類中聲明瞭和父類相同的變數名或靜態方法(方法名相同、引數列表相同、返回型別相同)則實現了對父類成員變數和靜態方法的隱藏,下面舉個例子有助理解:
class A { static int a = 1; static int b = 2; int c = 33; public static void printA() { System.out.print(a); } public static void printB() { System.out.print(b); } } class B extends A { static int a = 3; static int b = 4; int c = 44; public static void printB() { System.out.print(b); } } public class Test { public static void main(String[] args) { B.printA(); B.printB(); System.out.print(B.a); A a = new B(); B b = new B(); a.printB(); b.printB(); System.out.print(a.c); System.out.print(b.c); } }
輸出結果:
如果子類中有相同名稱的靜態方法或變數父類的會被隱藏,如果子類中存在同名的靜態方法或變數,則會隱藏父類中得靜態方法或變數,此時子類呼叫的就是子類中自己的靜態方法或變數;如果子類中不存在同名的靜態方法或變數,則會呼叫父類中的靜態方法或變數;父類呼叫的始終是其本身的靜態方法和變數。
二、封裝:
封裝是把物件的屬性和操作結合為一個獨立的整體,隱藏物件內部操作的實現,使用者只需要通過其對外提供的方法來訪問該物件,無需知道其內部實現細節。
優點:
隱藏內部實現細節,提供公共訪問方式
類內部可以自由修改不影響其呼叫者
減少耦合度,提高安全性
三、繼承:
繼承是一個物件獲取另一個物件屬性的過程,關鍵字為extends和implements。
1、IS-A關係(一個物件所屬於另一個物件):
方式一. 用extends來實現繼承:
public class Animal { public void eat() { System.out.println("Animal eating..."); } } public class Mammal extends Animal { public void eat() { System.out.println("Mammal eating..."); } } public class Dog extends Mammal { public void eat() { System.out.println("Dog eating..."); } }
方式二. 用implements來實現繼承:
public interface Animal { void eat(); } public class Mammal extends Animal { public void eat() { System.out.println("Mammal eating..."); } } public class Dog extends Mammal { public void eat() { System.out.println("Dog eating..."); } }
無論方式一還是方式二,我們都可以用instanceof關鍵字檢查得出:Mammal是一個Animal(哺乳動物也是動物);Dog既是一個Mammal,也是一個Animal(狗既是哺乳動物也是動物)。
public class Test { /** * instanceof關鍵字檢查程式碼 */ public static void main(String[] args) { Mammal m = new Mammal(); Dog d = new Dog(); System.out.print(m instanceof Animal); System.out.print(d instanceof Mammal); System.out.print(d instanceof Animal); } }
輸出結果:
true true true
2、HAS-A關係(一個物件含有另一個物件的一些屬性):
public class Car{} public class Speed{} public class Benz extends Car{ private Speed sp; }
Benz含有Spend屬性,但Benz不是Spend
四、多型:
實現多型的三個必要條件:繼承、重寫、父類引用指向子類物件。
1、向上轉型:
我們例項化一個Dog物件可以用 Dog d = new Dog(); 我們也可以用 Animal d = new Dog();,後者就是向上轉型(父引用指向子物件),上面兩種方式創建出來的物件d,呼叫d.eat();輸出的結果都是Dog eating...,這就體現出了java得多型。向上轉型建立的物件會遺失掉和父類不同的方法和變數(不能用來呼叫子類特有的方法和變數)。
2、舉例說明:
class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } class B extends A { public String show(B obj) { return ("B and B"); } public String show(A obj) { return ("B and A"); } } class C extends B {} class D extends B {} class Test { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b)); // ① System.out.println(a1.show(c)); // ② System.out.println(a1.show(d)); // ③ System.out.println(a2.show(b)); // ④ System.out.println(a2.show(c)); // ⑤ System.out.println(a2.show(d)); // ⑥ System.out.println(b.show(b)); // ⑦ System.out.println(b.show(c)); // ⑧ System.out.println(b.show(d)); // ⑨ } }
輸出結果:
A and A // ① A and A // ② A and D // ③ B and A // ④ B and A // ⑤ A and D // ⑥ B and B // ⑦ B and B // ⑧ A and D // ⑨
前三個比較簡單不容易出錯,看看下面幾個:
④:a2是A的引用指向B物件,向上轉型建立的物件會遺失掉和父類不同的方法和變數,所以a2只能呼叫show(D obj)、show(A obj)兩個方法,所以a2.show(b)應該呼叫show(A obj)方法,B中重寫了該方法,所以執行時JVM會呼叫B類中重寫的show(A obj)方法,所以輸出B and A;
⑤: 原理同④;
⑥:a2.show(d)應該呼叫show(D obj)方法,B中沒有重寫該方法所以呼叫的為A類中的該方法,所以輸出為A and D;
⑦⑧⑨:b為B類物件,可呼叫A類中show(D obj)、B類中show(B obj)、B類中show(A obj)方法,所以輸出如上。
寫在最後:歡迎留言討論,加關注,持續更新!