C# 为什么可以';当对象是子类类型时,我是否从超类调用子类中的公共方法?
我有一个类B,它是类a的子类。我创建了一个类型为B的对象并对其调用OnlyA(),但在OnlyA()内部,对OnlyB()的调用会导致编译器错误 根据我的理解,C# 为什么可以';当对象是子类类型时,我是否从超类调用子类中的公共方法?,c#,inheritance,C#,Inheritance,我有一个类B,它是类a的子类。我创建了一个类型为B的对象并对其调用OnlyA(),但在OnlyA()内部,对OnlyB()的调用会导致编译器错误 根据我的理解,OnlyB()与此相同。OnlyB()调用的方法应从对象的类(B)中选择,而不是从执行代码的当前类(A)中选择。这就是为什么对Both()的调用调用的是B中的方法,而不是A中的方法。那么为什么它只搜索A中的B(),而不是B中的?我怎么知道调用的方法是从对象的类还是当前类中选择的 class Program { static voi
OnlyB()
与此相同。OnlyB()调用的方法应从对象的类(B)中选择,而不是从执行代码的当前类(A)中选择。这就是为什么对Both()的调用调用的是B中的方法,而不是A中的方法。那么为什么它只搜索A中的B(),而不是B中的?我怎么知道调用的方法是从对象的类还是当前类中选择的
class Program
{
static void Main(string[] args)
{
B bRefB = new B();
bRefB.OnlyA();
}
}
class A
{
public void OnlyA()
{
Console.WriteLine("In A - OnlyA()");
OnlyB(); // compiler error
Both(); // calls the method in B
}
public virtual void Both()
{
Console.WriteLine("In A - Both()");
}
}
class B : A
{
public void OnlyB()
{
Console.WriteLine("In B - OnlyB()");
}
public override void Both()
{
Console.WriteLine("In B - Both()");
}
}
您完全正确地认为
OnlyB
与this.OnlyB
相同。这就是问题所在<代码>此属于A类型
。它不知道B
甚至存在(也不应该存在)
超类根本不知道(也不应该知道)它们有派生类,更不用说其中包含什么方法了。这不是一个“搜索”的问题;当您的C
没有定义OnlyB
时会发生什么?将调用什么方法
另一方面,子类总是超类的子类;因此,它们可以安全地调用基类方法。您绝对正确地认为
OnlyB
与this.OnlyB
相同。这就是问题所在<代码>此属于A类型
。它不知道B
甚至存在(也不应该存在)
超类根本不知道(也不应该知道)它们有派生类,更不用说其中包含什么方法了。这不是一个“搜索”的问题;当您的C
没有定义OnlyB
时会发生什么?将调用什么方法
另一方面,子类总是超类的子类;因此,它们可以安全地调用基类方法。Bradely的文章介绍了代码不起作用的原因(此
类型为A
)。以下是将需求编写为代码的正确方法
您希望根据对象的运行时类型调用方法。由于的编译时是当前对象的类型,所以在调用之前,您需要以某种方式将其强制转换为派生类型。可能的选择:
- just cast-静态检查B是否只有B
OnlyB
,运行时强制转换异常:
((B)this).OnlyB();
- 使用
dynamic
-无静态类型检查,如果实际类没有OnlyB
方法,则在运行时异常,无论它是否来自B、C
dynamic b = this;
b.OnlyB();
- 手动反射调用(与
动态相同)
- 泛型-参见
布雷德利的文章介绍了代码不起作用的原因(此
属于A
)。以下是将需求编写为代码的正确方法
您希望根据对象的运行时类型调用方法。由于的编译时是当前对象的类型,所以在调用之前,您需要以某种方式将其强制转换为派生类型。可能的选择:
- just cast-静态检查B是否只有B
OnlyB
,运行时强制转换异常:
((B)this).OnlyB();
- 使用
dynamic
-无静态类型检查,如果实际类没有OnlyB
方法,则在运行时异常,无论它是否来自B、C
dynamic b = this;
b.OnlyB();
- 手动反射调用(与
动态相同)
- 泛型-参见
想象一下,如果您没有遇到编译器错误。静态输入有什么好处?您可以从中调用任何内容,直到运行时才得到错误。想象一下,如果您没有得到编译器错误。静态输入有什么好处?您可以从调用中调用任何内容,直到运行时才得到错误。因此,超类调用子类中的方法(无需使用某些高级技术)的唯一方法是调用在子类中重写的方法?换句话说,超类不能访问任何子类方法,除非它们重写超类中的方法?@000 Correct;这是做这件事的唯一方法。请注意,您可以使用abstract
而不是virtual
来表示基类不定义行为并强制派生类实现它。这当然意味着基类不再是可构造的,因此超类调用子类中的方法(不使用某些高级技术)的唯一方法是调用在子类中重写的方法?换句话说,超类不能访问任何子类方法,除非它们重写超类中的方法?@000 Correct;这是做这件事的唯一方法。请注意,您可以使用abstract
而不是virtual
来表示基类不定义行为并强制派生类实现它。这当然意味着基类不再是可构造的