伪多重继承

时间:2012-01-06 00:51:46

标签: c# inheritance interface

我有一系列对象,我已使用LINQ to SQL映射到数据库。表格高度标准化。我要抽象我的问题。我在数据库中实现了五个中心实体。然后,我有一系列其他对象,我想实现这五个实体中的一个或全部。

假设我正在实施一种体育课(想想运动队)。这五个实体是五大运动;棒球,篮球,足球,曲棍球,足球。我想为每个体育场明确实施一个课程。

这是一个例子,洋基体育场举办了棒球,曲棍球和足球比赛。我希望它实现这3个接口中的每一个。 StadiumBaseClass是我的抽象基类,它与我的数据库接口。 StadiumBaseClass实现了所有5个主要的运动界面。我不希望在所有可能的体育馆中使用相同的代码来实现IBaseball接口,我希望它在StadiumBaseClass中实现一次。

我这个例子,我只想实现3,这是最好的方法吗?它有点单调,但不完全?

class YankeeStadium : IBaseball, IHockey, IFootball
{
    StadiumBaseClass _Stadium {get; set;}

   // IBaseball
   public IBaseball.Whatever {get { return _Stadium.Baseball;} }

   // IFootball
   public IFootball.Whatever {get { return _Stadium.Hockey;} }

  // IHockey
   public IHockey.Whatever {get { return _Stadium.Hockey;} }
}  

5 个答案:

答案 0 :(得分:2)

我认为你根本不应该使用继承。您应该拥有一个带有name属性的Stadium类,而不是YankeeStadium类。

同样,您应该拥有一个属性,例如HasHockey,如果不适用,只需让Hockey属性返回null。

答案 1 :(得分:2)

这似乎是面向常见的面向对象建模问题的一种变体 - 过去,我认为这是一个教育机构建模的问题,其中某个人可能是学生,导师中的一个或多个,讲师,标记,研究员等。

我见过的最佳解决方案是Peter CoadJeff De Luca提议的Nebulon Archetypal Domain Shape,也称为Color Modelling

在您的情况下,实际的体育场将是您的Places。由于您希望将每个体育场明确地作为一个班级实施,因此每个体育场都代表实际的体育场馆。拥有一个共同的抽象基类可能会有所帮助。课程中的属性将描述体育场的物理属性 - 例如它的实际地址等。

您想要支持的每项不同的运动(您列出棒球,篮球,足球,曲棍球和足球)将被实施为Role课程,例如BaseballStadiumBasketballStadiumFootballStadiumHockeyStadiumSoccerStadium。课程中的属性将描述托管特定运动的具体特征(座位容量可能会有所不同,例如,从一项运动到另一项运动)。

答案 2 :(得分:1)

我建议每个运动场上只有每个体育场的属性,所以你可以打电话

Stadium.Baseball.Fixtures
Stadium.Hockey.Teams

当特定体育场不允许进行某项运动时,请返回该运动的Null Object;

例如

iceRink.Baseball.Available // false
iceRink.Baseball.Fixtures // the empty list

这种方式可以帮助您避免多重继承的问题,特别是像

这样的代码
((IBaseball)stadium).Fixtures

答案 3 :(得分:0)

这是另一种方法(我们使用了类似的东西,但不确定它与你的linq实现的对应程度):

让StadiumBaseClass实现具有基本功能的每个接口,然后公开实现类可以使用的虚拟属性a)指示它支持哪些接口,以及b)根据需要改变默认行为。

例如,假设以下接口:

    public interface IBaseball
    {
        void Whatever();
    }
    public interface IHockey
    {
        void Whatever();
    }
    public interface IFootball
    {
        void Whatever();
    }
    public interface IBasketball
    {
        void Whatever();
    }
    public interface ISoccer
    {
        void Whatever();
    }

您的基类看起来像:

    public class StadiumBaseClass : IBaseball, IBasketball, IHockey, IFootball, ISoccer
    {

        #region IBaseball Members

        public virtual bool IBaseballImplemented
        {
            get
            {
                return false;
            }
        }

        void IBaseball.Whatever()
        {
            // Do something
        }

        #endregion

        #region IBasketball Members

        public virtual bool IBasketballImplemented
        {
            get
            {
                return false;
            }
        }

        void IBasketball.Whatever()
        {
            // Do something
        }

        #endregion

        #region IHockey Members

        public virtual bool IHockeyImplemented
        {
            get
            {
                return false;
            }
        }

        void IHockey.Whatever()
        {
            // Do something
        }

        #endregion

        #region IFootball Members

        public virtual bool IFootballImplemented
        {
            get
            {
                return false;
            }
        }

        void IFootball.Whatever()
        {
            // Do something
        }

        #endregion

        #region ISoccer Members

        public virtual bool ISoccerImplemented
        {
            get
            {
                return false;
            }
        }

        void ISoccer.Whatever()
        {
            // Do something
        }

        #endregion
    }

将您的个人体育场课程留作:

    class YankeeStadium : StadiumBaseClass
    {
        public override bool  IBaseballImplemented
        {
            get 
            { 
                return true;
            }
        }
        public override bool IHockeyImplemented
        {
            get
            {
                return true;
            }
        }
        public override bool IFootballImplemented
        {
            get
            {
                return true;
            }
        }
    }

答案 4 :(得分:-1)

我认为你应该退后一步,看一下这四种模式中的一些。这正是他们旨在展示解决方案的情况。我建议你开始看看访客模式。 vistior模式允许许多项目(在您的案例中为体育场馆)在其间执行共同的行为。见这里:http://www.dofactory.com/Patterns/PatternVisitor.aspx

这里有四个模式组合的列表:http://www.dofactory.com/Patterns/Patterns.aspx

可能其他人可能会建议另一种模式来查看。装饰图案看起来也很有希望。 (我之前没有使用过decarator模式)。我认为最终你不应该与OO作斗争,而是寻找已发布的解决方案来解决你可能的常见情况。