1.创建无法实例化的类有什么意义?
最常用作基类或接口(某些语言有单独的接口构造,有些没有) - 它不知道实现(由子类/实现类提供)< / p>
2.为什么有人想要这样的课?
For abstraction and re-use
3.抽象类变为NECESSARY的情况是什么?有人可以通过一个例子来简要介绍吗?
答案 0 :(得分:6)
抽象类并不总是必要,但它们通常非常方便。假设我想为特定类型的文本文件编写解析器。
// hasty code, might be written poorly
public abstract class FileParser<T> {
private readonly List<T> _contents;
public IEnumerable<T> Contents {
get { return _contents.AsReadOnly(); }
}
protected FileParser() {
_contents = new List<T>();
}
public void ReadFile(string path) {
if (!File.Exists(path))
return;
using (var reader = new StreamReader(path)) {
while (!reader.EndOfStream) {
T value;
if (TryParseLine(reader.ReadLine(), out value))
_contents.Add(value);
}
}
}
protected abstract bool TryParseLine(string text, out T value);
}
在抛出类似上面的内容之后,我已经完成了任何FileParser
- 样式类所需的样板代码。我需要为任何派生类做的只是覆盖一个抽象方法 - TryParseLine
- 而不是编写处理流等的所有相同的繁琐内容。此外,我可以在以后轻松添加功能 - - 例如异常处理 - 它将适用于所有派生类。
答案 1 :(得分:5)
抽象类允许您编写一段通用代码,将特定决策推迟到派生类,从而减少代码重复。
答案 2 :(得分:4)
您(可能)在创建继承树时需要抽象类,其中一个祖先无法实例化,只是因为不知道如何实现某些方法。
将类标记为抽象是告诉编译器:
示例1
如果您需要Car
和Bicycle
的单个祖先,则可能会创建一个Vehicle
类。您无法启动此Vehicle
课程,因为它未完成。 Vehicle
本身不起作用。这就是为什么Vehicle
将是抽象的。
示例2
.Net框架的另一个例子。 Stream
类是一个提供基本I / O功能的抽象类。它提供了一个Read和Write方法来处理底层流的字节。
此流可以是FileStream
,NetworkStream
,MemoryStream
,依此类推。 Stream
本身不知道如何从流的具体实现中读取或写入。但是实现了Stream
的一些方法,因为它们由流的所有实例共享。
这不可能与界面有关。所以你需要创建一个类。由于无法实现Read
和Write
方法,因此Stream
被标记为抽象。这将阻止按原样创建Stream
类。
答案 3 :(得分:2)
抽象类绝不是绝对必要的。您始终可以使用非抽象类,并为方法提供存根,否则这些方法将是抽象的。您还可以通过仅为类提供受保护的构造函数来近似抽象的各个方面。
但不是这一点。当一个类用于对一组子类的广义属性和行为进行建模时,您希望将其标记为抽象以使您的意图清晰。
答案 4 :(得分:2)
我知道我需要在执行应用程序之间保存信息。
我大致知道我需要采用哪些方法来实现这一目标。我还可以提供几种方法来执行整个数据存储操作的各个部分。
我知道我的客户对数据存储有不同的要求,基于偏好(MS Sql,Oracle)和法律(健康行业安全要求)。
如何提供一个可以完成80%重物的物体,但最后20%的物品可以自定义?
抽象基类允许我们为每个客户定制最后20%但仍重用基类中80%的公共代码。此外,抽象类不会受到versioning issues that interfaces face的影响,这是一个奖励。
我可以编写我的应用程序代码,提供抽象基类的默认实现,测试并部署它,而不必为每个客户端提供不同的版本。当客户端请求不同的存储方法时,可以通过dependency injection在运行时提供和使用不同的实现。