C# 如何访问抽象父类的实例成员?
如果无法创建父类(抽象)的实例,我们如何访问子类中抽象父类的实例成员?TL:RD;答案是肯定的。但它们不是复制品 比如说:C# 如何访问抽象父类的实例成员?,c#,inheritance,abstract-class,C#,Inheritance,Abstract Class,如果无法创建父类(抽象)的实例,我们如何访问子类中抽象父类的实例成员?TL:RD;答案是肯定的。但它们不是复制品 比如说: public abstract class A { public string Code { get;set; } } 您的超级(父/基)类和 public class B : A { public string Title { get;set; } } 是您的派生(子)类。类B的实例化将包含属性代码和标题 类B扩展了类A。这使得将类B的实例化转换为类A
public abstract class A
{
public string Code { get;set; }
}
您的超级(父/基)类和
public class B : A
{
public string Title { get;set; }
}
是您的派生(子)类。类B的实例化将包含属性代码和标题
类B扩展了类A。这使得将类B的实例化转换为类A成为可能,只需执行以下操作:
B foo = new B();
A bar = foo as A;
尽管我建议您使用接口而不是超类来检查实例是否具有您正在寻找的特定属性
同样,类A的属性和方法不会复制到类B。类B将其方法和属性扩展到类A
--编辑--
为了回答这个问题:两个构造函数都被调用,所以不是真的有两个不同的对象吗
在编译器级别上,是的,抽象类和派生类是两个不同的对象。但作为实例B的用户,您不必担心B实际上是由B和a组成的对象
在上面的示例中,如果将B向下转换为A,并修改属性“Code”。然后将对象强制转换回B。属性“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;
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 testbar;
这是因为派生类B实际上不包含属性代码。它只说它扩展了A,并且A具有属性代码
但是!如果您使用新的(vb.net中的阴影),您的怀疑是有道理的
例如:
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;
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;
然后发生的事情我想你担心会发生什么
现在派生类和超类都有一个属性“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;
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;
此外,抽象一词对您的类也没有多大作用,除了说明它不能单独构造,必须继承才能构造。这是一个大主题。。。。如果您想知道全部细节,我建议简而言之,编译器使其工作符合标准。它是如何做到这一点的是一个实现细节,但如果你好奇的话,有一些好书,比如@matthewatson推荐的书。Google上有很多关于这个主题的帖子。我怀疑的是,当我们创建子类实例时,会调用父类构造函数,也会创建父类实例,这样我们就可以访问子类中的父类成员。在抽象父类的情况下,这是如何打开的?请参阅我在编辑文章中的回复。作为评论添加有点太多了!:)@PrakashPotlapadu——完全一样。抽象类没有那么大的不同,您不能实例化它,因为编译器不允许它,而不是因为它不可能。抽象方法有问题,但其他成员没有问题。@Davey van Tilburg我是堆栈溢出新手,我不知道添加注释是不礼貌的。@PrakashPotlapadu抱歉,我不是这个意思!这绝对不是不礼貌:)我指的是我对你的问题的回答超过了我在评论中的600个字符:)所以我编辑了我对你文章的回答。