为什么Java API中的许多方法都有“抽象”修饰符?

问题描述:

学生水平的问题,我希望计算器可以帮助我更深刻地理解这里:为什么Java API中的许多方法都有“抽象”修饰符?

我注意到,许多Java API中的方法(如那些在Graphics2D,例如)具有“抽象“修饰符。为什么是这样?

现在我只是围绕着继承和多态来包装我的头,但据我了解,抽象类被用作一种由子类扩展的“父类”,而且抽象类本身不能实例化。我也明白抽象方法是在抽象类中声明(但没有实现),并且据推测必须在该子类的子类中实现,以便被认为是非抽象的(并且因此是可实例化的)。

那么,我怎样才能导入像Graphics2D这样的类,创建它的一个实例并使用它的抽象方法?

我的老师提到了一些关于在运行时(?)被覆盖的方法,但我不明白如何/为什么。很明显,我在这里错过了一些东西,我很想知道更多。

那么,我怎么能够导入像Graphics2D这样的类,创建它的一个实例并使用它的抽象方法呢?

因为你从来没有创建的Graphics2D直接一个实例。看看你的代码 - 你不会找到这个:

Graphics2D graphics = new Graphics2D(); // This wouldn't compile 

...任何地方。相反,您会发现调用方法返回 a Graphics2D,它实际上是返回对具体子类实例的引用。或者,也许你会提供接受呼叫者提供的GraphicsGraphics2D参数的方法......并且呼叫者可能了解具体的类别,或者他们也可能已从别处获得了参考。

在某些方面,这就是整个观点 - 事实上,你甚至想知道这些子类的位置是否证明整个工作的效果如何......你只需要处理Graphics2D,但实现内容这可以通过平台不同等

当你的教练在谈论被覆盖的方法,我怀疑他们居然说覆盖 - 其中一个子类可以提供更具体的实施方法的比超类,或甚可以提供一个超类只有抽象方法声明的地方。

+0

很好的答复,谢谢。很有意义的是,有些方法正在返回具体的,非抽象的子类的实例,但是您的意思是“调用者可能知道关于具体类的**”。 对抽象超类的存在的简单知识有何帮助?或者,你是否暗示对“认识”有不同的解释? – b1skit

+1

调用者可能知道concerete类,因为它是例如graphicssubsystem。它基本上构建并传递了具体的类,但是只能抽象地访问它。这非常像一个接口。 (区别仅在于实现者) – eckes

这是为了保持实现与定义分离;类似于C/C++头文件。

让我们考虑一下我们在Java中使用的一些基本类,比如InputStream。我们知道我们需要一种阅读方式,所以我们定义了几个适当的抽象方法,但尚未实际实现。

这对我们有利,因为如果一个类继承自InputStream,我们知道它将实现我们原来定义的读取方法。通常这些实现不同于子类的sublcass。例如,让我们考虑InputStream的几个子类别,如GZIPInputStreamFileInputStreamGZIPInputStream将不得不在其读取调用中解压缩字节。 FileInputStream只需要从其构造函数中传递的文件中读取字节。你可以看到这是怎么回事。