java中的子类和关键字

时间:2014-09-15 04:27:46

标签: java types static this subclass

在以下代码中,我不明白为什么在调用a1.k()时,this.xC会返回100而不是1.我的理解是this是指当前对象,但当前变量a1的静态类型是A。那么this.x不应该返回1,这是A类型的变量吗? 我的意思是a1.x应该返回1,对吗?非常感谢!

class A {
   public int x = 1;   
   public String k() { return "A" + this.x; }
}
class B extends A {
   public int x = 10;
   ...
}
class C extends B {
   public int x = 100;
   public String k() { return "C" + this.x; }
}
class TestABC {
   public static void main(String[] args) {
       A a1 = new C();
       C c1 = new C();
       System.out.println(a1.k());
   }
}

3 个答案:

答案 0 :(得分:1)

此功能称为动态多态。被调用的方法不依赖于其声明的类型,而是依赖于它的类型(定义)。

为此,类必须继承并覆盖父类中的方法。

这里C,B扩展A并覆盖方法k;

如果您尝试调用某些特定于C的方法或变量,则会抛出错误。 (因为A不知道)

A持有对C的引用(指向C)

a1.k实际上是C构造的Object及其新的C()。k(),其中x在C中是100。

class Base{
    int x=10;
    public int getx(){return x;}
}

class Sub extends Base{
    int x=100;
    public int getx(){return x;}
}

class Test
{   
    public static void main (String[] args) 
    {
        Base b = new Base();
        Sub s = new Sub();
        System.out.println("sub: getx:"+s.getx()+" .x:"+s.x+" Class: "+s.getClass().getName());
        System.out.println("base: getx:"+b.getx()+" .x:"+b.x+" Class: "+b.getClass().getName());
        Base btoS = new Sub();
        System.out.println("btos: getx"+btoS.getx()+" .x:"+btoS.x+" Class: "+btoS.getClass().getName());
    }
}

结果

sub: getx:100 .x:100 Class: Sub
base: getx:10 .x:10 Class: Base
btos: getx100 .x:10 Class: Sub

答案 1 :(得分:1)

当您致电a1.k()时,您会动态调度k方法,该方法由引用位于a1的实际对象定义。在这种情况下,它是C而不是AB,因此k方法是C中定义的覆盖。

静态类型(例如a1)用于静态分辨率;例如解析static方法,重载签名和字段。但是例如方法调用,要调用的方法的最终选择是动态的。

  

我知道应该调用C类中的k(),而不是类A中的k()。但为什么this.x返回100?我认为实例变量与静态类型有关。

好吧。但是,x调用中this.x k()使用this的静态类型是C.k中{{1}} 的静态类型方法正文

答案 2 :(得分:0)

由于您将a1声明为new C()a1将被视为类C的对象实例,它会覆盖其父类{{1}的字段}和B。那么为什么你会做像A这样的事情(或者你可能会看到很多这样的实现),有一个建议说"编程接口而不是实际的实现。",我认为this更好地解释了。