是否有任何理由使用抽象类来定义类中的每个方法?
似乎抽象类意味着类的定义不完整,因此无法实例化。
我看到了一些简单的Java代码,它有一个抽象的类,定义了所有的方法。然后我想知道,为什么他们把它作为一个抽象类而不是一个真正的类?他们是否这样做,以便我们无法从这个抽象类实例化?或者他们从创建一个定义了所有内容的抽象类中获得其他好处?
似乎抽象类意味着类的定义不完整,因此无法实例化。
我看到了一些简单的Java代码,它有一个抽象的类,定义了所有的方法。然后我想知道,为什么他们把它作为一个抽象类而不是一个真正的类?他们是否这样做,以便我们无法从这个抽象类实例化?或者他们从创建一个定义了所有内容的抽象类中获得其他好处?
即使所有方法都有默认实现,这些实现在应用程序的上下文中实际上也没有意义。这些方法可能只做内部簿记,而实际有用的实现必须由一个派生类提供,该派生类执行它需要做的事情,然后调用超类方法。
但是,这只是猜测。您必须展示一个实际示例,以说明此设计的原因可能是什么。
举个例子,让我们看一个简单的游戏引擎。我的游戏中有很多不同的。GameObject
有些是可见的,所以我的基本类得到了一个方法。但是可能有一些不可见的对象,比如触发区域,它们根本不会显示出来,所以我在基类中将其实现为 no-op。draw()
有些人在与某物发生碰撞时会做一些事情,所以每个人都会得到一个方法。但是有些在它们像纯粹的视觉粒子效果一样碰撞时不会做任何事情,所以我在基类中也提供了一个no-op。collide(other)
有些人每次游戏都会做一些事情,所以他们得到了一种方法。但有些物体,如一堵墙,可能根本不会自己做任何事情。因此,我也为此提供了一个禁忌。update()
那么,当我有一个看不见的物体,它自己不做任何事情,也不与任何东西互动时,我该怎么办呢?没有理由在游戏中出现这种情况。所以我做了这个基础类。从理论上讲,你可以把它作为实例,因为所有的方法都有一个实现,但实际上你没有理由这样做,当你尝试时,你误解了我的游戏引擎是如何工作的。abstract
一个典型的用例是创建适配器类。想象一个回调接口,您可以在其中收到10个不同事件的通知,但通常只对其中一些事件感兴趣。使用适配器类,可以提供空实现,以便实际的回调只需要在扩展适配器后实现那些感兴趣的方法。通过使适配器抽象化,您可以表达这样一个事实,即实例化适配器本身是没有意义的,因为它没有任何用处。
从 Java 8 开始,您将不再实现这样的适配器,而是对接口使用默认方法。