1. 程式人生 > >這些繼承知識你都知道嗎?

這些繼承知識你都知道嗎?

本文最初發表在個人部落格http://nijiaben058.jspkj.com,歡迎大家光臨。
     在這裡我主要是想記錄點繼承的基礎知識,當是一次小小的總結吧,以便自己將來查閱,也便於初學者學習,此文主要是以知識小結為主,不會詳細闡述原理,當然我覺得有必要的還是會講點的,下面從幾個方面來說說哈。

  1.子類繼承父類哪些東西呢?

  • 子類和父類在同一個包中:子類繼承父類的public,protected,預設訪問級別的成員變數和成員方法;
  • 子類和父類不再同一包中:子類繼承父類的public,protected訪問級別的成員變數和成員方法;


 
  2.什麼叫方法的過載?
    如果兩個方法的方法名相同,但引數不一致,那麼就可認為一個是另一個的過載方法。

  3.過載方法要滿足哪些條件呢?

  • 方法名相同;(必需)
  • 方法的返回型別可以不同;
  • 方法的修飾符可以不同;
  • 方法引數型別,順序,個數至少有一個不同;(必需)



  4.什麼是方法覆蓋?
    子類定義一個方法,其名稱,返回型別及引數簽名正好與父類中某個方法,返回型別以及引數簽名相匹配,那麼就屬於覆蓋了。

  5.方法覆蓋要注意的事項?

  • Java編譯器當碰到子類的一個方法名和父類的一方法名相同時,會先判斷它們的引數簽名,如果兩者一致,那麼編譯器就認為子類想覆蓋父類的方法,接下來分析它們的返回型別,要是該型別也相同,那麼就說明是方法覆蓋了,否則的話就是方法過載啦;
  • 子類的方法不能縮小父類方法的訪問許可權,也就是說要是父類的一方法訪問許可權為protected,那麼子類要是想覆蓋父類的方法的話,其訪問許可權至少是protected,當然還可以是public,但是不能是private訪問許可權;
  • 子類方法不能丟擲比父類更多的異常,子類方法丟擲的異常必須和父類方法丟擲的異常相同,或者子類方法丟擲異常是父類方法丟擲的異常類的子類;
  • 方法覆蓋至存在於子類和父類之間,即不存在於同一個類中;
  • 父類的靜態方法不能被子類覆蓋為非靜態方法;
  • 子類可以定義與父類的靜態方法同名的靜態方法,以便在子類中隱藏父類的靜態方法;
  • 父類的非靜態方法不能被子類覆蓋為靜態方法;
  • 父類的私有方法不能被子類覆蓋;
  • 父類的抽象方法可以被子類通過兩種方法:一是子類實現父類的抽象方法,而是子類重新宣告父類的抽象方法;
  • 父類的非抽象方法可以被覆蓋為抽象方法;



  6.子類隱藏父類的靜態方法和子類覆蓋父類的例項方法有什麼區別呢?
    執行時,Java虛擬機器把靜態方法和所屬的類繫結,而把例項方法和所屬的物件繫結。下面舉個例子說明:

Java程式碼 複製程式碼
  1. publicclass Base{   
  2. void method(){   
  3.       System.out.println("Method of Base");   
  4.    }   
  5. publicstaticvoid staticMethod(){   
  6.       System.out.println("Static method of Base");   
  7.    }   
  8. }   
  9. publicclass Sub extends Base{   
  10. publicvoid method(){   
  11.       System.out.println("Method of Sub");   
  12.    }   
  13. publicstaticvoid staticMethod(){   
  14.       System.out.println("Static method of Sub");   
  15.    }   
  16. }   
  17. publicclass Test{   
  18. publicstaticvoid main(String args[]){   
  19.         Base sub1=new Sub();   
  20.         sub1.method();//列印method of sub
  21.         sub1.staticMethod();//列印Static method of Base;
  22.         Sub sub2=new Sub();   
  23.         sub2.method();//列印method of sub
  24.         sub2.staticMethod();//列印Static method of Sub;
  25.     }   
  26. }  
    public class Base{
       void method(){
          System.out.println("Method of Base");
       }
       public static void staticMethod(){
          System.out.println("Static method of Base");
       }
    }
    
    public class Sub extends Base{
       public void method(){
          System.out.println("Method of Sub");
       }
       public static void staticMethod(){
          System.out.println("Static method of Sub");
       }
    }
    
    public class Test{
        public static void main(String args[]){
            Base sub1=new Sub();
            sub1.method();//列印method of sub
            sub1.staticMethod();//列印Static method of Base;
            
            Sub sub2=new Sub();
            sub2.method();//列印method of sub
            sub2.staticMethod();//列印Static method of Sub;
        }
    }


  7.只能在構造方法或例項方法內使用super關鍵字,而不能在靜態方法和靜態程式碼塊中使用super關鍵字。

  8.多型中常遇到的問題?

  • 對於一個引用型別的變數,Java編譯器按照它宣告的型別來處理(編譯時),例如:Base s=new Sub();在Base和Sub類中都有var屬性,那麼當我們訪問s.var時它指的是Base類中的var變數值;
  • 對於向下轉型必須進行強制型別轉換;例如:Base s=new Sub();(Sub)s;
  • 對於一個引用型別的變數,執行時Java虛擬機器按照它實際引用的物件來處理;
  • 在執行時環境中,通過引用型別變數來訪問所引用物件的方法和屬性時,java虛擬機器採用以下繫結規則:     a.例項方法與引用變數實際引用的物件的方法繫結,這種繫結屬於動態繫結,因為是在執行時有java虛擬機器動態決定的;
        b.靜態方法與引用變數所宣告的型別的方法繫結,這種繫結屬於靜態繫結,因為實際是在編譯階段已經做了繫結;
        c.成員變數(包括靜態變數和例項變數)與引用變數所宣告的型別的成員變數繫結,這種繫結屬於靜態繫結,因為實際上是在編譯階段所做的繫結。



   9.當一個系統使用一棵繼承樹上的類時,應該儘可能地把引用變數宣告為繼承樹的上層型別,這樣可以提高兩個系統間的鬆耦合