强制接口实现在c#中实现层次结构

时间:2009-06-26 13:35:39

标签: c# design-patterns interface hierarchy

我正在为新项目编写接口,并希望得到一些建议。

我有一个具有子类的类,它有一个子类。这个类的树是这样的:

Class Car
{
    Wheels Wheel;
}
Class Wheels
{
    Rims Rim;
}

简化:一辆车有一个轮子,一个轮子有一个轮圈。 (不能弥补其他更好的例子,对不起)。

所以我想在我的ICar,IWheels和IRims的接口实现中强制使用这个层次结构。

所以我做了类似的事(在C#中):

ICar
{
  IWheels Wheel;
}
IWheels
{
  IRims Rim;
}

我有一个错误,我不能在接口实现中有字段。所以这开始我的事情可能是错误的界面设计。我想强制接口实现来实现这种层次结构。但是也许可以按照设计模式和最佳实践来进行其他方式吗?

您能告诉我如何设计我的系统,以便强制对象实现这种层次结构吗?

也许在我的问题中有一些不准确的东西,或者我遗漏了一些重要的信息。如果是,请在评论中提问。

6 个答案:

答案 0 :(得分:10)

在您的界面中,您必须明确Wheels应该是ICar的属性,因为您无法声明接口实现应该具有哪些字段。 (字段是内部工作,因此界面不应该知道它。)

interface ICar
{
    IWheels Wheels
    {
       get;
    }
}

答案 1 :(得分:7)

您无法在界面中指定字段(并且您不应该 - 这是一个实施决策),但您可以指定属性:< / p>

public interface ICar
{
    IWheels Wheel { get; set; }
}

public interface IWheels
{
    IRims Rim { get; set; }
}

你可能只想把getter放在接口中 - 在接口中包含一个setter有点不寻常:

public interface ICar
{
    IWheels Wheel { get; }
}

public interface IWheels
{
    IRims Rim { get; }
}

(如果你想覆盖现有的(或抽象的)只有一个getter来添加一个setter的属性,那就很奇怪了,但我相信也可以用setter实现一个“getter-only”接口。)

答案 2 :(得分:4)

如错误所示,您无法在接口中指定字段。您可以指定属性:

interface ICar
{
    IWheels Wheel { get; set; }
}

interface IWheels
{
    IRims Rim { get; set; }
}

答案 3 :(得分:4)

您不能声明字段,但可以声明属性。这将强制特定类提供另一个类的实例具有相同的最终效果。

ICar
{
  IWheels Wheel { get; set; }
}
IWheels
{
  IRims Rim { get; set; }
}

答案 4 :(得分:0)

我不太习惯C#,但听起来你可以通过使用你想要使用的字段制作抽象类来强制实现。 因此,如果您扩展这些抽象类,您将获得其中的字段。 你必须创建一个抽象类和一个接口...

答案 5 :(得分:0)

这是一个功能齐全的代码...... 希望它有所帮助...

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication10
{
    //Interfaces

    public interface ICar
    {
        string name { get;}
        IWheel wheel { get;}
    }


    public interface IWheel
    {
        string brand { get;}
    }

    //Implementations

    public class Michelin : IWheel
    {
        #region IWheel Members

        public string brand
        {
            get { return "michelin"; }
        }

        #endregion
    }


    public class Toyota : ICar
    {
        Michelin m = new Michelin();
        #region ICar Members

        public string name
        {
            get { return "toyota"; }
        }

        public IWheel wheel
        {
            get { return m; }
        }

        #endregion
    }

    //A user of the interfaces. Only cares about ICar but knows implicitly about IWheel

    public class Stand
    {
        public Stand()
        {
            cars = new List<ICar>(2);
            cars.Add(new Toyota());
            cars.Add(new Toyota());
        }
        List<ICar> cars;

        public string ShowCars()
        {
            StringBuilder str = new StringBuilder();
            foreach (ICar iterCar in cars)
            {

                str.AppendLine(string.Format("car {0} with wheel {1}",
                    iterCar.name, iterCar.wheel.brand));
            }
            return str.ToString();
        }
    }

    //entry point. creates a stand and shows the cars, testing that properties are visible
    class Program
    {
        static void Main(string[] args)
        {
            Stand myLittleStand = new Stand();
            Console.WriteLine(myLittleStand.ShowCars());
        }
    }
}