简体   繁体   English

超类的获取器和设置器?

[英]getters and setters for superclasses?

Is it still standard practice to provide getters and setters in the superclass, for subclasses to access the attributes of the superclass (in other words set the attributes as private)? 在超类中提供获取器和设置器,以使子类访问超类的属性(换句话说,将属性设置为私有)仍然是标准做法吗? Or should the attributes be accessed directly (declaring the attributes as protected) by the subclasses? 还是应该由子类直接访问属性(将属性声明为受保护的)?

Is there a standard convention? 有标准惯例吗?

It depends entirely on what you want to accomplish. 这完全取决于您要完成什么。

If you want the superclass attributes to be accessible without being inherited, then you need to declare public getters and setters. 如果希望超类属性可以访问而不被继承,则需要声明公共getter和setter。

If, on the other hand, you want the members to be accessible only if the superclass is inherited, then you need to declare protected members. 另一方面,如果您希望仅在继承超类时才可访问成员,则需要声明受保护的成员。

If you want some form of validation, you need getters and setters. 如果您需要某种形式的验证,则需要使用getter和setter。 This protects the superclass from inadvertent corruption, even if it is inherited. 这样可以保护超类免受意外损坏,即使它是继承的也是如此。

When I was in university doing my CS degree we were told don't do getters and setters in second year and do them in fifth year. 当我在大学攻读计算机科学学位时,我们被告知不要在第二年做吸气器和安装器,而在第五年做。

My personal preference, is to use getters and setters where absolutely required only and to never ever have public variables. 我个人的喜好是仅在绝对需要的地方使用getter和setter,并且永远不要使用公共变量。

Check the top two answers to this question: 检查此问题的前两个答案:

Are getters and setters poor design? 吸气器和吸气器设计不佳吗? Contradictory advice seen 看到矛盾的建议

Not a great answer to your question but you are obviously concerned with coding good OO so you should give them some thought. 对您的问题来说,这不是一个很好的答案,但是您显然对编写好的OO感到担心,因此您应该考虑一下。

In Java I prefer to make all my fields private. 在Java中,我倾向于将所有字段设为私有。 If I really need to expose something, I create a separate, protected getter for the field. 如果确实需要公开某些内容,则可以为该字段创建一个单独的受保护的吸气剂。 (For example if the interface I'm implementing requires a broader return type than what I want to pass between the different levels of implementations.) (例如,如果我要实现的接口要求的返回类型比我想要在不同级别的实现之间传递的接口更大的返回类型。)

With tools that can generate getters/setters at a click of the mouse, I never felt the need to break encapsulation even between parent/child classes. 借助可通过单击鼠标生成吸气剂/塞特剂的工具,我什至从未感到需要打破封装,即使在父/子类之间也是如此。

Speaking for the C# side, if you have a data member (field or property) that is not public, but is useful to child classes and should be available both to read and write, then declare that member as protected. 说到C#端,如果您有一个非公共的数据成员(字段或属性),但对子类有用,并且应该可供读取和写入,则将该成员声明为受保护的。

If the member should be read by subclasses but not written, you can define the member as a property that is protected but with a private setter: 如果成员应该由子类读取而不是写入,则可以将成员定义为受保护但具有私有设置程序的属性:

//as of C# 3.0 this can also be an auto-property
private string myValue;
protected string MyValue 
{
   get{return myValue;} 
   private set{myValue = value;}
}

This makes MyValue completely hidden from classes outside the inheritance hierarchy, and read-only to subclasses; 这使得MyValue对继承层次结构之外的类完全隐藏,对子类只读; only the superclass itself can set the value. 只有超类本身可以设置值。 This would be equivalent to a private field with a protected getter method and a private setter method. 这等效于带有受保护的getter方法和private setter方法的私有字段。

In general, as the designer of the superclass, it's up to you to define how subclasses should be able to use what you provide. 通常,作为超类的设计者,您需要定义子类应如何使用所提供的内容。 If you make something protected, assume subclasses will do anything that "protected" allows them to do. 如果您将某些内容设为受保护的,则假定子类将执行“受保护”允许它们执行的所有操作。 Both C# and Java have methods by which you can independently control the visibility of read and write access. C#和Java都具有您可以独立控制读写访问可见性的方法。

Seems that in C#, the standard practice is to use properties with get/set accessors. 似乎在C#中,标准做法是将属性与get / set访问器一起使用。 In the simplified form you'll have: 以简化形式,您将拥有:

public string Name { get; set; }

But you may have finer control over the access level, for example: 但是您可以更好地控制访问级别,例如:

public string Name { get; protected set; }

Here you publicly expose the get method, but leave the set method to derived classes only. 在这里,您公开公开了get方法,但是将set方法仅留给派生类。

One other benefit of using accessors instead of directly accessing a data member is that you could put a break point on a get/set method and see who executed the method. 使用访问器而不是直接访问数据成员的另一个好处是,您可以在get / set方法上设置一个断点,并查看谁执行了该方法。
This, however, is not possible with the { get; set; } 但是,使用{ get; set; } { get; set; } { get; set; } trick. { get; set; }欺骗。 You'll have to write the whole expanded property form: 您必须编写整个扩展属性表格:

private string m_Name = string.Empty;
public string Name
{
    get { return m_Name; }  // Put a happy breakpoint here
    set { m_Name = value; } // or here.
}

It will be safe to reflect the same concept for Java. 可以肯定地反映出Java的相同概念。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM