覆盖属性

ano*_*ous 13 java inheritance attributes overriding

覆盖方法时,必须保留方法的签名,并且不能降低其可见性.现在我尝试使用属性执行此操作时发生的事情.我很惊讶 - 它的工作原理!看看自己:

public class A {

    public Integer myAttribute;

}

public class B extends A {

    public String myAttribute;

}

public class Main {

        public static void main(String[] args) {
        B b = new B();
        b.myAttribute = "myString";
        ((A) b).myAttribute = 1337;
        System.out.println(b.myAttribute);
        System.out.println(((A)b).myAttribute);
    }

}
Run Code Online (Sandbox Code Playgroud)

因此,可以在子类中编写具有与超类中相同的属性名称的属性,但您可以使用不同的可见性(修饰符)和类型.所以我要说超类和子类中的属性几乎完全相互独立.

现在,如果您真的在超类和子类中使用相同的属性名称,则可以有效地隐藏超类的属性.使用子类访问属性时,您将获得子类的属性.但超类的属性也在那里!您必须执行强制转换才能从外部访问超类的属性.从里面的"超级"关键字应该是有用的.

问题1:现在基本上你有两个具有相同名称的不同属性.这不会破坏LSP吗?

我为什么要详细说明这一点:我正在试验一个自编写的持久性框架.我想读取对象的完整内部状态并保持该状态.我通过reflexion读取所有属性的值,从子类型开始并遍历超类.现在,如果在超类和子类中有两个具有相同名称的属性,我必须记住声明属性的类,以便能够将属性值映射到正确的属性并恢复对象的状态.

问题2:任何其他想法如何处理这个细节?问题3:其他持久性框架如何处理这个细节?

我从来没有看到过这个细节.也许编写两个具有相同名称的属性有点难看,但它是可能的,并且任何持久性框架都可能面临它.也许有些情况下这种技术可能会有用.

提前到达.

Boz*_*zho 5

ORM通常使用定义"属性"的javabeans标准.属性由读取器和/或写入器方法定义,而不是它们读/写的字段.在99%的情况下,属性是字段+ getter和setter,但不一定是这种情况.ORM读取这些属性,并仅检测具有getter和setter的字段.由于方法被覆盖而不是被遮蔽,因此问题就消失了.

这比封装违反LSP更具问题.字段访问不受多态性的影响,因此如果你有Foo foo = new FooSubclas();foo.field the value of theFoo`字段将被采用,这意味着行为不会改变.