Java 继承与 C# 继承

2022-09-03 13:22:27

假设Java有这些分层类:

class A 
{
}
class B extends A
{
    public void m()
    {
        System.out.println("B\n");
    }
}
class C extends B
{
    public void m()
    {
        System.out.println("C\n");
    }
}
class D extends C
{
    public static void main(String[] args)
    {
        A a = new D();
        // a.m(); // doesn't work
        B b = new D();
        b.m();
        C c = new D();
        c.m();
        D d = new D();
        d.m();
    }
}

这是 C# 中相同代码的(盲)重复:

using System;
class A 
{   
}
class B : A
{
    public void M()
    {
        Console.WriteLine("B");
    }
}
class C : B
{
    public void M() // I need to use public new void M() to avoid the warning
    {
        Console.WriteLine("C");
    }
}
class D : C
{
    public static void Main(String[] args)
    {
        A a = new D();
        // a.M(); // doesn't work       
        B b = new D();
        b.M();
        C c = new D();
        c.M();
        D d = new D();
        d.M();
    }
}

当我执行Java代码时,我得到了,而C#返回.C-C-CB-C-C

对我来说,C#的结果更有意义,因为引用B调用了自己的方法。

  • Java设计人员决定打印而不是打印背后的逻辑是什么?我的意思是,为什么引用B在C中使用重写方法?这种方法的优势是什么?C-C-CB-C-C
  • 如何像 C# 一样将 Java 代码更改为打印出来?我的意思是,我怎么能教java调用它使用的确切引用的方法?B-C-C
  • 如何更改C#代码以打印出来?我的意思是,如何教C#调用重写方法?C-C-C

答案 1

它用于虚函数定义:

虚函数或虚方法是一种函数或方法,其行为可以在具有相同签名的函数的继承类中重写。这个概念是面向对象编程(OOP)多态性部分的一个非常重要的部分。

在 C# 中,应将该方法声明为虚拟方法才能被重写,如 MSDN 所示:

由于该方法不是虚拟的,因此即使变量实际上是一个实例,它也会执行。Mb.M()bD

在Java中,默认情况下,每个非静态方法都是虚拟的,因此当您覆盖方法(即使没有注释)时,的行为将是继承方法行为的行为。@Overrideb.M()d.M()c.M()

如何更改Java代码以像C#一样打印出B-C-C?我的意思是,我怎么能教java调用它使用的确切引用的方法?

在Java中,你根本无法做到这一点。类中的方法将覆盖 中的方法。将修饰符添加到 只会使该方法或其他子级无法覆盖该方法。MCMBfinalB#MCBM()

如何更改 C# 代码以打印出 C-C-C?我的意思是,如何教C#调用重写方法?

将类中的方法更改为并在类中重写它:MBvirtualC

class B : A
{
    public virtual void M()
    {
        Console.WriteLine("B");
    }
}
class C : B
{
    public override void M() // I need to use public new void M() to avoid the warning
    {
        Console.WriteLine("C");
    }
}

答案 2
  1. 在java中,默认情况下所有方法都是虚拟的。派生类中的方法从基数重写方法。在 C# 中,它们不是。

  2. 似乎你不能这样做。但是,您可以通过将派生类声明为 来防止派生类重写此方法。final

  3. 使用基类中的关键字和派生的关键字声明此方法。virtualoverride


推荐