为什么抽象类不能被实例化,什么是无法实例化的类的使用

use*_*166 4 c# oop

我知道并阅读有关抽象类和接口的内容,但我从未理解的一点是,无法实例化的类的用法是什么.我可以使用普通类和虚方法而不是抽象类吗?当我实例化基类时会发生什么?

cdh*_*wie 19

当您在派生类之间共享一些常用功能时,通常使用抽象类.也就是说,您不能使用接口,因为您想提供一些默认功能.

看看System.IO.Stream课程.此类提供了一些常见的基本功能,但要求特定类型的流实现某些成员才能使其正常运行.这些成员也被标记abstract,这向编译器和运行时指示没有合适的基类实现.派生抽象类的非抽象类必须覆盖所有继承的抽象成员,就像实现接口的类必须实现接口上定义的所有成员一样.

在流示例中,该Read()方法是抽象的,但该ReadByte()方法不是 - 因为ReadByte()可以通过调用来实现Read().(虽然不是最佳的,这就是ReadByte()虚拟的原因,因此可以选择性地提供更有效的实现.)虚拟成员是不同的,因为它们确实有一个实现,但可以选择被覆盖.默认情况下,抽象成员没有实现,必须重写.

换句话说,抽象类上的方法可以使用类上的其他抽象成员,即使它们没有实现!这是因为,派生非抽象类是所需的,以提供一个实现-一个实现保证在该方法将被调用的点存在.这类似于如何使用接口的成员,即使成员在接口上没有实现,因为它保证实现接口的对象必须实现其所有成员.

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

Stream foo = new Stream();       // Invalid, Stream is abstract.
Stream foo = new MemoryStream(); // Valid.
Run Code Online (Sandbox Code Playgroud)

所以,现在总结一下你在标题中提出的问题的答案.抽象类无法实例化,因为它可能包含抽象且没有实现的成员.抽象类的使用是双重的:首先,要进行子类化,并允许子类共享某些成员的公共实现,其次,允许通过对抽象类的引用来使用子类的任何对象的实例.

  • @ user1681166因为流只是一个概念.这是产生或消耗字节的东西.流没有"默认实现".从中读取时,字节来自何处?当你写它时,字节在哪里?有几种流的实现由文件,内存或网络套接字支持.但是没有"只是简单的流".它始终是一些*类型的流.Stream类实现了所有流中通用的东西. (2认同)