簡體   English   中英

接口和繼承與派生類

[英]Interfaces and inheritance with derived class

我被接口和繼承所困擾。 如果我實現兩個都有接口的類,那么如何將A類和B類的屬性加在一起? 比如我想聯想firstitemseconditem

public interface IAlpha
{
  [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/AddBravoToAlpha/{firstitem}/{seconditem}")]
  void AddBravoToAlpha(int firstitem, int seconditem);
}
public interface IBravo
{
    // what goes in here?
}
public Class Alpha
{
    public Alpha()
    {
        AlphaAdd = new List<Bravo>();
    }
   int Firstitem { get; set }
   public List<Bravo> AlphaAdd { get; set; }
}
public Class Bravo 
{
   public Bravo() 
   {
        BravoAdd = new List<Alpha>(); //not sure if Bravo can access Alpha (derived class)
   }
   int Seconditem { get; set }
   Guid Indexer { get; set }
   public List<Alpha> BravoAdd { get; set; }
}
public Class BravoDoesAlpha : IBravo, IAlpha //????
{
    List<Alpha> alpha = new List<Alpha>();
    List<Bravo> bravo = new List<Bravo>();

    public void AddBravoToAlpha(int firstitem, int seconditem)
    {
        var result = alpha.Where(n => String.Equals(n.Firstitem, firstitem)).FirstOrDefault();
        var result1 = bravo.Where(n => String.Equals(n.Seconditem, seconditem)).FirstOrDefault();
        if (result != null)
        {
            result.BravoAdd.Add(new Alpha() { Firstitem = firstitem });
        }
        if (result1 != null)
        {
            result1.AlphaAdd.Add(new Bravo() { Seconditem = seconditem });
        }

    }
}

好的,所以您要問的問題基本上是一個關於如何進行某種重構的問題,稱為“提取”接口。

如果您了解接口與類型之間的關系,這是更容易進行的重構之一。

所有接口都是類型,但並非所有類型都是接口。

現在,假設我們正在處理一個具有兩個類型族的世界:類和接口(如您的示例)。

除了直接使用示例之外,我將使用一個不使用AlphaBravoCharlieEpsilon等的不同但更清晰的示例,因為這種東西使含義更難理解。

首先,這是之前的內容:

public class Dog
{
    public void Bark() { Console.WriteLine("Woof!"); }

    public int NumberOfDogLegs { get { return 2; } }

    public int NumberOfDogFriends { get; set; } // this can be set

    private string SecretsOfDog { get; set; } // this is private
}

public class DoorBell
{
    public void Chime() { Console.WriteLine("Ding!"); }
}

要提取類的接口,只需簡單地將類的所有公共成員提取到接口即可。

public interface IDog
{
     void Bark();
     int NumberOfDogLegs { get; }
     int NumberOfDogFriends { get; set; }
}

public interface IDoorBell
{
     void Chime();
}

現在,要真正利用OOP,您可以找到抽象IDogIDoorBell 他們有什么共同點? 好吧,顯而易見的是它們都發出聲音。 因此,我們創建了一個新接口,即public interface IMakeANoise並說IDogIDoorBell都實現了它。

public interface IMakeANoise
{
     void MakeNoise();
}

public interface IDog : IMakeANoise
{
     void Bark();
     int NumberOfDogLegs { get; }
     int NumberOfDogFriends { get; set; }
}

public interface IDoorBell : IMakeANoise
{
     void Chime();
}

現在我們有了在Dog and DoorBell上實現的新方法。

public class Dog : IDog
{
    public void Bark() { Console.WriteLine("Woof!"); }

    public int NumberOfDogLegs { get { return 2; } }

    public int NumberOfDogFriends { get; set; } // this can be set

    private string SecretsOfDog { get; set; } // this is private

    public void IMakeANoise() { Bark(); }
}

public class DoorBell : IDoorBell
{
    public void Chime() { Console.WriteLine("Ding!"); }

    public void IMakeANoise() { Chime(); }
}

現在,我們實際上正在編寫一個視頻游戲,而DogDoorBell都是我們可以在屏幕上顯示的東西。 好吧,這會使它們更大,因為我們將需要提供更多信息,例如其坐標,狀態等。

在這種情況下, DogDoorBell對我們DoorBell可能非常不同,但是足夠相似,有可能值得分享一個基類。 (確實,這是一個延伸,但確實可以理解要點。)

在不添加所有這些新接口及其實現的情況下,我們只需對已有的東西進行“共享基類”重構即可。

public class RenderableThing : IMakeANoise, IDoAThousandOtherThings
{
    protected virtual string MyNoiseToMake { get { return ""; } }

    public virtual void MakeANoise()
    {
         Console.WriteLine(MyNoiseToMake);
    }
}

public class Dog : RenderableThing, IDog
{
    protected override string MyNoiseToMake { get { return "Woof!"; } }

    public void Bark() { MakeANoise(); } // see what we did there?

    // Notice that I am not declaring the method MakeANoise because it is inherited and I am using it by overriding MyNoiseToMake

    public int NumberOfDogLegs { get { return 2; } }

    public int NumberOfDogFriends { get; set; } // this can be set

    private string SecretsOfDog { get; set; } // this is private   
}

public class DoorBell : RenderableThing, IDoorBell
{
    public void Chime() { Console.WriteLine("Ding!"); }

    public override void MakeANoise()
    {
         Chime(); Chime(); Chime(); //I'll do it my own way!
    }
}

您可能想知道,這有什么意義? 所以我們可以做...

IMakeANoise dogNoiseMaker = new Dog();

IMakeANoise doorBellNoiseMaker = new DoorBell();

IList<IMakeANoise> listOfNoiseMakers = new List<IMakeANoise>();
listOfNoiseMakers.Add(dogNoiseMaker);
listOfNoiseMakers.Add(doorBellNoiseMaker);

foreach (IMakeANoise noiseMaker in listOfNoiseMakers)
{
    noiseMaker.MakeANoise();
}

// This will output

// Woof!
// Ding!
// Ding!
// Ding!

我將在黑暗中進行拍攝,並冒險猜測您不太了解接口和繼承是什么。 我將從解釋什么接口開始:

接口僅包含繼承類必須實現的方法,屬性,事件或索引器的定義。

例如:

interface IExample
{
    void HelloWorld();
}

class ExampleClass : IExample
{
    public void HelloWorld()
    {
        Console.WriteLine("Hello world.");
    }
}

現在繼承 ; 當您從基類派生一個類時,派生類將繼承該基類的所有成員,但構造函數除外。 注意:根據基類中成員的可訪問性,其孩子可能會或可能無法訪問父級成員。

public class Animal
{
    public string Name { get; set; }

    public Animal(string name)
    {
        Name = name;
    }

    public void Talk()
    {
        Console.WriteLine("{0} is talking", Name);
    }
}

public class Cat : Animal
{
    public Cat(string name) : base(name) { }
}

public class Dog : Animal
{
    public string FurColor { get; set; }

    public Dog(string name, string furColor) : base(name)
    {
        FurColor = furColor;
    }

    public void Greeting()
    {
        Console.WriteLine("{0} has {1} fur.", Name, FurColor);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var cat = new Cat("Rex");
        cat.Talk();

        var dog = new Dog("Beanie", "Red");
        dog.Talk();
    }
}

暫無
暫無

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

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