super的正確用法

super的含義

super並沒有代表超類的一個引用的能力(但是,this可以作爲隱含的引用,所以可以System.out.println(this);),只是代表調用父類的方法或屬性而已。

反例:如果super是超類的引用,那麼就可以System.out.println(super);, 事實上不可以,所以super不是超類的引用

看下面的程序


//Test1.java

class A{

      

       public void print(){        

              System.out.println(super.getClass());//System.out.println(super.getClass().getName());//輸出類的名字,用這個換一下呢,看看結果

              System.out.println(this.getClass());         

              System.out.println(super.hashCode());

              System.out.println(this.hashCode());   

       } 

}

  

class B extends A{

       public void print(){    

              System.out.println(super.getClass());//調用A類中的getclass()方法,A是Object的子類,A中的getClass()是Object中的,運行時期的實例是B類,所以輸出的依然是Class B

              System.out.println(this.getClass()); //調用B類中的getclass()方法,此方法從A繼承的,A從Object繼承的,運行時期的實例是B類,所以輸出的是Class B

              /*上面的super.getClass()和this.getClass()都是調用的Object中的getClass(),

              而super.getClass()和this.getClass()都是通過實例化B類,調用print(),從而調

              用這兩個方法,運行時期的類都是B,Object中的getClass()返回的是運行時期的類

              名,所以輸出都是Class B

              */

              /*事實上如果是通過一個ClassLoader裝載的話,調用super.getClass()是沒有什麼

              意義的,不如直接調用 this.getClass() 【這個從網上搜的,自己沒有看過,不過

              覺得有用】,有興趣的可以繼續查閱

              */

              System.out.println(super.hashCode());

              System.out.println(this.hashCode());             

              /*Object中的hashCode()返回的是實例對象的哈希碼值,此處實例對象是B類的,所

              以輸出的都是B類實例的哈希碼

              */             

       } 

}

  

public class Test1{ 

       public static void main(String[] args){             

              A a=new A();

              B b=new B();             

              a.print();

              b.print();             

       }

} 

/*

運行結果:

class A

class A

14576877

14576877

class B

class B

12677476

12677476 

super一直就表示代表調用父類的方法或是屬性,getClass()從Object繼承的。如果 B繼承A, A繼承Object,如果b.getClass() 是B , 那麼,無論B是調用Object中的getClass()  ,還是調用   B中的getClass()   結果都是一樣的,就是B 。因爲getClass()的意思就是運行期的類,就是說b一開始是什麼就是什麼。不受造型的影響。

*/

 

//Test2.java

class A{

}

 

class B extends A{

       public void print(){            

              System.out.println(super.toString());

              System.out.println(this.toString());

              /*B繼承A,A繼承Object,所以super.toString()和this.toString()調用的都是Object中的toString(),

              返回的是實例對象的字符串形式,實例對象是B類的,所以返回的都是B的

              */

       }             

}

 

public class Test2{ 

       public static void main(String[] args){             

              B b=new B();

              b.print();             

       } 

} 

/*

運行結果:

B@de6ced

B@de6ced

*/

 

//Test3.java

class A{      

       public String toString(){

              return "A";     

       }      

}

 

class B extends A{ 

       public void print(){             

              System.out.println(super.toString());//調用父類A中的toString(),輸出A

              System.out.println(this.toString()); //調用子類B中的toString(),輸出B

              /*

              因爲A類重寫了Object中的toString()

              B類重寫了A類中toString(),所以和Test2.java的結果是不一樣的

              */                    

       }      

       public String toString(){

              return "B";     

       }             

}

 

public class Test3{ 

       public static void main(String[] args){             

              B b=new B();

              b.print();                    

       } 

} 

/*

運行結果:

A

B

*/

 

//Test.java 

class A{      

       int data=1;

       public String getName(){

              return "A";     

       }      

       public int getData(){

              return data;    

       }      

       public void printData(){

              System.out.println(getData());     

       }      

       public void printName(){

              System.out.println(getName());

       }

}

 

class B extends A{      

       int data=2;      

       public String getName(){

              return "B";     

       }      

       public int getData(){

              return data;    

       }      

       public void printData(){             

              //super.printData(); //在本例中和下面的等價,不信自己試試呢

              System.out.println(getData());                  

       }

      

       public void printName(){             

              System.out.println(getName());//在本例中和下面的等價,不信自己試試呢

              //super.printName();             

       }      

       public void testSuper(){             

              System.out.println(super.data);//調用父類A中的data爲1

              System.out.println(this.data); //調用子類B中的data爲2

             

              System.out.println(super.getName());//調用父類A中的getName()方法,返回"A"

              System.out.println(this.getName());      //調用子類B中的getName()方法,返回"B"

             

              System.out.println(super.getData());//調用父類A中的getData()方法,父類A中的getData()方法返回的是父類A的data爲1

              System.out.println(this.getData()); //調用子類B中的getData()方法,子類B中的getData()方法返回的是子類B的data爲2

             

             

              super.printName();//打印B,因爲:調用父類A中的printName()方法,此方法又調用了getName(),是子類B的getName(),爲啥是B的?因爲實例是B類的,由多態性知調用的是B的

              this.printName(); //打印B,因爲:調用子類B中的printName()方法,此方法又調用了B中的getName()

             

              super.printData();//打印2,因爲:調用父類A中的printData()方法,此方法又調用了getData(),是子類B的getData(),爲啥是B的?因爲實例B的實例,由多態性知調用的是B的

              this.printData();//打印2,因爲:調用子類B中的printData()方法,此方法又調用了B中的getData()

             

       }

      

      

}

 

public class Test{

       public static void main(String[] args){             

              A a=new A();

              B b=new B();

              A ab=new B();             

              System.out.println("屬性:");      

              System.out.println(a.data);

              System.out.println(b.data);

              System.out.println(ab.data);//屬性不具有多態性,所以輸出的是A類中的data 

              System.out.println("測試super:");

              b.testSuper();             

       }          

} 

/*

運行結果: 

屬性:

1

2

1

測試super:

1

2

A

B

1

2

B

B

2

2

 

小結:

在子類B中用super.method()調用父類的方法method(),運行時的實例依然是子類B

1、若父類A的method()中調用了f()這個方法【子類B重寫了這個方法】,那麼這個方法事實上是調用的子類B中的方法,因爲運行時的實例是子類B,方法具

有多態性,所以是調用子類B中的f()

2、若父類A的method()中調用了data這個屬性【子類中重寫了這個屬性】,那麼這個方法事實上調用的依然是父類A中的屬性,儘管運行時的實例是子類B,

但是屬性不具有多態性,所以調用的是父類A中的屬性data

*/

<>打印地址與否

打印地址或不打印地址,object是系統類,一般都不打印地址,如果是自己定義的類,且又沒有重寫toString()方法,那麼打印是地址。如果不想打印出地址,那沒就重寫toString()方法 

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