java 覆盖属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6692366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:55:46  来源:igfitidea点击:

Override attributes

javainheritanceattributesoverriding

提问by anonymous

When you override a method you must keep the method's signature and can't reduce its visibility. Now I tried what happends when I do this with attributes. I was surprised - IT WORKS! Look yourself:

当您覆盖一个方法时,您必须保留该方法的签名并且不能降低其可见性。现在我尝试使用属性执行此操作时会发生什么。我很惊讶 - 它有效!看看你自己:

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);
    }

}

So it is possible to write an attribute in a subclass with the same attibute name as in the superclass, but you can use different visibility (modifier) and type. So I would say that the attributes in superclass and subclass are almost completely independend from each other.

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

Now if you really use the same attribute name in superclass and subclass you effectively hide the superclass's attribute. When accessing the attribute using the subclass, you get the subclass's attribute. But the superclass's attribute is there, too! You have to perform a cast to access the superclass's attribute from outside. From inside the "super" keyword should be usefull.

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

Question 1: Now basically you have two different attributes with the same name. Doesn't this break LSP?

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

Why I came to this detail is this: I am experimenting with an self written persistence framework. I want to read the complete internal state of an object and persist that state. I read all attribute's values via reflexion, starting at the subtype and traversing over the superclasses. Now if there are two attributes with the same name in superclass and subclass I have to remember the class which declares an attribute to be able to map the attributes values to the right attributes and restore an object's state.

我之所以要讨论这个细节是因为:我正在试验一个自写的持久性框架。我想读取对象的完整内部状态并保持该状态。我通过反射读取所有属性的值,从子类型开始并遍历超类。现在,如果超类和子类中有两个同名的属性,我必须记住声明属性的类,以便能够将属性值映射到正确的属性并恢复对象的状态。

Question 2: Any other ideas how to deal with this detail? Question 3: How do other persistence frameworks handle this detail?

问题 2:还有其他想法如何处理这个细节吗?问题 3:其他持久化框架如何处理这个细节?

I never saw this detail in use. Maybe writing two attributes with the same name is a bit ugly, but it is possible and any persistence framework may be confronted with it. Maybe there are situations where this technique might be usefull.

我从未在使用中看到过这个细节。也许写两个同名的属性有点难看,但这是可能的,任何持久化框架都可能面临它。也许在某些情况下这种技术可能有用。

Thans in advance.

比提前。

采纳答案by Bozho

ORMs usually use the javabeans standard which defines "properties". Properties are defined by a reader and/or writer method rather than the field they read/write. In 99% of the cases properties are field+getter&setter, but it need not be the case. And the ORM reads these properties, and detects only the fields that have getters&setters. Since methods are overridden rather than shadowed, the problem is gone.

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

This is more a problem of encapsulation than a violation of LSP. Field access is not affected by polymorphism, so if you have Foo foo = new FooSubclas();foo.fieldthe value of theFoo` field will be taken, which means the behaviour won't change.

这与其说是违反 LSP,不如说是封装问题。字段访问不受多态影响,所以如果你有Foo foo = new FooSubclas();foo.field the value of theFoo` 字段将被占用,这意味着行为不会改变。

回答by Oliver Charlesworth

Question 1: It doesn't break LSP, because member variables are not polymorphic.

问题 1:它不会破坏 LSP,因为成员变量不是多态的。

回答by Dorus

You can not override a attribute, only hide it. This is literally called hiding fields in the tutorial. More details on this blog.

您不能覆盖属性,只能隐藏它。这在教程中字面称为隐藏字段。有关此博客的更多详细信息。

Q1: No, it doesn't break LSP, any reference to A a = new B(); a.myAttributewill still refer to A.myAttributeand not to B.myAttribute.

Q1:不,它不会破坏 LSP,任何对 的引用A a = new B(); a.myAttribute仍将引用A.myAttribute而不是B.myAttribute

Q2: I would try to avoid it, but if you must, you can still access A.myAttributefrom Busing the super.myAttributekeyword.

Q2:我会尽量避免它,但如果你一定要,你仍然可以访问A.myAttribute,从B使用super.myAttribute关键字。

Q3: I think C# allows the same, they use baseinstead of super, but it i got no C# compiler at hand, and the documentation on field hiding in C# is sparse.

Q3:我认为 C# 允许相同,他们使用base而不是super,但我手头没有 C# 编译器,并且关于 C# 中字段隐藏的文档很少。

回答by Thomas

Question 1: LSP is about behavioral subtypingand I'd say having two members with the same name doesn't change behavior itself.

问题 1:LSP 是关于behavioral subtyping,我想说有两个同名的成员不会改变行为本身。

Question 2: Detect it (you'd need to scan the class hierarchy anyways) and don't allow it.

问题 2:检测它(无论如何您都需要扫描类层次结构)并且不允许它。

回答by bezmax

Question 2: Only serialize/deserialize through getters/setters.

问题 2:仅通过 getter/setter 进行序列化/反序列化。

Question 3: See answer 2.

问题 3:见答案 2。