请教各位,这段代码执行的内部机理是什么,包括注掉的部分,谢谢!public class TestBasic {
public static void main(String []args) {
Basic b1 = new Basic();
SubBasic s1 = new SubBasic();
System.out.println(b1.i);
System.out.println(s1.i);
b1.print();
s1.print();

System.out.println("----------------");
Basic b2 = (Basic) s1;
b2.print();
System.out.println(b2.i);

/*
System.out.println("----------------");
SubBasic s2 = (SubBasic) b1;
s2.print();
System.out.println(s2.i);
*/

System.out.println("----------------");
SubBasic s3 = (SubBasic)((Basic)s1);
s3.print();
System.out.println(s3.i);

/*
System.out.println("-----------------");
Basic b3 = (Basic)((SubBasic)b1);
b3.print();
System.out.println(b3.i);
*/
}
}class Basic {
int i = 0;

public void print() {
System.out.println("Basic's print");
}
}class SubBasic extends Basic {
int i = 1;

public void print() {
System.out.println("SubBasic's print");
}
}

解决方案 »

  1.   

    子類SubBasic中的方法覆蓋了Basic中的同名方法
      

  2.   

    另外那位老兄能把
    String s1 = "Hello";
    String s2 = new String();
    String s3 = new String("Hello");
    的内存给分析一下,就是在内存中的具体位置,小弟不胜感激
      

  3.   

        说简单点,实际上是JAVA的动态绑定机制!
        假设有如下类:
        public class Father {
    public int age=38;
    public void show(){
    System.out.println("I'm father,my age is "+age);
    }
        }
        public class Son extends Father{
    public int age=23;
    public void show(){
    System.out.println("I'm son,my age is "+age);
    }
        }
        public class Test {
    public static void main(String args[]){
    Father f=new Son();
    System.out.println(f.age);
    f.show();
    }
        }
        打印结果为:38
                  I'm son,my age is 23
        1.Father f=new Son();引用为Father(父)类型,对象为Son(子)类型.
        2.System.out.println(f.age);f直接调用当前引用类型自己的变量.
        3.f.show();f从它的Class对象中寻找show()方法,如果子类也有该方法,那么会调用子类的方法,否则,调用父类自己的.
      

  4.   

    对于非静态变量实行动态邦定,对于静态变量实行静态邦定,即如果是调用非静态变量或者方法,那么所调用的是new 出来的对象的类型的变量或者方法
    如果是调用的静态变量或者方法,那么调用的是定义对象的类型的变量或者方法。
      

  5.   

    非常感谢,我就是想问这一点,只是,为什么运行f.age时不执行子类的age呢
    而运行f.show()时就是子类的show()呢
      

  6.   

       可以用反射的思想来理解:
       Father f=new Son()后堆区中的Son对象和Father.class对象暂时绑定在一起,
       age做为成员变量,在堆区中,是和对象引用类型绑定在一起,
       所以f.age会调用Father类的age,
       f.show()会从Father.class对象中反射方法,这时发现堆区实际的对象是Father的子类,
       那么又会到Son.class对象中反射重写的方法,如果有的话,就调用子类的,否则就调用父类的! 
       
      

  7.   

    public class TestBasic { 
    public static void main(String []args) { 
    Basic b1 = new Basic();               -----------创建父类对象b1
    SubBasic s1 = new SubBasic();         -----------创建子类对象s1
    System.out.println(b1.i);             -----------调用父类属性-----打印0
    System.out.println(s1.i);             -----------调用子类属性-----打印1
    b1.print();                           -----------调用父类方法-----打印Basic's print
    s1.print();                           -----------调用子类方法-----打印SubBasic's printSystem.out.println("----------------"); 
    Basic b2 = (Basic) s1;                -----------声明父类引用直线刚才创建的子类 
    b2.print();        ------因为b2指向的是子类则调用子类的print打印SubBasic's print           
    System.out.println(b2.i);          -----属性和的覆盖和方法的重写不同,这里调父类的0/* 
    System.out.println("----------------"); 
    SubBasic s2 = (SubBasic) b1; 
    s2.print(); 
    System.out.println(s2.i); 
    */ System.out.println("----------------"); 
    SubBasic s3 = (SubBasic)((Basic)s1); ------声明子类引用,指向被转型为父类的引用,因为是大范围像小范围转需要用(SubBasic)强制转换,先在s3和s1的效果一样
    s3.print();          -------   打印 SubBasic's print
    System.out.println(s3.i); -------打印 1/* 
    System.out.println("-----------------"); 
    Basic b3 = (Basic)((SubBasic)b1); 
    b3.print(); 
    System.out.println(b3.i); 
    */ 

    } class Basic { 
    int i = 0; public void print() { 
    System.out.println("Basic's print"); 

    } class SubBasic extends Basic { 
    int i = 1; public void print() { 
    System.out.println("SubBasic's print"); 

    }
      

  8.   

    Basic b2 = (Basic) s1; //强制类型转换 把原来为SubBasic类型的引用s1 转换成Basic 类型的!Super s = new Sub(); //多态
    方法的重写和属性的遮盖 
    方法重写后如果调用方法就看其实际指向的对象的类型 s.print()调用重写后的方法 因为s实际指向的是子类对象
    属性遮盖后调用属性就看引用的类型 s.i 调用父类Super中的属性,因为s就是Super类型的!
      

  9.   

    再请教一下,
    Father f = new Son();
    中的f实际上是一个Father还是一个Son
      

  10.   

    f只是引用而已,引用类型为Father,在栈区,它指向堆区中的new Son()对象!
      

  11.   

    SubBasic类中的Print()将会覆盖父类Basic类中的print()方法!
     这主要体现JAVA多态的一个特征:Override覆盖。
     可以说这2个类就是体现多态一个特征。
    TestBasic是一个测试类,用来测试这两个类。
    那现在问句什么叫多态,举个例子,开窗户,开门,“开”就是多态!
    .........