为什么需要抽象类?

时间:2010-04-26 12:15:44

标签: c# abstract-class

  

可能重复:
  What is an abstract class ?

1.创建无法实例化的类有什么意义?

最常用作基类或接口(某些语言有单独的接口构造,有些没有) - 它不知道实现(由子类/实现类提供)< / p>

2.为什么有人想要这样的课?

For abstraction and re-use

3.抽象类变为NECESSARY的情况是什么?有人可以通过一个例子来简要介绍吗?

5 个答案:

答案 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
    如果您需要CarBicycle的单个祖先,则可能会创建一个Vehicle类。您无法启动此Vehicle课程,因为它未完成。 Vehicle本身不起作用。这就是为什么Vehicle将是抽象的。

  • 示例2
    .Net框架的另一个例子。 Stream类是一个提供基本I / O功能的抽象类。它提供了一个Read和Write方法来处理底层流的字节。

此流可以是FileStreamNetworkStreamMemoryStream,依此类推。 Stream本身不知道如何从流的具体实现中读取或写入。但是实现了Stream的一些方法,因为它们由流的所有实例共享。

这不可能与界面有关。所以你需要创建一个类。由于无法实现ReadWrite方法,因此Stream被标记为抽象。这将阻止按原样创建Stream类。

答案 3 :(得分:2)

抽象类绝不是绝对必要的。您始终可以使用非抽象类,并为方法提供存根,否则这些方法将是抽象的。您还可以通过仅为类提供受保护的构造函数来近似抽象的各个方面。

但不是这一点。当一个类用于对一组子类的广义属性和行为进行建模时,您希望将其标记为抽象以使您的意图清晰。

答案 4 :(得分:2)

我知道我需要在执行应用程序之间保存信息。

我大致知道我需要采用哪些方法来实现这一目标。我还可以提供几种方法来执行整个数据存储操作的各个部分。

我知道我的客户对数据存储有不同的要求,基于偏好(MS Sql,Oracle)和法律(健康行业安全要求)。

如何提供一个可以完成80%重物的物体,但最后20%的物品可以自定义?

抽象基类允许我们为每个客户定制最后20%但仍重用基类中80%的公共代码。此外,抽象类不会受到versioning issues that interfaces face的影响,这是一个奖励。

我可以编写我的应用程序代码,提供抽象基类的默认实现,测试并部署它,而不必为每个客户端提供不同的版本。当客户端请求不同的存储方法时,可以通过dependency injection在运行时提供和使用不同的实现。