我从an MSDN article得到了以下声明。它说抽象类比接口有优势,因为可以改变抽象类来添加新成员。不改变抽象类真的会使从它继承的类不稳定吗?或者任何人都可以解释一下他们的观点是什么?
支持在接口上定义类。
在库的更高版本中,您可以安全地添加新成员 班;您无法在不中断的情况下向接口添加成员 现有代码。
答案 0 :(得分:5)
假设您有一个界面
public interface Animal
{
void Sleep();
}
您发布了库,并且发现需要在界面中添加属性。
public interface Animal
{
int Age{get;set;}
void Sleep();
}
每个人针对第一个版本的界面编写的所有代码都将不再编译强制升级。如果您使用此抽象类发布了第一个版本。
public abstract class Animal
{
public abstract void Sleep();
}
现在你需要添加另一个属性
public abstract class Animal
{
public virtual int Age{get;set;}
public abstract void Sleep();
}
在这种情况下,用户无需更改代码。
答案 1 :(得分:4)
假设您在第一个版本中编写代码并使用某个接口(IExample
)。在您的程序的第二个版本中,您了解IExample
应该有一个名为IExample.NewMethod
的方法。如果使用此方法扩展IExample
,则会自动删除之前编写的所有代码,因为从IExample
继承的所有类都不会完全实现此接口 - 因此代码将不会被编译。如果我们只讨论这个案子,这是正确的。使用从INewExample
继承的新接口(IExample
)或仅创建没有继承的新接口可以解决此问题
但是接口对抽象类也有一些优势。接口封装了代码的实现比抽象类更好。你也可以使用不同类的接口,但是当你使用抽象类时,它应该意味着你的类是某种抽象类(例如Circle
是Shape
所以你可以继承Circle
abstract Shape
)但是从Circle
继承Car
是非常糟糕的,即使它们具有相同的接口
要阅读界面VS抽象类的完整概述,我建议你Kent Beck's book和代码完成继承
答案 2 :(得分:4)
不要过于严格。通过接口编程(作为契约)实际上是解耦应用程序的最佳方法。例如,在界面周围创建包装器非常容易,而类甚至不需要使用单个虚拟方法。
此外,the article似乎甚至没有将abstract
类与接口进行比较(因为它仅在下一个"指南"中提及它们),但所有类都在一般的接口。所以,如果你问我,这是一个相当模糊的准则。
它可能仅对所述问题有意义:更改界面会破坏所有实现,而将成员添加到类中则不会。另一方面,如果你改变一个方法的签名,你也不会很幸运。从安全的角度来看,抽象类确实提供了一种方法来确保您的库始终向调用者公开其自己的功能,只允许在您需要的地方进行修改。使用接口,您可以传递几乎任何满足合同的代码。
答案 3 :(得分:0)
Abstract
类的最大优势是可能拥有Interface
不能拥有的内部成员。另一方面,您可以在interfaces
上使用多个继承,但不能在absrtact
个类上。
答案 4 :(得分:0)
抽象类的优点是可以实现常用功能。使用接口,每个实现类都必须提供自己定义的操作的实现。
答案 5 :(得分:0)
不改变抽象类真的会使从它继承的类不稳定吗?
不一定。只要您不将新成员标记为virtual
,任何当前不使用新成员的类都将能够忽略它们,因此没有版本控制中断。
或者任何人都可以解释一下他们的观点是什么?
关键是,如果向接口添加新成员,则实现该接口的任何类都会立即被破坏,因为它没有实现新成员。将成员添加到抽象类没有这样的构建中断。