1

这个问题与这个问题类似。不同之处在于我想要两个基类。

例子:

public class Circle
{
    private string _radius { get; set; }

    public Circle Radius(string radius)
    {
        _radius = radius;
        return this;
    }
}

public class Box
{
    private string _width { get; set; }

    public Circle Width(string width)
    {
        _width = width;
        return this;
    }
}

public class CircleAndBox : Circle, Box // Can't do in c#
{
    // should contain methods from both Circle and Box, but return CircleAndBox
}

也许 Circle and Box 不是最好的例子。基本上它们代表具有不同属性和方法的类。CircleAndBox 类恰好具有与 Circle 和 Box 相同的属性和方法。CircleAndBox 可能具有在 Circle 和 Box 中都不存在的附加属性和方法。

期望的结果

我应该可以写:

var circle = new Circle().Radius("5");
var box = new Box().Width("6");
var circleAndBox = new CircleAndBox().Radius("5").Width("6");

如果:

当我向CircleBox类添加方法时,我不应该触摸CircleAndBox类。就像从单个类的常规继承一样,CircleAndBox应该自动从两者继承所有公共方法,Circle并且Box

4

4 回答 4

4

既不CircleAndBox继承自类,又继承自这些类的对象。它必须重新定义每个类的方法。您可以添加隐式转换,CircleBox允许在需要引用这些对象的上下文中使用它。

public class CircleAndBox
{
    public Circle Circle { get; private set; }
    public Box Box { get; private set; }

    public CircleAndBox()
    {
        Circle = new Circle();
        Box = new Box();
    }

    public CircleAndBox Radius(string radius)
    {
        Circle.Radius(radius);
        return this;
    }

    public CircleAndBox Width(string width)
    {
        Box.Width(width);
        return this;
    }

    public static implicit operator Circle(CircleAndBox self)
    {
        return self == null ? null : self.Circle;
    }

    public static implicit operator Box(CircleAndBox self)
    {
        return self == null ? null : self.Box;
    }
}

请注意,隐式转换不会保留对象的类型,因此不应使用此技术将 a 传递CircleAndBox给采用 a 的方法Box并期望另一端的结果是 a CircleAndBox

CircleAndBox cb = new CircleAndBox();

// Implicit conversion, b contains a Box object.
Box b = cb;

// Compile-time error CS0030.
cb = (CircleAndBox)b;
于 2013-08-02T21:41:18.300 回答
2

继承的意思是“是一个”。

Ball是一个RoundThingCircle是一个RoundThingBox是一个SquareThingLamborghini是一个Car,并且Car是一个TransportBus并且Bicycle也是Transports。

如果它不是“是”关系,则不是继承。这就是为什么 C# 和 Java 不支持多重继承的解释,我认识的大多数 C++ 人都不鼓励它。一个对象几乎永远不会同时是两个东西。

不要仅仅为了节省代码行而滥用继承。即使保存代码行是一个合法的目标(我不同意),它甚至没有必要。其他两个构造可以在这里为您提供帮助。

首先,关于关系。您正在寻找的是完全不同的关系。不是“is a”,而是“can be used as”。这就是接口的用武之地。接口指定对象可以用作什么。所以你可以有两个接口IBoxICircle. 然后,您CircleAndBox的事物可以实现这两个接口,从而指定它可以同时用作两者。

其次,您可以使用更多的关系来使生活更轻松。您不会保存代码行。但是您将确保您CircleAndBox始终具有正确的行为,在CircleBox类中定义。为此,您可以使用聚合以及委托模式。聚合是一种表示“具有”的关系。所以让你的CircleAndBox类有一个私有Circle对象和一个私有Box对象,然后简单地通过调用相应私有对象的相应方法/属性/事件来实现ICircle和接口,并返回它们返回的内容。IBox

Presto,你有一个类,它有一个(聚合)Circle 和 Box 实例来实际传递工作,它通过具有相同的方法(委托)公开这些,因此可以用作(接口)一个 Circle一个盒子。

于 2013-08-02T22:22:16.997 回答
1

使用接口:

IBox 和 ICircle

public interface IBox
{
    Circle Width(string width)
}

public interface ICircle
{
    Circle Radius(string radius)
}

public class Circle : ICircle
{
    private int _radius { get; set; }

    public Circle Radius(string radius)
    {
        _radius = radius;
        return this;
    }
}

public class Box : IBox
{
    private int _width { get; set; }

    public Circle Width(string width)
    {
        _width = width;
        return this;
    }
}

public class CircleAndBox : ICircle, IBox
{
    // should contain methods from both Circle and Box, but return CircleAndBox
}
于 2013-08-02T21:38:29.823 回答
0

我认为你不能完全按照你的期望做,因为 C#(和一般的 .Net)不支持类的多重继承。您可以从一个类继承并实现一个接口。

例如:

interface iBox
{
  iBox Width(string width); //Assuming you want Box here and not Circle
}

然后你有盒子

class Box : iBox ...

现在你可以拥有

public class CircleAndBox : Circle, iBox
{
private Box _helper;
public iBox Width(string width) { _helper.Width(width); return this; }
}

这并不完全是您想要的,但它与我认为的 C# 所允许的一样接近。如果您愿意使用弱类型,还有一个委托方法可以将事物传递给 _helper,而无需显式实现每个方法。但是,通过直接委托,您不会返回您的 CircleAndBox 对象,而是返回 _helper 对象。我不确定这是否会达到目的。

此外,如果您不控制至少一个您希望继承的类,这将不起作用。

于 2013-08-02T21:47:17.820 回答