c# - 如何访问抽象父类的实例成员?
问题描述
如果无法创建父类(抽象)的实例,我们如何在子类中访问抽象父类的实例成员?
解决方案
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。并修改属性“代码”。然后将对象转换回 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。
但!如果您使用 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; }
}
然后发生的事情就是我认为你担心发生的事情。
现在派生类和超类都有一个属性“代码”。
在此示例中,输出实际上会根据您查看对象的方式而有所不同。
在这种情况下会发生一些非常奇怪的事情,如果使用不当很容易出现故障。
例子:
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 对您的类没有更多作用,除了说明它不能自己构造,它必须被继承才能构造。