一、
public class ExplorationJDKSource { /** * @param args */ public static void main(String[] args) { System.out.println(new A()); } } class A{}
实验截图:
结果输出了包名(为了测试包名随便设置的)+ . +A+@+随机的一个字符串
通过使用javap-c命令反汇编 .class文件
发现:
main方法实际上调用的是:
public void println(Object x),这一方法内部调用了String类的valueOf方法。
valueOf方法内部又调用Object.toString方法:
public String toString() {
return getClass().getName() +"@" +
Integer.toHexString(hashCode());
}
hashCode方法是本地方法,由JVM设计者实现:
public native int hashCode();
也就是说输出的是java中顶层基类Object的toString()方法。
public void println(Object x),这一方法内部调用了String类的valueOf方法。
valueOf方法内部又调用Object.toString方法:
public String toString() {
return getClass().getName() +"@" +
Integer.toHexString(hashCode());
}
hashCode方法是本地方法,由JVM设计者实现:
public native int hashCode();
也就是说输出的是java中顶层基类Object的toString()方法。
二、
public class Fruit { public String toString() { return "Fruit toString."; } public static void main(String args[]) { Fruit f=new Fruit(); System.out.println("f="+f); System.out.println("f="+f.toString()); } }
实验截图:
实验分析:
在“+”运算中,当任何一个对象与一个String对象,连接时,会隐式地调用其toString()方法,默认情况下,此方法返回“类名 @ + hashCode”。为了返回有意义的信息,子类可以重写toString()方法。
输出的第一行字符:是自动隐式调用了Fruit里重写的toString方法,
输出的第二行字符:是显示调用了Fruit里重写的toString方法,
三、
class Mammal{} class Dog extends Mammal {} class Cat extends Mammal{} public class Testcast { public static void main(String args[]) { Mammal m; Dog d=new Dog(); Cat c=new Cat(); m=d; //d=m; d=(Dog)m; //d=c; //c=(Cat)m; } }
实验结果分析:
1、子类转到父类是自动的,可行的;
2、父类向子类转型,是可能的,父类赋值给子类时要作强制类型转换,父类转型为子类类型时,编译时会通过,但是运行时可能会失败;
也就是说,要是想将一个父类转化成一个子类,只有当父类本身指向的就是一个子类对象(利用多态)。
3、兄弟”类之间的平级转型是不合理的,就是说继承同一父类的两个子类之间无法转换。
四、
public class Testcast { public static void main(String[] args) { Parent parent=new Parent(); parent.printValue(); Child child=new Child(); child.printValue(); parent=child; parent.printValue(); parent.myValue++; parent.printValue(); ((Child)parent).myValue++; parent.printValue(); } } class Parent{ public int myValue=100; public void printValue() { System.out.println("Parent.printValue(),myValue="+myValue); } } class Child extends Parent{ public int myValue=200; public void printValue() { System.out.println("Child.printValue(),myValue="+myValue); } }
实验截图:
分析:
这里面的 parent.myValue++;是对父类的myValue进行了加一;
而方法是调用了子类的方法;
(1)当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
(2)如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
如果子类被当作父类使用,则通过子类访问的字段是父类的!