簡體   English   中英

當我不斷調用基類方法時,不確定如何調用我的具體類方法

[英]Not sure how to call my concrete class method when I keep calling the base class method

鑒於這些類:

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中的所有代碼

所以在這種情況下,如果汽車是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
    }
}

您的復制方法應該是虛擬方法。

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.Copy聲明為虛擬,並將Ford.Copy聲明為overover。 然后它應該工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM