[英]Interfaces and inheritance with derived class
我被接口和繼承所困擾。 如果我實現兩個都有接口的類,那么如何將A類和B類的屬性加在一起? 比如我想聯想firstitem
與seconditem
。
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 });
}
}
}
好的,所以您要問的問題基本上是一個關於如何進行某種重構的問題,稱為“提取”接口。
如果您了解接口與類型之間的關系,這是更容易進行的重構之一。
所有接口都是類型,但並非所有類型都是接口。
現在,假設我們正在處理一個具有兩個類型族的世界:類和接口(如您的示例)。
除了直接使用示例之外,我將使用一個不使用Alpha
, Bravo
, Charlie
, Epsilon
等的不同但更清晰的示例,因為這種東西使含義更難理解。
首先,這是之前的內容:
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,您可以找到抽象IDog
和IDoorBell
。 他們有什么共同點? 好吧,顯而易見的是它們都發出聲音。 因此,我們創建了一個新接口,即public interface IMakeANoise
並說IDog
和IDoorBell
都實現了它。
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(); }
}
現在,我們實際上正在編寫一個視頻游戲,而Dog
和DoorBell
都是我們可以在屏幕上顯示的東西。 好吧,這會使它們更大,因為我們將需要提供更多信息,例如其坐標,狀態等。
在這種情況下, Dog
和DoorBell
對我們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.