我正在为新项目编写接口,并希望得到一些建议。
我有一个具有子类的类,它有一个子类。这个类的树是这样的:
Class Car
{
Wheels Wheel;
}
Class Wheels
{
Rims Rim;
}
简化:一辆车有一个轮子,一个轮子有一个轮圈。 (不能弥补其他更好的例子,对不起)。
所以我想在我的ICar,IWheels和IRims的接口实现中强制使用这个层次结构。
所以我做了类似的事(在C#中):
ICar
{
IWheels Wheel;
}
IWheels
{
IRims Rim;
}
我有一个错误,我不能在接口实现中有字段。所以这开始我的事情可能是错误的界面设计。我想强制接口实现来实现这种层次结构。但是也许可以按照设计模式和最佳实践来进行其他方式吗?
您能告诉我如何设计我的系统,以便强制对象实现这种层次结构吗?
也许在我的问题中有一些不准确的东西,或者我遗漏了一些重要的信息。如果是,请在评论中提问。
答案 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());
}
}
}