继承是面向对象编程 (OOP) 语言(如 Java)的主要功能之一。它是一种以增强软件设计中类重用能力的方式组织类的基本技术。多重继承是众多继承类型中的一种,是继承机制的一个重要原则。本文探讨了一般继承的一些概念以及 Java 中多重继承的复杂性。
概述
继承创建了子类的层次结构,其中子类扩展了父类的功能。这样做不仅是为了继承超类的能力,也是为了被继承的类赋予新的意义。这种能力的扩展通常是通过覆盖超类的功能、添加新的方法和属性来完成的。在 Java 中,可以从超类派生的子类的数量没有实际限制。但是,层次结构必须遵循线性方式。
因此,在创建子类时,我们不是声明所有新的类成员,而是指定它使用现有类的成员。现有类称为超类,新类称为子类,其中每个子类都可以在继承层次结构中进一步扩展成为超类。
Java中的多级单继承
Java 支持单一继承,其中每个类都派生自一个直接超类。每个派生的子类都有可能成为未来子类的超类。在单级继承中,子类继承父类的属性。我们还可以从单个父类创建多个子类,这些子类进一步可能是另一个父类的子类。因此,多级单继承本质上意味着我们可以将单级类层次的思想扩展到多级。
多重继承
Java 不支持多重继承。多重继承是指从多个直接超类派生的类。这增加了类之间关系的复杂性和模糊性。如果我们考虑在函数覆盖中发生的事情,这个问题就很明显了。假设有两个类,A 和 B,每个类都定义了一个名为 func() 的函数。现在,假设我们定义了另一个类 C,它继承自 A 和 B(多重继承),但是假设这个类没有覆盖名为 func() 的函数。
接口的多重继承
尽管 Java 不允许多重继承,但它允许接口的多重实现。所以,在某种程度上,这个想法仍然存在。现在,什么是接口?
接口描述了一组方法,但不为所有方法提供任何具体的实现。我们可以借助提供方法具体实现的类来实现接口。这样,一个类可以实现多个接口,因此可以提供从一个或多个接口派生的方法的具体实现。实现一个或多个接口的类与接口类型形成一种is-a关系。这也意味着从类实例化的对象保证提供接口声明的功能。从此类派生的任何子类也提供相同的功能。
接口对于为许多可能不相关的类提供通用功能特别有用。因此,实现相同接口的类的对象可以响应所有接口中描述的方法调用。
从 Java 8 开始,接口通过其完整实现支持默认方法。众所周知,一个类可以实现多个接口;因此,如果多个接口包含具有相同方法签名的默认方法,则实现的类应指定要使用或覆盖的特定方法。
结论
多重继承的经典问题之一称为菱形问题。这可以通过称为虚拟继承的继承机制来解决。但是,经验表明,Java 并没有因为完全禁止多重继承而损失太多。事实上,Java 编译器已经摆脱了它们,它为我们可以轻松解决的问题提供了一个复杂的解决方案。尽管如此,仍然有支持它的 OOP 语言,例如 C++。