当我不断调用基类方法时,如何调用我的具体类方法

本文关键字:类方法 调用 我的 何调用 基类 | 更新日期: 2023-09-27 18:08:56

给定这些类:

public abstract class Car
{
    public void Copy(Car car)
    {
        // stuff //
    }
}
public class Ford : Car
{
    public void Copy(Ford updatedFord) 
    {
        base.Copy(updatedFord);
        // copy ford stuff //
    }
}
public class Holden  : Car
{
    public void Copy(Holden updatedHolden) { .. }
}

这就是我想做的…

public void TestMethod()
{
    Car car1 = new Ford { Colour = "Red", StickerCount = 1 };
    Car car2 = new Ford { Colour = "Blue", StickerCount = 666 };
    car1.Copy(car2);
    // I expect blue AND 666 to be copied. only Blue is.
}

这是。net FIDDLE中的所有代码。

所以在这个场景中,如果car是一个Ford实例,那么Ford类的Copy(..)方法被调用..而不是Car实例上的copy方法。

我只是不确定如何使复制方法在最具体的类上调用(然后通过继承的层次结构调用base.XXX())。

当我不断调用基类方法时,如何调用我的具体类方法

这是因为Ford.Copy没有在基类上声明,因此在将Ford转换为Car后无法访问。

Ford.Copy需要重写Car.Copy .

但是由于它的形参有不同的类型,它不能直接覆盖基方法。

您需要的是参数化Car - Car<TCar>,然后使用该类型参数定义您的参数类型。然后,每个子类将指定它们要复制的汽车的类型。

这被称为f界多态性。

public abstract class Car<TCar> where TCar : Car<TCar>
{
    public virtual void Copy(TCar car)
    {
        // stuff //
    }
}

public class Ford : Car<Ford>
{
    public override void Copy(Ford updatedFord) {}
}
public class Holden  : Car<Holden>
{
    public override void Copy(Holden updatedHolden) { .. }
}

这会给你你想要的行为:

    dynamic car1 = (Car)new Ford { Id = 1, Colour = "Red", StickerCount = 1 };
    dynamic car2 = (Car)new Ford { Id = 2, Colour = "Blue", StickerCount = 666 };

这里没有"隐藏"。他超载了Car.Copy(Car)。这会帮助你找到自我。

using System;
class A
{
    public void Foo(A a)
    {
        Console.WriteLine("A.Foo");
    }
}
class B : A
{
    //overloading
    public void Foo(B b)
    {
        Console.WriteLine("Overload");
    }
    //hiding
    public new void Foo(A a)
    {
        Console.WriteLine("Hide");
    }
}
class Test
{
    static void Main()
    {
        A a = new A(); 
        A b = new B();
        B c = new B();
        a.Foo(a);   //A.foo
        b.Foo(a);   //A.foo
        b.Foo(b);   //A.foo
        ((dynamic) b).Foo(a); //hide (equivalent to overriding Foo in B when A.Foo is virtual or abstract)
        c.Foo(a);   //hide
        c.Foo(b);   //hide
        c.Foo(c);   //overload
    }
}

你的Copy方法应该是一个虚拟方法。

public abstract class Car
{
    public string Colour { get; set; }
    public virtual void Copy(Car car)
    {
        Colour = car.Colour;
    }
}
public class Ford : Car
{
    public int StickerCount { get; set; }
    public override void Copy(Car car) 
    {
        base.Copy(car);
        Ford ford = car as Ford;
        if (ford != null)
            StickerCount = ford.StickerCount;    
    }
}
public static void Main()
{
    Car car1 = new Ford { Colour = "Red", StickerCount = 1 };
    Car car2 = new Ford { Colour = "Blue", StickerCount = 666 };
    // if Copy is not virtual, Car.Copy will be called here instead of Ford.Copy!
    car1.Copy(car2);
    Console.WriteLine("Result should be blue: " + car1.Colour);
    Console.WriteLine("Result should be 666: " + ((Ford)car1).StickerCount);
}

必须声明Car。复制为虚拟和福特。复制覆盖。