我有一些关于抽象类/方法的基本问题。我知道抽象类的基本用途是为未来的类创建模板。但是它们还有其他用途吗?什么时候你应该更喜欢它们而不是接口,什么时候不喜欢?另外,抽象方法什么时候有用?
5 回答
我知道抽象类的基本用途是为未来的类创建模板。但是它们还有更多用途吗?
您不仅可以为子类定义模板,而且抽象类提供了额外的好处,即允许您定义子类以后可以使用的功能。
您无法在 Java 8 之前的接口中提供默认方法实现。
什么时候你应该更喜欢它们而不是接口,什么时候不喜欢?
如果您想为您的孩子提供实现细节但又不想让您的类的实例被直接实例化(这允许您部分定义一个类),那么抽象类非常适合。
如果您想简单地为要遵循的对象定义合同,请使用接口。
抽象方法什么时候有用?
抽象方法的用处与在接口中定义方法的用处相同。这是抽象类的设计者说“我的任何孩子都必须实现这个方法”的一种方式。
抽象类
–> 当您的基类应提供某些方法的默认实现而其他方法应开放以被子类覆盖时,请使用抽象类。
例如,再次以上面的 Vehicle 类为例。如果我们希望从 Vehicle 派生的所有类都以固定方式实现 Drive() 方法,而其他方法可以被子类覆盖。在这种情况下,我们将 Vehicle 类实现为具有 Drive 实现的抽象类,而将其他方法/属性保留为抽象类,以便它们可以被子类覆盖。
–> 抽象类的目的是提供一个基类的通用定义,多个派生类可以共享。
例如,类库可以定义一个抽象类,用作其许多函数的参数,并要求使用该库的程序员通过创建派生类来提供他们自己的类实现。
使用抽象类
当创建一个将被广泛分发或重用的类库时——尤其是对客户端,使用抽象类而不是接口;因为,它简化了版本控制。这是开发基类库的 Microsoft 团队使用的做法。(COM 是围绕接口设计的。)使用抽象类为一系列类型定义公共基类。使用抽象类来提供默认行为。仅子类化该类在逻辑上属于的层次结构中的基类。
在非常高的水平上:
任何类型的抽象都归结为分离关注点。抽象的“客户”代码并不关心抽象所暴露的合约是如何实现的。例如,您通常不关心字符串类是否使用空终止或缓冲区长度跟踪的内部存储实现。封装隐藏了细节,但通过制作类/方法/等。抽象,您允许更改实现或添加新实现而不影响客户端代码。
当一个类提供一些高级功能但遗漏了某些细节以由派生类实现时,通常使用抽象类/方法。使类/方法抽象确保它不能单独使用,但必须专门用于定义高级实现中遗漏的细节。这最常与模板方法模式一起使用:
通常使用抽象类来提供一些不完整的功能,这些功能将由具体的子类来充实。它可以提供其子类使用的方法;它也可以表示类层次结构中的中间节点,以表示具体子类的公共分组,以某种方式将它们与其超类的其他子类区分开来。由于接口不能从类派生,这是另一种需要类(抽象或其他)而不是接口的情况。
一个好的经验法则是,只有类层次结构的叶节点才应该被实例化。使非叶节点抽象是确保这一点的简单方法。