从基类访问子类成员的首选方式

Posted

技术标签:

【中文标题】从基类访问子类成员的首选方式【英文标题】:preferred way of accessing child class members from base class 【发布时间】:2012-12-08 10:08:53 【问题描述】:

在基类中访问子类属性的最佳方式是什么。似乎如果我使用继承,我只需要依赖方法而不是属性[因为单独的类存在单独的属性集]。是否有任何推荐的安全方式从基类访问子类属性。或者这是重构代码的任何首选方式,以便我可以通过基类访问子类成员。我知道虚函数的使用,但我不知道如何使用它来设置子类成员变量的值。

class Abc

  public int Abc_1 get;set;
  private int _abc;

  virtual int DoCalculationonAbc(int a)
  
    return abc_1 * a;
  

  virtual void SetValueToPrivate(int a)
  
    _abc = a;
  


class Def:Abc

  private int _def;
  private int _def2;
  public int Def_2get;set; // what is the preferred way to set values this property

  override public void SetValueToPrivate(int a)
  
     _def = a;
     //_def2 = ??
  


Main()

  Abc ab = new Def();

【问题讨论】:

如果你能给出一个具体的例子,那真的很有帮助。 你必须依赖方法的原因是你的基类永远不知道子类有什么属性。而且您的基类不知道它是从哪里继承的。如果该属性已在基类中声明,您仍然无法访问子类副本,因为您不知道您的子类是否已覆盖它。 @JonSkeet 添加了代码。谢谢。 在你的例子中,这取决于你想用 _def2 做什么,因为这是在 Def 类中新声明的。您的属性访问器 Def_2 是将值设置为 _def2 的首选方式; @ryadavilli 但 Def_2 无法使用 Abc 实例访问。 【参考方案1】:

当你想做这样的事情时,你应该提前知道你想让你的超类使用哪些属性。您可以在基类中将它们声明为受保护,以便您的子类可以根据自己的规则设置它们。

如前所述,您不能从基类访问孩子新声明的属性(如 Def 类中的 _def2_def)。

如果您实例化一个子类型并将其分配给一个超类型,例如Abc ab = new Def(),您决定将ab 视为Abc,这意味着您放弃了Def 的特定成员并在您对ab 做事时发挥作用。 ab 确实是 Def,但您必须将其作为 Abc 进行操作。

同样,如果您在函数someFunction(Abc ab) 中传递Def,则该函数会更好地将ab 视为Abc。创建someFunction(Abc ab) 是为了处理Abc 的任何子类型,但只能通过Abc 中定义的公共属性和方法来处理。

【讨论】:

【参考方案2】:

不能从基类访问子类的成员,因为它不知道哪个类继承了它。访问子类成员的唯一方法是通过多态性和向下转换来实现。

    class Base
        public Base();
        int a;
    

    class Derived : Base
        public Derived();
        public int b;
    
    Base testBase = new Test;
    Base testDerived = new Derived;
    testBase.a = (Derived)testDerived.b; // Downcasting here.

【讨论】:

【参考方案3】:

你可以试试:

var testDerived = (Derived)new Derived(); //casting to derived class required to access its members.

testBase.a = testDerived.b;

【讨论】:

以上是关于从基类访问子类成员的首选方式的主要内容,如果未能解决你的问题,请参考以下文章

3.继承与派生

如何使用多态性从基类访问派生类向量成员?

继承和友元函数,从基类访问受保护的成员

从基类指针访问两个具有不同类型的派生成员变量。

c ++设计:从基类转换为派生类,没有额外的数据成员

5继承与派生2-访问控制