我知道并阅读有关抽象类和接口的内容,但我从未理解的一点是,无法实例化的类的用法是什么.我可以使用普通类和虚方法而不是抽象类吗?当我实例化基类时会发生什么?
cdh*_*wie 19
当您在派生类之间共享一些常用功能时,通常使用抽象类.也就是说,您不能使用接口,因为您想提供一些默认功能.
看看System.IO.Stream课程.此类提供了一些常见的基本功能,但要求特定类型的流实现某些成员才能使其正常运行.这些成员也被标记abstract,这向编译器和运行时指示没有合适的基类实现.派生抽象类的非抽象类必须覆盖所有继承的抽象成员,就像实现接口的类必须实现接口上定义的所有成员一样.
在流示例中,该Read()方法是抽象的,但该ReadByte()方法不是 - 因为ReadByte()可以通过调用来实现Read().(虽然不是最佳的,这就是ReadByte()虚拟的原因,因此可以选择性地提供更有效的实现.)虚拟成员是不同的,因为它们确实有一个实现,但可以选择被覆盖.默认情况下,抽象成员没有实现,必须重写.
换句话说,抽象类上的方法可以使用类上的其他抽象成员,即使它们没有实现!这是因为,派生非抽象类是所需的,以提供一个实现-一个实现保证在该方法将被调用的点存在.这类似于如何使用接口的成员,即使成员在接口上没有实现,因为它保证实现接口的对象必须实现其所有成员.
子类喜欢MemoryStream并FileStream覆盖所有抽象方法以形成具体类,并且可以实例化它们.但是,您可以将它们存储在Stream引用变量中,并将它们视为通用的"黑盒子"流.这允许您声明一个接受Stream对象的方法,而您不必关心它实际上是什么类型的流.
Stream foo = new Stream(); // Invalid, Stream is abstract.
Stream foo = new MemoryStream(); // Valid.
Run Code Online (Sandbox Code Playgroud)
所以,现在总结一下你在标题中提出的问题的答案.抽象类无法实例化,因为它可能包含抽象且没有实现的成员.抽象类的使用是双重的:首先,要进行子类化,并允许子类共享某些成员的公共实现,其次,允许通过对抽象类的引用来使用子类的任何对象的实例.
| 归档时间: |
|
| 查看次数: |
15786 次 |
| 最近记录: |