C# 如何在C语言中设计构造函数继承#

C# 如何在C语言中设计构造函数继承#,c#,oop,C#,Oop,我喜欢C#但就是找不到解决办法。这显然是一种简化 假设我们有动物,狗,猫,家具,椅子,狗 动物有一个名字。家具有高度 但是。一只狗突然出现。它有一个名字和一个高度 如何避免塔尔多格和家具的高度重复 abstract class Animal { public string Name { get; set; } public Animal(string name) { Name = name; } } class Dog : Animal {

我喜欢C#但就是找不到解决办法。这显然是一种简化

假设我们有动物,狗,猫,家具,椅子,狗

动物有一个名字。家具有高度

但是。一只狗突然出现。它有一个名字和一个高度

如何避免塔尔多格和家具的高度重复

abstract class Animal
{
    public string Name { get; set; }
    public Animal(string name)
    {
        Name = name;
    }
}
class Dog : Animal
{
    public Dog(string name)
        : base(name)
    {

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

    }
}
abstract class Furniture
{
    public int Height { get; set; }
    public Furniture(int height)
    {
        Height = height;
    }
}
class Chair : Furniture
{
    public Chair(int height)
        : base(height)
    {

    }
}
class TallDog : Animal
{
    public int Height { get; set; }
    public TallDog(string name, int height)
        : base(name)
    {
        Height = height;
    }
}

下面是一个工厂实现,它利用泛型和接口来实现您的目标,只使用默认构造函数

public interface INameable
{
    string Name { get; set; }
}

public interface IMeasurable
{
    int Height { get; set; }
}

abstract class Animal: INameable
{
    public string Name { get; set; }
}
class Dog : Animal { }
class Cat : Animal { }

abstract class Furniture: IMeasurable
{
    public int Height { get; set; }
}
class Chair : Furniture { }

class TallDog : Animal, IMeasurable
{
    public int Height { get; set; }
}

public T NameableFactory<T>(string name)
    where T:INameable, new()
{
    return new T { Name = name };
}

public T MeasurableFactory<T>(int height)
    where T : IMeasurable, new()
{
    return new T { Height = height };
}

public T NameableMeasurableFactory<T>(string name, int height)
    where T : INameable, IMeasurable, new()
{
    return new T { Name = name , Height = height };
}

[TestMethod]
public void TestFactories()
{
    Cat ct = NameableFactory<Cat>("milo");
    Chair ch = MeasurableFactory<Chair>(5);
    TallDog td = NameableMeasurableFactory<TallDog>("Fido", 5);
}
公共接口不可测量
{
字符串名称{get;set;}
}
公共接口不可测量
{
整数高度{get;set;}
}
抽象类动物:不可测量
{
公共字符串名称{get;set;}
}
狗类:动物{}
类别猫:动物{}
抽象类家具:可测量
{
公共整数高度{get;set;}
}
班主任:家具{}
狗类:动物,可测量
{
公共整数高度{get;set;}
}
公共T namableFactory(字符串名称)
其中T:INameable,new()
{
返回新的T{Name=Name};
}
公共T可测量工厂(内部高度)
其中T:i可测量,new()
{
返回新的T{Height=Height};
}
公共T namableMeasureFactory(字符串名称,整数高度)
式中:不可测量,不可测量,新()
{
返回新的T{Name=Name,Height=Height};
}
[测试方法]
公共测试工厂()
{
Cat ct=可命名工厂(“milo”);
椅子ch=可测量工厂(5);
TallDog td=可测量的工厂名称(“Fido”,5);
}

您应该记住,“好的OO”主要是关于对象的行为。对象(和类)的存在是为了将一些“脱离现实的概念”映射到作为应用程序基础的“模型”中

因此:您不需要使用继承在这里或那里保存一行代码。您将“B扩展A”标记放在B上,因为这是由您的模型引导的合理操作

考虑到这一点:对于出于完全错误的原因使用继承的人来说,你把一只高狗变成家具的想法是一个很好的例子


因此:干脆忘掉这个想法;并按照评论中的建议去做:创建合理的接口,并将这些类放在它们有意义的地方。

我认为您不会避免重复实现。。。但是如果你想(比如)比较任何一条高狗和任何一件家具的高度,你可以让
家具和
高狗实现一个通用的界面。我不认为高狗就是一件家具@因此,最好的选项是
TallDog:ISizable
Furniture:ISizable
。@TheSilence您不能将两个同名类成员在不同类中的分配视为重复。首先是因为这实际上是不可能的,其次是因为你会以非常糟糕的方式将所有的实现结合在一起。只是因为他们看起来一样并不意味着他们是一样的东西。它们在不同的类上是不同的属性-只需做两个赋值。@老实说,我通常甚至会去掉
动物
,只为你的动物行为提供接口,并让
狗:我和每个动物都做
并复制这些赋值-这种继承通常不是一条好的方法旅行。您已经遇到了它的局限性(因此这个问题)。这将从技术上缓解OP一心想消除重复的两行代码,但我确信他也不想扩展或维护此实现。是否为每种可能的接口排列提供工厂方法?一旦你想让你的实现有所不同,整个事情就会分崩离析。你会如何处理这个问题?用接口。策略模式可能取决于共享实现。通过不以维护能力和可扩展性为代价来消除简单构造函数分配的重复数据。听起来是个好主意。想提供一些代码吗?我很乐意删除这个答案。