Java 继承和隐藏的公共字段

Java inheritance and hidden public fields

提问人:рüффп 提问时间:5/5/2015 最后编辑:рüффп 更新时间:11/17/2015 访问量:969

问:

为了模拟一些自动生成的类,我做了一个小的jUnit测试类来模拟继承和隐藏字段。

public class ClassDerivationTest {

    @Test
    public void testChild() {

        ChildClass child = new ChildClass();

        // Implicit boolean as it is hiding the super value
        child.value = true;

        // one way to update the parent value
        // child.setParentVal("true");

        // child.super.value = "test";
    }

    public class ChildClass extends ParentClass {
        public boolean value;
    }

    public class ParentClass {
        public String name;
        public String value;
    }
}

我的问题是:有没有捷径可以像这样以类似的方式分配超类字段:value

child.super.value = "test";

而不是在 ChildClass 中创建特定的 setter:

    // Imagine this method is not existing for the question
    public void setParentVal(String val) {
        super.value = val;
    }

我正在使用 Java 7,我想知道是否可以在不修改 nor 的情况下(就像它可以是自动生成的代码一样)。ChildClassParentClass

更新: 我知道你有几种方法可以解决这个问题 a) 根据乔恩的回答进行选角:但不是很好 b) 像这样实例化超类(尽可能多):代码将引用 ParentClass 中的字段((ParentClass) child).value = "test";ParentClass myInstance = new ChildClass();myInstance.value

但我想更专注于 Java 8 的新功能。 例如,是否可以使用 lambda 或 Java 8 的另一个新功能来解决这个问题?

Java OOP 继承 快捷方式

评论

0赞 Thomas 5/5/2015
它们是否必须被命名为同一事物?我认为对于想要设置父成员的子类来说,正确的解决方案是首先不要覆盖它们。
8赞 JB Nizet 5/5/2015
您不会覆盖父字段。你把它藏起来了。多态性仅适用于方法。没有字段。使用公共字段是极其糟糕的做法。只是不要这样做。
1赞 GhostCat 5/5/2015
@JBNizet 这是不好的做法,除非你称它为“数据传输对象”,并从中创建一个模式。你看,如果你使用一个豆子,并为那些人提供愚蠢的 getters 和 setters......与现场访问的本质区别是什么?只是在以后的某个时间点改变二传手的理论可能性。
2赞 JB Nizet 5/5/2015
有很多区别:与其他类的一致性,仍然能够向 DTO 添加方法(想想 getFullName() 返回名字和姓氏的串联),使 DTO 不可变的能力,实现接口的能力,能够将 DTO 与依赖于 JavaBean 约定(JSP 等)的框架一起使用,能够重命名字段,但仍保留旧的 getter 以便于迁移, 能够向 getter 和 setter 添加断点或日志记录跟踪,以了解何时访问属性等。
0赞 рüффп 5/5/2015
我把样本做得很短,但实际上我对类没有太多的控制权。考虑一下 Jaxb 自动生成的类用作访问器类型。我知道这根本不是最佳实践,但我只是想知道除了修改类之外还存在一些快捷方式。XmlAccessType.FIELD

答:

8赞 Jon Skeet 5/5/2015 #1

好吧,您可以直接转换以使编译器解析字段,而不是:childvalueParentClassChildClass

((ParentClass) child).value = "test";

但坦率地说,我会 a) 避免非私人领域;b) 避免故意为超类和子类字段提供相同的名称。

与您的评论相反,子类字段不会“覆盖”超类字段 - 它会隐藏它。

评论

0赞 Jon Skeet 5/5/2015
@JoopEggen:涉及继承(),但我同意子类字段隐藏了父类字段 - 我只是为此写了一个编辑。ChildClass extends ParentClass
0赞 Chetan Kinger 5/5/2015
为什么要避免?我能理解,但只是好奇被避免。protectedpublicprotected
0赞 Jon Skeet 5/5/2015
@ChetanKinger:IMO,字段是一个实现细节,应仅限于类本身。如果我想稍后更改该实现(重命名字段,更改其类型),我应该能够在不破坏子类的情况下做到这一点。
0赞 Chetan Kinger 5/5/2015
因此,如果我理解正确,字段应始终标记为私有并可通过 or 方法访问?publicprotected
1赞 Jon Skeet 5/5/2015
@ChetanKinger:嗯,这就是我个人的工作方式,是的。