可以在父类中使用子类字段吗?

时间:2018-08-30 09:39:03

标签: c# .net oop

是否可以使用父类构造函数或方法中的子类字段或属性?

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”

5 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

当您通过对obj 不了解的父类访问实例y时,您肯定无法访问该成员仅在子类上定义。

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

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

要使用基本类型的变量访问派生类型的成员,应将变量显式转换为派生类型

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

但是请记住,如果Child child = (Child)parent;包含其他类型的对象,例如,如果您在上面编写了parent,则Parent parent = new AnotherChild();会抛出运行时异常

您可以使用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。

答案 4 :(得分:0)

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

在某些情况下,您的Parent类可以服从于child类(有关示例,请参见虚拟和抽象方法和属性)。子类可能通过考虑y的值来影响这些虚拟方法或抽象方法之一的行为,但父类不能在不声明此类属性的情况下公开y。