与派生类的接口和继承

时间:2015-10-14 02:35:15

标签: c# linq inheritance interface polymorphism

我被困在接口和继承上。如果我实现两个都有接口的类,我怎么能一起添加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 });
        }

    }
}

2 个答案:

答案 0 :(得分:2)

好的,所以你被问到的问题基本上就是如何进行某种称为“提取”接口的重构。

如果您了解接口与类型,这是更容易重构和理解之一。

所有接口都是类型,但并非所有类型都是接口。

现在让我们假设我们正在处理一个有两类类型的世界:类和接口(如示例所示)。

我不会直接使用您的示例,而是会使用一个不同但更清晰的示例,该示例不使用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();
}

现在我们在DogDoorBell上实施了一种新方法。

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可能与我们非常不同,但足够相似,可能值得共享基类。 (实际上,这是一个延伸,但它确实得到了重点。)

如果不添加所有这些新接口及其实现,让我们只为我们已有的“共享基类”重构。

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!

答案 1 :(得分:1)

我将在黑暗中拍摄并猜测你不太了解接口和继承是什么。我将首先解释一下接口是什么:

接口仅包含继承类必须实现的方法,属性,事件或索引器的定义。

例如:

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();
    }
}