super不可以被print函数打印出来地址值,这代表着什么?
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()方法