【问题标题】:Why can't I call a public method in the subclass from the superclass when the object is of the subclass type?当对象是子类类型时,为什么我不能从超类调用子类中的公共方法?
【发布时间】:2017-06-29 20:52:09
【问题描述】:

我有一个 B 类,它是 A 类的子类。我创建了一个 B 类型的对象并在其上调用 OnlyA(),但在 OnlyA() 内部,对 OnlyB() 的调用会导致编译器错误。

据我了解,OnlyB()this.OnlyB() 相同,调用的方法应从对象的类 (B) 中选择,而不是从正在执行代码的当前类 (A) 中选择。这就是为什么对 Both() 的调用调用 B 中的方法,而不是 A。那么为什么它在 A 中而不是 B 中搜索 OnlyB()?我应该如何知道调用的方法是从对象的类还是当前类中选择的?

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()");
    }
}

【问题讨论】:

  • 想象一下,如果您没有收到编译器错误。静态类型有什么好处?您可以从 A 调用任何内容,并且在运行时之前不会出现错误。

标签: c# inheritance


【解决方案1】:

OnlyBthis.OnlyB 相同是绝对正确的。这就是问题所在; this 的类型为 A。它不知道B 甚至存在(也不应该存在)。

超类不知道也不应该知道它们有派生类这一事实根本更不用说它们中有什么方法了。这不是“搜索”的问题;当您拥有未定义 OnlyBC 时会发生什么?会调用什么方法?

另一方面,子类总是超类的子类;因此它们调用基类方法是安全的。

【讨论】:

  • 那么超类调用子类中的方法的唯一方法(不使用一些高级技术)是调用子类中覆盖的方法吗?换句话说,超类不能访问任何子类方法,除非它们覆盖超类中的方法?
  • @000 正确;这是唯一技术应该用来做这样的事情。请注意,您可以使用abstract 而不是virtual 来表示基类没有定义行为并强制派生类实现它。这当然意味着基类不再是可构造的
【解决方案2】:

Bradely 的 answer 介绍了为什么您的代码不起作用(this 的类型为 A)。这是将您的需求编写为代码的正确方法。

您想根据对象的运行时类型调用方法。由于this 的编译时间是当前对象的类型,因此您需要在调用之前以某种方式将其转换为派生类型。可能的选择:

  • 只是强制转换 - 静态检查 B 是否有 OnlyB,在运行时强制转换异常:

    ((B)this).OnlyB(); 
    
  • 使用dynamic - 没有静态类型检查,如果实际类没有OnlyB 方法,则在运行时出现异常,无论它来自B、C...

    dynamic b = this;
    b.OnlyB(); 
    
  • 手动反射调用(同dynamic)。

  • 泛型 - 见Curiously Recurring Template Pattern and generics constraints (C#)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-14
    • 2018-08-22
    • 1970-01-01
    • 2015-06-19
    • 2020-05-03
    • 2013-03-01
    • 2017-05-13
    • 1970-01-01
    相关资源
    最近更新 更多