1.什么是创建一个不能被实例化一个类的呢?
通常用作基类或接口(某些语言具有单独的接口构造,有些则不) - 它不知道实现(即由子类/实现类提供)
2.为什么会有人想要这样的班级?
For abstraction and re-use
3.什么是抽象类成为必要的情况?任何人都可以用一个例子来简要介绍一下吗?
1.什么是创建一个不能被实例化一个类的呢?
通常用作基类或接口(某些语言具有单独的接口构造,有些则不) - 它不知道实现(即由子类/实现类提供)
2.为什么会有人想要这样的班级?
For abstraction and re-use
3.什么是抽象类成为必要的情况?任何人都可以用一个例子来简要介绍一下吗?
抽象类允许您编写一段通用的代码,将特定决策推迟到派生类,从而减少代码重复。
@OtávioDécio:当基类不能为方法提供有意义的默认实现时必需? – bala3569 2010-04-26 12:26:34
@ bala3569:抽象基类*可以为方法(或大部分方法)提供有意义的默认实现。看到我的答案。 – 2010-04-26 12:28:57
当您创建一个继承树时,您可能需要抽象类,并且不能实例化一个单独的祖先,仅仅因为未知如何实现一些方法。
标记一个类为抽象告诉编译器有:
例1
如果你需要一个Car
和Bicycle
一个祖先,你可能会创建一个Vehicle
类。你不能启动这个Vehicle
类,因为它是未完成的。 A Vehicle
本身不起作用。这就是为什么Vehicle
将是抽象的。
实施例2
从.NET框架另一个实例。 Stream
类是提供基本I/O功能的抽象类。它提供了一个读写方法来处理下层流的字节。
该物流可以是FileStream
,NetworkStream
,MemoryStream
,等等。 Stream
本身不知道如何读取或写入流的具体实现。但是实现了Stream
的一些方法,因为它们被流的所有实例共享。
这是不可能与一个接口。所以你需要创建一个类。由于Read
和Write
方法无法执行,因此Stream
被标记为抽象。这将阻止Stream
类按原样创建。
抽象类绝不是必须的。你总是可以使用一个非抽象类,并为本来是抽象的方法提供存根。您也可以通过仅为受保护的构造函数提供类来近似抽象的方面。
但这不是重点。当一个类用于对一组子类的广义属性和行为进行建模时,您需要将其标记为抽象,以使您的意图清晰。
我知道我需要在执行应用程序的时间之间保存信息。
我大概知道我需要什么方法来完成这个。我也可以提供几种执行整个数据存储操作的各个部分的方法。
我知道我的客户根据偏好(MS Sql,Oracle)和法律(健康行业安全要求)对数据存储有不同的要求。
我该如何提供一个可以完成80%重物提升的对象,但最后的20%会自动定制?
抽象基类允许我们为每个客户自定义最后的20%,并重用基类中80%的通用代码。此外,抽象类不会受到versioning issues that interfaces face的影响,这是一项奖励。
我可以编写我的应用程序,提供抽象基类的默认实现,测试它并部署它,而不必为每个客户端拥有不同的版本。当客户请求不同的存储方法时,可以通过dependency injection在运行时提供和使用不同的实现。
这不是抽象类总是必要,但他们往往很方便。假设我想为特定类型的文本文件编写解析器。
// 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
-esque类需要。所有我需要为任何派生类做的只是重写一个抽象方法 - 而不是写所有处理流等乏味的东西,而且,我可以稍后轻松地添加功能 - 例如异常处理 - 它将适用于所有派生类。
这是一个愚蠢的愚蠢。 – slugster 2010-04-26 12:31:14