c# - 为什么不能实例化抽象类,不能实例化的类有什么用

标签 c# oop

我知道并阅读过抽象类和接口(interface),但我一直不明白的一点是,无法实例化的类有什么用。 我可以使用普通类和虚方法代替抽象类吗? 当我实例化基类时会发生什么?

最佳答案

当您有一组公共(public)功能要在派生类之间共享时,您通常会使用抽象类。也就是说,您不能因为要提供一些默认功能而使用接口(interface)。

看看 System.IO.Stream类(class)。此类提供了一些通用的基本功能,但需要特定类型的流实现某些成员才能发挥作用。这些成员也被标记为 abstract,这向编译器和运行时表明没有合适的基类实现。派生抽象类的非抽象类必须覆盖所有继承的抽象成员,就像实现接口(interface)的类必须实现接口(interface)上定义的所有成员一样。

在流示例中,Read()方法是抽象的,但是 ReadByte()方法不是——因为 ReadByte() 可以根据对 Read() 的调用来实现。 (尽管不是最优的,这就是为什么 ReadByte() 是虚拟的,因此可以选择提供更有效的实现。)虚拟成员不同,因为它们确实实现,但可以选择被覆盖。默认情况下,抽象成员没有实现,并且必须被覆盖。

换句话说,抽象类的方法可以使用该类的其他抽象成员,即使它们没有实现!这是因为派生的非抽象类需要 来提供实现——在调用方法时保证存在一个实现。这类似于您如何使用接口(interface)的成员,即使这些成员在接口(interface)上没有实现,因为它保证实现接口(interface)的对象必须实现其所有成员。

MemoryStream 这样的子类和 FileStream覆盖所有的抽象方法,形成一个具体的类,并且可以实例化它们。但是,您可以将它们存储在 Stream 引用变量中,并将它们视为通用的“黑盒”流。这允许您声明一个接受 Stream 对象的方法,并且您不必关心它实际上是什么类型的流。

Stream foo = new Stream();       // Invalid, Stream is abstract.
Stream foo = new MemoryStream(); // Valid.

那么,现在总结一下您在标题中提出的问题的答案。抽象类不能被实例化,因为它可能包含抽象的成员并且没有实现。抽象类的使用有两个方面:首先,被子类化并允许子类共享某些成员的公共(public)实现;其次,允许通过对抽象类的引用来使用子类的任何对象的实例。

关于c# - 为什么不能实例化抽象类,不能实例化的类有什么用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16342494/

相关文章:

c# - 需要 Windows chmod777 等效项

java - 如何按实例计算方法调用

java - MVC模式;我的模型类需要用户输入,但我知道它不应该询问用户或 Controller

java - 如何在不编写已经很简单的方法的情况下简化类?

java - 如何确保实用静态方法的线程安全?

C# 泛型转换

c# - MSSQL 快速更新

javascript - 在 Asp.Net MVC Razor 中将 HTML View 作为电子邮件附件发送

c# - 使用 Swagger 的 Web API MVC5 不会使用带有 header 的 "Try it out!"调用 API

c# - 使用一些默认值构建 XML 的最佳方法