13.繼承

1.繼承

關鍵字:extends

class Father{
    public int num1=10;
    private int num2=20;
    protected int num3=30;

    public Father(int num1,int num2,int num3){
        this.num1=num1;
        this.num2=num2;
        this.num3=num3;
    }

    public Father(){
        System.out.println("Father");
    }

    @Override
    public String toString() {
        return String.format("%d %d %d",num1,num2,num3);
    }
}

class Son extends Father{
    public Son(int num1,int num2,int num3){
        super(num1,num2,num3);
    }

    @Override
    public String toString() {
        return super.toString();
    }

  public static void main(String[] args){
    System.out.println(new Son(1,2,3));
  }
}//輸出 1 2 3

重點

a.創建子類對象的時候會調用父類的構造函數,如果是無參數的構造函數,會自動的調用,不用寫super()

b.Father father=new Son();//Son的實例但是進行了向上轉型,father引用可以調用Father類中的函數,以及子類中被重寫的函數(多態),但是父類的引用是不能調用子類的屬性的,因爲多態只針對方法不針對屬性

例子:

public class Main {
    public static void main(String[] args){
        /*創建子類對象的時候會調用子類的構造函數*/
        Son son=new Son();

        /*輸出num1的值*/
        Father father=new Son();
        System.out.println(father.num1);

        /*調用函數f()*/
        father.f();
    }
}

class Father{
    public int num1=10;
    public Father(){
        System.out.println("Constructor of Father");
    }

    public void f(){
        System.out.println("Father's f()");
    }
}

class  Son extends Father{
    public int num1=20;
    public Son(){
        System.out.println("Constructor of Son");
    }

    @Override
    public void f(){
        System.out.println("Son's f()");
    }
}//輸出:

Constructor of Father
Constructor of Son
Constructor of Father
Constructor of Son
10
Son's f()

 覆蓋與重載

  • 注意:重載與覆蓋的區別
  • 重載(函數名稱一樣、參數的類型或者個不一致、與返回值無關)  
  • 覆蓋(必須是有繼承關係的兩個類之間,函數的訪問權限,函數名稱,參數的類型個數都必須一致)
  • @Override之後必須是覆蓋而不能是重載--經常用在實現接口的函數的時候

 Public、private、protected關鍵字

class A{
      public String name=new String(“Tom”);
      protected String school=new String(“SouthEast University”);
      private String sex=new String(“M”);
}
  • public關鍵字不做過多的解釋,通過指向A對象的引用,可以訪問name屬性
  • private關鍵字,在A的類作用域之外,不能直接使用sex熟悉
  • protected關鍵字
      • 1.同包內protected與public相同
      • 2.不同包內,2.1不是A的子類與private相同,
          •  2.2是A的子類與public相同(只能在子類的作用域內),這就是爲什麼下邊的代碼爲什麼不能執行的原因
            public class Test{
                    public static void main(String[] args){
                          Object obj=new Object();
                          System.out.println(obj.hashCode()); 
                    } 
            }    
            //解釋
            按道理所有的類都是Object的子類,hahCode是protected函數,也就是說對於Object的子類,都可以執行hashCode()函數,但是必須在子類包中,這裏就是Object所在的包中
            這樣寫就是沒問題的
            @Override
            public int hashCode(){
              return super.hashCode();
            }
  • 省去包修飾符是包訪問權限

關鍵字:final

作用如下

  • 修飾屬性,表示編譯器常量
      • final int a=9;//被初始化之後就不能改變--一般常量
      • static final int A=9;//靜態常量--類的常量
    • 備註:Java中的final變量在定義的時候可以不進行初始化,但是初始化之後就不能修改常量的值
        • eg:
        • final int m;
        • m=30;
        • m=20;//Wrong  
  • 修飾對象和數組引用,表示引用不能改變“指向”
      • final int[] a=new int[]{1,2,3};
      • a[0]=1000;//可以改變數組的值
      • a=new int [20];//Wrong 不能改變a的引用
  • 修飾方法,表示函數不能被重寫(覆蓋)
  • private 其實就是隱式的final函數,但是本質還是不一樣的,只能說peivate 函數是有final關鍵字的
      • 1.final 函數,子類中不能添加同名同參數的函數
      • 2.private函數,子類中可以添加同名同參數的函數,但是這個不是重寫,只是添加了自己的同名函數,與父類無關--------強烈建議避免這樣寫
      •  class Instrument {
            private void display(){System.out.println("Instrument's display");}//無法被覆蓋
        }
        
        public class Wind extends Instrument{
            private void display(){System.out.println("Wind's display");}//並不是覆蓋父類的函數,而是添加自己的函數
            public static void main(String[] args){
                Instrument instrument=new Wind();//向上轉型爲父類的對象同時丟失父類的private方法
                instrument.display();//Wrong
            }
        }
  • 修飾類,表示類不能被繼承

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章