Tor*_*eli 12 c# abstract-class interface c#-8.0 default-interface-member
我知道抽象类是一种无法实例化的特殊类.抽象类只是被分类(继承自).换句话说,它只允许其他类继承它但不能实例化.优点是它为所有子类强制执行某些层次结构.简单来说,它是一种强制所有子类进行相同层次结构或标准的契约.
我也知道An接口不是一个类.它是由Interface这个词定义的实体.接口没有实现; 它只有签名或换言之,只是没有正文的方法的定义.作为与Abstract类相似的一个,它是一个契约,用于为所有子类定义层次结构,或者它定义特定的方法集及其参数.它们之间的主要区别在于类可以实现多个接口,但只能从一个抽象类继承.由于C#不支持多重继承,因此接口用于实现多重继承.
当我们创建一个接口时,我们基本上创建了一组方法,没有必须被实现的类覆盖的任何实现.它的优点是它为类提供了一种方法,使其成为两个类的一部分:一个来自继承层次结构,另一个来自接口.
当我们创建一个抽象类时,我们正在创建一个可能有一个或多个已完成方法的基类,但至少有一个或多个方法未完成并被声明为abstract.如果抽象类的所有方法都未完成,那么它与接口相同.
但 但 但
我注意到我们将在C#8.0中使用默认接口方法
也许我问它因为我只有1 - 2年的编程经验,但现在抽象类和界面之间的主要区别是什么?
我知道我们不能在界面中建立状态,它们之间只有一个区别吗?
这里是不是有很多两个除了显而易见的事实,抽象类可以有状态,接口不能之间的差异.Java中实际上已经有一段时间可以使用默认方法或者也称为虚拟扩展方法.默认方法的主要驱动因素是接口演化,这意味着能够在未来版本中向接口添加方法,而不会破坏与该接口的现有实现的源或二进制兼容性.
这篇文章提到的另外两点好处:
首先,类和接口之间存在概念上的区别。
目前抽象类有时用于代码重用,即使没有“是”关系。这会污染 OO 设计。例如FerrariClass
继承自CarWithSteeringWheel
这个例子展示了一些好处。
您可以将一个(过度简化的)记录器接口描述如下:
interface ILogger
{
void LogWarning(string message);
void LogError(string message);
void Log(LogLevel level, string message);
}
Run Code Online (Sandbox Code Playgroud)
然后,该界面的用户可以使用LogWarning
和轻松记录警告和错误LogError
。但缺点是实现者必须实现所有方法。
一个更好的默认界面是:
interface ILogger
{
void LogWarning(string message) => Log(LogLevel.Warning, message);
void LogError(string message) => Log(LogLevel.Error, message);
void Log(LogLevel level, string message);
}
Run Code Online (Sandbox Code Playgroud)
现在用户仍然可以使用所有方法,但实现者只需要实现Log
. 此外,他可以实施LogWarning
和LogError
。
此外,将来您可能希望添加日志级别“灾难性”。在 C#8 之前,您无法在LogCatastrophic
不破坏所有当前实现的情况下将方法添加到 ILogger。
归档时间: |
|
查看次数: |
757 次 |
最近记录: |