打印结果如图,感觉有点矛盾,打印this的结果说明this引用的是sub对象,可是前面两个结果都是
Base,更无法理解的是,super.toString()打印的也是sub对象的引用,求大神指点 ,这是怎么回事 

解决方案 »

  1.   

    你调用的print方法是父类的方法,子类并没有重写,而在父类中,this的声明类型是Base,所以他使用的属性都是base中的属性。
      

  2.   

    可是,我打印this,结果显示this是sub类型的引用
      

  3.   


    实际类型是sub,声明类型是Base啊
      

  4.   

    你Base构造器中的this的实际类型(运行时类型)是Sub,但声明类型(编译时类型)是Base,这时候访问对象的属性,程序会选择访问声明类型(编译时类型)的属性。
      

  5.   


    您好,首先谢谢您的解答,不过我还是有点不太明白,您说的在父类中this的声明类型是Base,这个怎么理解?
    意思是当一个引用调用从父类继承而来的方法时,首先是将引用临时转为父类类型?是这个意思吗?还有下面是我自己的思考,还请您指正:
    1.this.showMe()打印结果是:Base,如果this的运行时类型是Sub的话,根据动态绑定机制,实例方法与引用变量实际引用的对象的方法绑定,那它打印结果应该是Sub吧?当然,我知道,如果将Base类的的showMe方法改为public,则打印的是Sub,意思是,动态绑定机制只适用于重写的情况?
    2.this.a  打印结果是Base,您说是因为this引用类型是Base,如果您能具体讲一下(即回答一下我上面的问题),我应该会明白,这是因为静态绑定。
    3.this 打印结果是jicheng.Sub@6521f956,因为toString方法调用getClass.getName()+@,打印的是对象所属类的名称,this引用Sub对象,这个我可以理解。
    4.super.toString 打印结果是jicheng.Sub@6521f956,super代表当前对象的父类对象的引用,那我调用super.toString方法,
    当前对象是Sub对象,则父类对象即super引用的是Base对象,执行后打印的应该是jicheg.Base@才对吧?
    写的有点多,耽误了您的时间,十分感谢!
      

  6.   

    1.私有方法不会被重写,也就是不能被覆盖。2.我说了,调用属性根据编译类型选择,编译类型是Base,那它调用的就是Base里声明的a4.为什么不会打印jicheg.Base?你要理解getClass方法是干嘛的,它的方法注释上开头就是这句话:Returns the runtime class of this {@code Object},返回运行时类型...而我说过,你的运行时类型是Sub
      

  7.   

     public class sub extends base{
        private String name="sub";
    public sub(String name) {
    super(name);
    this.name=name;
    }
    public String showMe(){
    return "sub";
    }
    public static void main(String[] args) {
    sub s=new sub("sub");
    s.print();
    }
    }
     class base {
    private String name="sub";
    public base(String name) {
    this.name=name;
    }

    public  String showMe(){
    return "base";
    }

        public void print(){
         System.out.println(showMe()+" "+this.name+" "+this.toString());
        }
    }
      

  8.   

    Base 基类不能被继承,所以第一个打印的就是Base,
    之后的是因为没有子类没有创建构造函数,所以a没有被初始化;
    导致了调用的就是引用了子类的a参数
      

  9.   

    1. this.showMe()之所以会打印"Base"是因为这个方法是私有的,不能被override,所以在Base中调用的showMe是属于Base自己的。你可以将private改成protected或public看看结果
    2. Java中是没有变量override的说法的,访问的变量优先访问类自身的变量,其次是父类中的变量。也可以说编译阶段就已经明确了。
    3. this就是指当前实际对象本身,无论他出现在哪里。打印this相当于执行this.toString()
    4. super.toString()等同于执行this.toString()你可以 加上以下代码进一步理解:
    Base base1 = new Base(); 
    base1.print(); 
    Base base2 = new Sub(); 
    base2.print(); 
      

  10.   

    this编译时和运行时不一样呗,这很正常呀,你如果不了解this,当然不知道正确结果喽,对这个例子,this编译时是父类,运行时却是子类。