【问题标题】:Can a child class fields be used in parent class?子类字段可以在父类中使用吗?
【发布时间】:2019-02-05 05:01:35
【问题描述】:

有没有办法在父类构造函数或方法中使用子类字段或属性?

public class Parent
{
    public Parent()
    {

    }
}
public class Child : Parent
{
    public int y;
    public Child()
    {

    }
}
class Program
{
    static void Main(string[] args)
    {
        Parent obj = new Child();
        obj.y = 10;
    }
}

在上面的代码中,我无法访问“y”字段

【问题讨论】:

  • 是的,你到底想要什么?请举个例子好吗?
  • 不能不使用子类实例,这是个坏主意,基类不应该知道它的派生类。
  • 我没有任何示例,因为这是在讨论 C# 和 OOPS 概念时向我提出的问题
  • “我尝试编写代码,但在基类中使用子类字段时显示错误” - 您应该在问题中包含该代码..
  • 澄清一下,当您谈论父/子类时,您指的是像public class Parent { } public class Child : Parent { } 这样的继承,对吗?或者你的意思是像public class Parent { public class Child { } }这样的嵌套类?

标签: c# .net oop


【解决方案1】:

当您通过父类访问您的实例obj 时,y 没有任何知识,您肯定无法访问该成员,因为它只是定义的在儿童班上。

换句话说:每个Child 都是Parent 并且有一个y 属性。但不是每个Parent 也是Child

因此,您的引用 obj 必须具有编译时类型 Child,而不是 Parent

Child obj = new Child();
obj.y = 10;

【讨论】:

    【解决方案2】:

    不,你不能这样做。 这是因为 ClassB 的任何实例也是 ClassA 的实例,反之亦然。

    另外如果上面的表述不清楚,除非有充分的理由,否则最好避免父类依赖子类的情况。

    【讨论】:

      【解决方案3】:

      没有。从 Parent 继承的对象不一定具有 int 类型的属性 y。事实上,这将违反 Liskov 替换原则(SOLID 中的 L)。这个原则意味着我应该能够将任何从 Parent 下降到该变量的类型的对象分配给该变量,并且逻辑应该可以工作。显然,如果我创建了一个名为 Child2 的类,该类继承自 Parent 但没有任何属性,或者将 y 声明为其他类型(例如 DateTime),那么您的代码显然无法将值 10 分配给该对象实例。

      在某些情况下,您的父类可能会推迟到子类(请参阅虚拟和抽象方法和属性以获取示例)。子类可能会通过考虑 y 的值来影响这些虚拟或抽象方法之一的行为,但父类不能在不声明此类属性的情况下公开该 y。

      【讨论】:

        【解决方案4】:

        这是不可能的,因为您使用的是 Parent 类型的变量,而 parent 没有公开属性 y。

        【讨论】:

          【解决方案5】:

          要使用基类型的变量访问派生类型的成员,您应该显式地将变量强制转换为派生类型:

          Parent parent = new Child();
          Child child = (Child) parent;
          child.y = 10;
          

          但您应该记住,如果parent 包含另一种类型的对象,Child child = (Child)parent 可能会引发运行时异常。例如,这段代码抛出运行时异常:

          Parent parent = new AnotherChild();
          Child child = (Child) parent;
          

          您可以使用is 运算符避免运行时异常:

          if (parent is Child) 
          {
              Child child = (Child) parent;
              child.y = 10;
          }
          

          或者使用as 运算符更好

          Child child = parent as Child;
          if (child != null)
          {
              child.y = 10;
          }
          

          as 运算符从不抛出异常。相反,如果无法转换对象,则返回 null。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-09
            • 2011-05-06
            相关资源
            最近更新 更多