4

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

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

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

所以为了简化:一辆车有一个轮子,一个轮子有一个轮辋。(无法弥补其他更好的例子,对不起)。

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

所以我做了这样的事情(在 C# 中):

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

而且我有一个错误,我不能在接口实现中拥有字段。所以这让我开始觉得可能是错误的界面设计。我想强制接口实现来实现这种层次结构。但也许根据设计模式和最佳实践,它应该以其他方式完成?

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

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

4

6 回答 6

10

在你的接口中,你必须明确 Wheels 应该是 ICar 的一个属性,因为你不能声明接口实现应该有哪些字段。(字段是内部工作,所以界面不应该知道它)。

interface ICar
{
    IWheels Wheels
    {
       get;
    }
}
于 2009-06-26T13:38:59.277 回答
7

你不能在接口中指定一个字段(你不应该能够——这是一个实现决定),但你可以指定一个属性

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”接口也是可以的。)

于 2009-06-26T13:39:35.783 回答
4

正如错误所说,您无法在界面中指定字段。您可以指定属性:

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

interface IWheels
{
    IRims Rim { get; set; }
}
于 2009-06-26T13:39:29.073 回答
4

You can't declare fields, but you can declare properties. That will have the same end effect of forcing a particular class to provide an instance of another class.

ICar
{
  IWheels Wheel { get; set; }
}
IWheels
{
  IRims Rim { get; set; }
}
于 2009-06-26T13:39:40.353 回答
0

I'm not so much used to C# but it sounds to me that you can force that implementation by making Abstract classes, with the fields you want to use. So if you extend those abstract classes you will have the fields in them available. You'll have to make an abstract class AND an interface though...

于 2009-06-26T13:50:07.697 回答
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());
        }
    }
}
于 2009-06-26T14:01:36.363 回答