如何访问抽象父类的实例成员?

时间:2018-06-14 08:02:11

标签: c# inheritance abstract-class

如果无法创建父类(抽象)的实例,我们如何访问子类中抽象父类的实例成员?

1 个答案:

答案 0 :(得分:0)

TL:RD;答案是肯定的。但他们没有被复制。

让我们说:

public abstract class A
{
    public string Code { get;set; }
}

是你的超级(父/基)班级和

public class B : A
{
    public string Title { get;set; }
}

是派生(子)类。 B类的实例化将包含属性Code和Title。

B类扩展了A类。这样就可以通过简单地将类B的实例化转换为A类来实现:

B foo = new B();
A bar = foo as A;

虽然我建议您使用接口而不是超类来检查实例是否具有您正在寻找的特定属性。

同样,A类属性和方法不会复制到B类.B类将其方法和属性扩展到A类。

- 编辑 -

回答这个问题:两个构造函数都被调用,所以不是真的有两个不同的对象吗?

在编译器级别上,是的,抽象类和派生类是2个不同的对象。但是作为实例B的用户,您不必担心B实际上是由B和A组成的对象。

在上面的示例中,如果将B转换为A.并修改属性“Code”。然后将对象强制转换为B.属性“代码”仍设置为新值。

示例:

B foo = new B();
foo.Code = "testfoo";
Console.WriteLine(foo.Code); //output will be testfoo;

A bar = foo as A;
bar.Code = "testbar";
Console.WriteLine(bar.Code); //output will be testbar;

但是:

Console.WriteLine(foo.Code); //output will be testbar;

这是因为派生类B实际上并不包含属性Code。它只表示它扩展了A,A具有属性Code。

BUT!如果你使用new(vb.net中的阴影),你的疑问是合理的。

示例:

public abstract class A
{
    public string Code { get;set; }
}

public class B : A
{
    public new string Code { get;set; }
    public string Title { get;set; }
}

然后发生的是我认为你担心发生的事情。

现在派生类和超类都有一个属性'Code'。

在此示例中,输出实际上会根据您查看对象的方式而有所不同。

在这种情况下会发生一些非常奇怪的事情,如果使用不当,很容易出现故障。

示例:

B foo = new B();
foo.Code = "testfoo";
Console.WriteLine(foo.Code); //output will be testfoo;

A bar = foo as A;
bar.Code = "testbar";
Console.WriteLine(bar.Code); //output will be testbar;

但现在:

Console.WriteLine(foo.Code); //output will be testfoo;

此外,除了声明它不能单独构造之外,术语Abstract对你的类没有更多的作用,它必须被继承才能被构造。