在多个类中继承相同的接口时,是否在使用接口的实现更新所有类时没有问题?例如,如果我有一个由4个类实现的接口,将来可能会更多,如果我向接口添加任何方法,只有4个类中的一个实现,那么这不是一项繁琐的工作。并使用未实现的异常或其他东西实现所有其余类。?我知道你可能会质疑为什么我不能将这个方法添加到类本身,原因是我在这里使用了一个工厂并且我返回了这些类的一个对象的接口引用。关于如何采用这种方法的任何想法?对于这种情况,还有其他方法吗?
添加上述方案的示例代码
public interface ITest
{
string TestMethod1(string st, int ab);
int TestMethod2(string st);
void TestMethod4(int ab);
float ITest.TestMethod3(string st);
}
public class Class1 : ITest
{
public string TestMethod1(string st, int ab)
{
return string.Empty;
}
public void TestMethod4(int ab)
{
throw new NotImplementedException();
}
public int TestMethod2(string st)
{
throw new NotImplementedException();
}
public float TestMethod3(string st)
{
throw new NotImplementedException();
}
}
public class Class2 : ITest
{
float ITest.TestMethod3(string st)
{
return float.Parse("12.4");
}
void ITest.TestMethod4(int ab)
{
throw new NotImplementedException();
}
public string TestMethod1(string st, int ab)
{
throw new NotImplementedException();
}
public int TestMethod2(string st)
{
throw new NotImplementedException();
}
}
public class Main
{
ITest test = null;
public ITest CreateFactory(TestType testType)
{
switch(testType)
{
case TestType.Class1:
test = new Class1();
break;
case TestType.Class2:
test = new Class2();
break;
}
return test;
}
}
enum TestType
{
Class1,
Class2
}
答案 0 :(得分:4)
例如,如果我有一个由4个类实现的接口,将来可能会更多,如果我向接口添加任何方法,只有4个类中的一个实现,那么它是不是很乏味任务去实现所有其他类没有实现的异常或什么..?
界面是合约。如果您希望某些课程无法遵守合同,那么他们不应该声明他们这样做。实现简单抛出NotSupportedException
或NotImplementedException
的界面应该是最后的选择;通常有更好,更清洁的解决方案。
您的案例中的解决方案是简单地声明一个新界面:
public interface IFrobbable //legacy version
{
void Frob()
}
public interface IFrobbableOnSteroids: IFrobbable //the new and improved frobbable wonder
{
void MegaFrob();
}
您新改进的实施应该实施IFrobbableOnSteroids
。请注意,这个新接口实现了自己IFrobbable
;这意味着任何实现IFrobbableOnSteroids
的对象都可用于" legacy"代码(仅知道Frob
)和更新的代码(知道MegaFrob
)。这有一个很好的属性,你不会破坏现有的客户端代码。
当然你也可以简单地让新的更新类实现两个接口,但我个人更喜欢让一个接口包含另一个接口。
"传统"那些没有足够幸运可以改进的课程将保持简单和凡人IFrobbable
,但这应该是它的方式。如果你不是FrobbableInSteroids
,不要假装是一个人;正如我国所说的那样(免费翻译),"更容易抓住一个骗子而不是一个残废的"。
更新:
关于您关于工厂方法的问题,考虑到您的课程似乎是公开的,enum
没有真正的理由。只需使用泛型和类型本身:
public static T CreateFrobbable<T>()
where T: IFrobbable, new()
{
return new T();
}
public static T CreateFrobabbleOnSteroids<T>()
where T: IFrobbableOnSteroids, new()
{
return new T();
}
现在,如果我们有一个班级SomeFrobbable: IFrobbable
,您只需拨打CreateFrobbable<SomeFrobbable>()
即可创建一个班级。 SomeFrobbableOnSteroids: IFrobbableOnSteroids
可以创建为IFrobbable
CreateFrobbable<SomeFrobbableOnSteroids>()
,也可以创建IFrobbableOnSteroids
CreateFrobbableOnSteroids<SomeFrobbableOnSteroids>()
CreateFrobbableOnSteroids<SomeFrobbable>() //Compile time error
。你不能做什么,这是一件好事,是.forceY([min, max])
。
答案 1 :(得分:2)
对现有API进行更改非常繁琐,并且需要对API的现有客户端进行许多更改。但是,添加新成员会更容易,因为您可以简单地引入一个添加新功能的新界面:
interface ITheInterface
{
void DoSomething();
}
现在创建一个派生自现有界面的新界面:
interface ITheInterface2: ITheInterface
{
void DoSomething2();
}
一个常见的 - 但不是最好的 - 最常见的做法是在接口名称后面使用一个数字来表示其版本 - 这里2
并标记旧的Obsolete
以表示有更新的版。恕我直言,最好添加一些名称,说明新界面实际上做了什么,这就是新功能。
现在所有现有的类仍然可以实现ITheInterface
,而新的类实现新的接口。因此,您不需要更改现有代码,但如果实现新接口,则可以使用新成员。