Java:未实现的抽象方法返回什么成员值?

时间:2014-07-04 06:02:22

标签: java inheritance abstract-class member extends

在Java中,如果我有一个像这样的类

abstract class TestClass
{
    int mMember = 0;

    int getMember()
    {
        return mMember;
    }
}

以及扩展此类的类:

class TestExtended extends TestClass
{
     int mMember = 1;
}

如果我创建一个TestExtended实例,并调用 testExtended.getMember(); 它会返回0还是1?

换句话说,当我扩展一个类,并且不覆盖所述类中的方法时,它是否调用该方法并对所述类或扩展类中的成员进行操作?

我是否需要在扩展类中重新实现(复制粘贴)函数以使函数返回1?

4 个答案:

答案 0 :(得分:2)

它将返回0,而不是1

这是因为您无法“覆盖”超类中的字段。您可以设置它们,只要它们不是private,但如果您声明一个具有相同名称的新变量,它将只是遮蔽超类变量。

另一方面,你可以覆盖方法。

现在,以这种方式遮蔽成员变量通常是一个非常糟糕的想法,并且是避免公共字段的另一个原因。这就是原因:

TestExtended sub = new TestExtended();
sub.mMember = 5;
System.out.println(sub.mMember); // prints '5', as expected

TestClass sup = sub; // this is fine, TestExtended extends TestClass
System.out.println(sup.mMember); // prints '0'!

编译器将根据编译时类型选择要使用的变量版本,从而打破多态性。不要隐藏成员变量,并避免公共字段,这将永远不会有问题。改为使用getter和setter。

答案 1 :(得分:1)

可以通过跑步来确认。它将返回0。这是因为无法覆盖这些字段。你实际做的是按照jls hiding实例变量。

  

覆盖方法不同于隐藏字段(§8.3),因为它是   允许字段隐藏其他类型的字段。

检查例8.4.8.3-4。在language specification获取更多信息

要获得子类版本,您必须:

 class TestExtended extends TestClass
     {
     int mMember = 1;

     @Override
     int getMember(){
          return mMember;
       }
    }

答案 2 :(得分:0)

基类方法无法访问子类字段(至少不使用反射)。完全停止。

此外,与方法不同,字段不参与覆盖。

答案 3 :(得分:0)

使用testExtended.getMember();显然意味着您正在调用抽象类方法,因为您不会覆盖子类中的方法。如果你要覆盖它,那么如果你的对象属于类的子类,那么首先会给出子类方法的首选项。所以在这种情况下,除非你覆盖方法,否则它会给你0。