当前位置:  开发笔记 > 编程语言 > 正文

Java不继承访问器方法?

如何解决《Java不继承访问器方法?》经验,为你挑选了3个好方法。

给定一个类"Bar",扩展类"Foo",实现接口"DeeDum"

public interface DeeDum {
    public String getDee();
    public String getDum();
}

public class Foo implements DeeDum {
    public String dee = "D";
    public String dum;

    public String getDee() { return dee; }
    public String getDum() { return dum; }
}

public class Bar extends Foo {
    public String dee = "DEE";
    public String dum = "DUM";
}

为什么这不起作用?

public static Bar mybar = new Bar();
Assert.assertEquals("DEE", mybar.getDee());
Assert.assertEquals("DUM", mybar.getDum());

我得到"D"而无效.换句话说,Bar不会从Foo继承访问器,也不能覆盖属性.以某种方式调用mybar.getDum()调用类Foo的静态实例并从父类返回静态属性.即使在子类中重写属性!这是否意味着您不能继承任何方法或属性?

我无法绕过它.为什么Java不能继承访问者(为什么他们选择这样一个奇怪的选择呢?)

或者我只是做错了什么?


实际上,我仍然看到一些奇怪而不确定的东西.如果你有另一个类'Bar'扩展Foo并在初始化块中设置继承的访问器

虽然您可以在上面的块中设置父属性,但它实际上并不为子类创建副本.

它似乎是多个类的非确定性初始化.

因此,如果你有扩展foo和初始化块的Bar和Baz,它们似乎都继承了Bar设置的值.

public class Bar extends Foo {
    {
        dee = "dee";
        dum = "dum";
    }
}
public class Baz extends Foo {
    {
        dee = "DEE";
        dum = "DUM";
    }
}

public static Bar bar = new Bar();
public static Baz baz = new Baz();

System.out.println("mybaz: " + mybaz.getDee() + mybaz.getDum());  // DEEDUM
System.out.println("mybar: " + mybar.getDee() + mybar.getDum());  // DEEDUM

但如果他们以不同的顺序实例化,我得到:

public static Baz baz = new Baz();
public static Bar bar = new Bar();

System.out.println("mybaz: " + mybaz.getDee() + mybaz.getDum());  // deedum
System.out.println("mybar: " + mybar.getDee() + mybar.getDum());  // deedum

如果在基类Foo中设置了默认值,它仍然会有所不同.

我想我现在明白Bar和Baz中的初始化块实际上是设置Foo :: dee和Foo :: dum,但为什么声明的区别呢?对我来说似乎是"未定义的".



1> Arne Burmeis..:

问题是,你的成员重复申报deedumFooBar隐藏的那些Foo.Bar自己的成员; 那些Foo永远不会被使用的Bar.你的意思是什么

public class Bar extends Foo {
  {
    dee = "DEE";
    dum = "DUM";
  }
}


对于我的下一个技巧,我将尝试通过在MS Word中写一篇关于"为什么Unicorns比Griffons更酷"的文章来学习西班牙语,让clippy纠正我的拼写和语法.

2> iny..:

您正在使用子类中定义的变量隐藏继承的变量.

public class Bar extends Foo {
    public Bar() {
        dee = "DEE";
        dum = "DUM";
    }
}

应该工作得更好.



3> Rob Kennedy..:

当你调用时mybar.getDee(),你正在调用Foo基类中定义的方法.(该方法继承的Bar.否则,你不会被允许首先在Bar实例变量上调用它.)该方法返回dee字段的值,但它是deeFoo类中定义的字段- 类所在的类方法本身已定义.编译器在Foo类中编译方法时解析了对字段的引用.

其他一些答案使用了覆盖这个词,通过声明一个名为deein 的字段来定义你所做的Bar事情,但事实并非如此.您不能覆盖字段,因为字段不是虚拟的.也许你认为他们是.如果存在"虚拟字段"之类的东西,我也可能期望getDee()返回字段的运行时类的版本(一个Bar),而不是编译方法时范围内的那个(Foo' S).但这并不是Java(或C#,或C++,或Delphi,或我所知的任何其他语言)的工作方式.您习惯使用哪种语言?

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有