现在的位置: 首页 > 综合 > 正文

super的正确用法

2018年12月15日 ⁄ 综合 ⁄ 共 5613字 ⁄ 字号 评论关闭

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()方法 

抱歉!评论已关闭.