天天看點

JAVA知識點總結(四)繼承,多态,重載與重寫

一、繼承、接口與多态的相關問題:

1、 繼承的作用?好處?壞處?

繼承:通過繼承實作代碼複用。Java中所有的類都是通過直接或間接地繼程java.lang.Object類得到的。繼承而得到的類稱為子類,被繼承的類稱為父類。子類不能繼承父類中通路權限為private的成員變量和方法。子類可以重寫父類的方法,及命名與父類同名的成員變量。但Java不支援多重繼承,即一個類從多個超類派生的能力。

優點:a因為大部分是繼承而來的,實作代碼重用,減少代碼書寫量;

b很容易修改和擴充已有的實作

缺點:a打破了封裝,因為基類向子類暴露了實作細節

b白盒重用,因為基類的内部細節通常對子類是可見的

c當父類的實作改變時可能要相應的對子類做出改變

d不能在運作時改變由父類繼承來的實作

2、 接口的好處?壞處?

優點:幫助Java語言實作一個類似于多繼承的功能.但是實作的多繼承功能不會使代碼中的類之間出現網狀關系,而是比較清楚的樹狀關系,類似于家譜的感覺。

缺點:如果向一個java接口加入一個新的方法時,所有實作這個接口的類都得編寫具體的實作。

3、 多态的作用?好處?壞處?

作用:簡單的說就是一個接口,多種實作;繼承的表現就是多态(沒有繼承就沒有多态。)

a應用程式不必為每一個派生類編寫功能調用,隻需要對抽象基類進行處理即可。大大提高程式的可複用性。

b派生類的功能可以被基類的方法或引用變量所調用,這叫向後相容,可以提高可擴充性和可維護性。

優點:a可替換性(可以替換一存在的代碼);

b可擴充性(增加新的子類不影響原有類的特性);

c接口性;

d靈活性;

e簡化性

缺點:a“遮蓋”私有方法。隻有非private的方法才能夠被籠罩,盡管編譯器不會報錯,然而也不會遵照我們所渴望的來實行。在導出類中,對于基類中的private方法,優秀采納不同的名字。

b域在轉型時候的問題。對于成員變量(域),導出類将占有從基類承襲而來的成員變量和自己的成員變量(變量名字相一同也是如此),況且,将分攤不同的存儲空間,這麼,導出類将具有兩個名目一樣的域。為了取得基類的域,務須實際地著名super.field能力走訪,而默許的域則是導出類自己的域。

c靜态計策是與類相關系的,而非與某個對象相幹聯的,那麼它就不擁有多态行動。

4、 什麼是重載?什麼是重寫?

重載:

a方法重載是讓類以統一的方式處理不同類型資料的一種手段。多個同名函數同時存在,具有不同的參數個數/類型。重載Overloading是一個類中多态性的一種表現。

b Java的方法重載,就是在類中可以建立多個方法,它們具有相同的名字,但具有不同的參數和不同的定義。調用方法時通過傳遞給它們的不同參數個數和參數類型來決定具體使用哪個方法, 這就是多态性。

c重載的時候,方法名要一樣,但是參數類型和個數不一樣,傳回值類型可以相同也可以不相同。無法以傳回型别作為重載函數的區分标準。

重寫:

a父類與子類之間的多态性,對父類的函數進行重新定義。如果在子類中定義某方法與其父類有相同的名稱和參數,我們說該方法被重寫 (Overriding)。在Java中,子類可繼承父類中的方法,而不需要重新編寫相同的方法。但有時子類并不想原封不動地繼承父類的方法,而是想作一定的修改,這就需要采用方法的重寫。方法重寫又稱方法覆寫。

b若子類中的方法與父類中的某一方法具有相同的方法名、傳回類型和參數表,則新方法将覆寫原有的方法。如需父類中原有的方法,可使用super關鍵字,該關鍵字引用了目前類的父類。

c子類函數的通路修飾權限不能少于父類的;

java的繼承與覆寫基本是java筆試中常出的題,也比較繞,我這裡對java的繼承覆寫做一個總結

1.構造函數:

        當子類繼承一個父類時,構造子類時需要調用父類的構造函數,存在三種情況

        (1),父類無構造函數或者一個無參數構造函數,子類若無構造函數或者有無參數構造函數,子類構造函數中不需要顯式調用父類的構造函數,系統會自動在調用子類構造函數前調用父類的構造函數

         (2),父類隻有有參數構造函數,子類在構造方法中必須要顯示調用父類的構造函數,否則編譯出錯

         (3),父類既有無參數構造函數,也有有參構造函數,子類可以不在構造方法中調用父類的構造函數,這時使用的是父類的無參數構造函數

           //以上三個結論已經過代碼驗證

2.方法覆寫:

          (1)子類覆寫父類的方法,必須有同樣的參數傳回類型,否則編譯不能通過

          (2)子類覆寫父類的方法,在jdk1.5後,參數傳回類可以是父類方法傳回類的子類

         (3)子類覆寫父類方法,可以修改方法作用域修飾符,但隻能把方法的作用域放大,而不能把public修改為private

          (4)子類方法能夠通路父類的protected作用域成員,不能夠通路預設的作用域成員

         (5)子類的靜态方法不能隐藏同名的父類執行個體方法

         (6)java與C++一樣,繼承的方法具有多态性

         //以上6個結論已經過代碼驗證

3.成員覆寫:

         (1)當子類覆寫父類的成員變量時,父類方法使用的是父類的成員變量,子類方法使用的是子類的成員變量

          這個聽起來很容易了解的一回事,但是實際使用過程中很多人容易搞混:尤其是在多态的時候,調用一個被繼承的方法,該方法通路是一個被覆寫的成員m,那麼方法中到底是通路了父類的成員還是子類的成員m?結論是,若實際調用的是父類的方法,就使用了父類的該成員m,若實際調用的是子類的方法,就使用子類的成員m,記住一句,每個類使用成員都相當于在前面加了 一個this指針。

         //以上1個結論已經過代碼驗證

        我在論壇上看到下面例子,了解上面,你就能夠很好得出答案了:

[c-sharp]  view plain copy

  1. class SuperClass {  
  2.     private int number;  
  3.     public SuperClass() {  
  4.         this.number = 0;  
  5.     }  
  6.     public SuperClass(int number) {  
  7.         this.number = number;  
  8.     }  
  9.     public int getNumber() {  
  10.         number++;  
  11.         return number;  
  12.     }  
  13. }  
  14. class SubClass1 extends SuperClass {  
  15.     public SubClass1(int number) {  
  16.         super(number);  
  17.     }  
  18. }  
  19. class SubClass2 extends SuperClass {  
  20.     private int number;  
  21.     public SubClass2(int number) {  
  22.         super(number);  
  23.     }  
  24. }  
  25. public class SubClass extends SuperClass {  
  26.     private int number;  
  27.     public SubClass(int number) {  
  28.         super(number);  
  29.     }  
  30.     public int getNumber() {  
  31.         number++;  
  32.         return number;  
  33.     }  
  34.     public static void main(String[] args) {  
  35.         SuperClass s = new SubClass(20);  
  36.         SuperClass s1 = new SubClass1(20);  
  37.         SuperClass s2 = new SubClass2(20);  
  38.         System.out.println(s.getNumber());  
  39.         System.out.println(s1.getNumber());  
  40.         System.out.println(s2.getNumber());  
  41.         //結論一:多态時,當子類覆寫了父類的方法,使用子類覆寫的方法  
  42.         //結論二:當子類覆寫父類的成員變量時,父類方法使用的是父類的成員變量,子類方法使用的是子類的成員變量  
  43.     }  
  44. }  

執行輸出:

1

21

21