【问题标题】:Interfaces and inheritance with derived class派生类的接口和继承
【发布时间】:2015-10-14 02:35:15
【问题描述】:

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

    }
}

【问题讨论】:

  • 如果Class A已经实现了Interface A,为什么还要在Class B中实现呢?你总是可以尝试创建这个场景。
  • 我投票决定将此问题作为题外话结束,因为只有很少的代码会真正编译
  • 为什么你认为将AB 分成单独的.cs 文件意味着你需要第三个派生类?如果AB 共享一些描述它们的作用的通用方法,那么您可以创建一个单一接口来覆盖该功能(比如说它称为IDoStuff),其中both @987654333 @ 和 B 实施:public class A : IDoStuff {}public class B : IDoStuff {} 在这里提供一些奇怪的信息,并不会帮助您及时获得准确的答案,因为目标职位不断移动。
  • @KirstyWhite 根据您对此的 cmet 和我的回答,我认为您需要回到绘图板并考虑该站点如何提供帮助。 SO的想法是回答具有客观答案的狭窄问题。不可能读懂你的想法或任何要求你做这些事情的人的想法。它最初是关于伪代码中的接口和继承的问题,最新的更新是您需要制作 Web 服务吗?这一切都是可以实现的,但前提是您清楚地知道首先需要做什么。
  • 抱歉,代码现在应该看起来更清晰了。但是我不确定我应该在 Bravo 的界面中添加什么?正如我所说,我被要求为 Alpha 和 Bravo 实现一个接口。但是,我一直只返回一个界面。

标签: c# linq inheritance interface polymorphism


【解决方案1】:

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

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

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

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

我不会直接使用您的示例,而是使用不使用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!

【讨论】:

  • 我按照您的要求做了,但是 请不要实际使用此代码,这不是您实现您想要做的事情的方式,我只是想这样做你问了什么
  • @KirstyWhite 这只是错误的名称。我将删除它并保持第二次尝试填补空白,但我将进行第三次尝试,这种尝试只保留您的问题的精神而无需代码。
  • 当你提到网络服务时,我在想this 讨论的内容;通过实现多个接口来组合 Web 服务,这将导致类似 this 的结果。但是随着最新的更新,我仍然无法理解您想要实现的目标。
  • 不应该Dog 现在实现IDog
  • @DanielFlint 我认为 KirstyWhite 一次有不止一个问题,但感觉最好的起点是继承?我们没有足够的信息来开始猜测我的感受
【解决方案2】:

我将在黑暗中试一试,并冒险猜测您不太了解接口和继承是什么。我将首先解释什么是接口:

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

例如:

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

【讨论】:

  • 示例越多,包含可运行的内容就越好。
  • 谢谢!只是想我会加我的 2 美分:)
猜你喜欢
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多