热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中类多继承的实现方法与限制-ImplementingMultipleInheritanceinJava:MethodsandLimitations

在Java中,一个类可以实现多个接口,但是否能够继承多个类则存在限制。本文探讨了Java中实现多继承的方法及其局限性,详细分析了通过接口、抽象类和组合等技术手段来模拟多继承的策略,并讨论了这些方法的优势和潜在问题。

I know that a class can implement more than one interface, but is it possible to extend more than one class? For example I want my class to extend both TransformGroup and a class I created. Is this possible in Java? Both statements class X extends TransformGroup extends Y and class X extends TransformGroup, Y receive an error. And if it is not possible, why? TransformGroup extends Group but I guess it also extends Node since it inherits fields from Node and it can be passed where a Node object is required. Also, like all classes in Java, they extend Object class. So why wouldn't it be possible to extend with more than one class?

我知道一个类可以实现多个接口,但是否可能扩展多个类?例如,我希望我的类同时扩展TransformGroup和我创建的类。这在Java中可能吗?两个语句类X扩展TransformGroup扩展Y和类X扩展TransformGroup, Y收到错误。如果不可能,为什么呢?TransformGroup扩展了Group,但我猜它也扩展了Node,因为它从Node继承了字段,可以在需要节点对象的地方传递。同样,与Java中的所有类一样,它们扩展了对象类。那么为什么不可能扩展到多个类呢?

TransformGroup inheritance

TransformGroup继承

So, if that is possible, what is the proper way to do it? And if not, why and how should I solve the problem?

那么,如果这是可能的,那么正确的做法是什么呢?如果没有,为什么我应该,如何解决这个问题?

11 个解决方案

#1


50  

In Java multiple inheritance is not permitted. It was excluded from the language as a design decision, primarily to avoid circular dependencies.

在Java中,多重继承是不允许的。作为设计决策,它被排除在语言之外,主要是为了避免循环依赖。

Scenario1: As you have learned the following is not possible in Java:

场景1:您已经了解到Java中不可能出现以下情况:

public class Dog extends Animal, Canine{

}

Scenario 2: However the following is possible:

场景2:但是有以下可能:

public class Canine extends Animal{

}

public class Dog extends Canine{

}

The difference in these two approaches is that in the second approach there is a clearly defined parent or super class, while in the first approach the super class is ambiguous.

这两种方法的不同之处在于,在第二种方法中有一个明确定义的父类或超类,而在第一种方法中,超类是不明确的。

Consider if both Animal and Canine had a method drink(). Under the first scenario which parent method would be called if we called Dog.drink()? Under the second scenario, we know calling Dog.drink() would call the Canine classes drink method as long as Dog had not overridden it.

考虑一下如果动物和狗都有方法饮料()。在第一个场景中,如果我们调用Dog.drink(),会调用哪个父方法?在第二种情况下,我们知道调用Dog.drink()会调用犬科类的drink方法,前提是狗没有重写它。

#2


4  

No it is not possible in java (Maybe in java 8 it will be avilable). Except the case when you extend in a tree. For example:

不,这在java中是不可能的(也许在java 8中是可以实现的)。除非你把它延伸到一棵树上。例如:

class A
class B extends A
class C extends B

#3


4  

In Java multiple inheritance is not permitted for implementations (classes) only for interfaces:

在Java多重继承中,实现(类)不允许仅用于接口:

interface A extends B, C

E.g. MouseInputListener extends MouseListener and MouseMotionListener

MouseInputListener扩展了MouseListener和MouseMotionListener

And, of course, a class can implement several interfaces:

当然,一个类可以实现几个接口:

class X implements A, F

#4


3  

Multiple inheritance is not possible with class, you can achieve it with the help of interface but not with class. It is by design of java language. Look a comment by James gosling.

对于类来说,多重继承是不可能的,你可以通过接口而不是类来实现。它是由java语言设计的。看看詹姆斯·高斯林的评论。

by James Gosling in February 1995 gives an idea on why multiple inheritance is not supported in Java.

作者James Gosling在1995年2月提出了为什么Java不支持多重继承的想法。

JAVA omits many rarely used, poorly understood, confusing features of C++ that in our experience bring more grief than benefit. This primarily consists of operator overloading (although it does have method overloading), multiple inheritance, and extensive automatic coercions.

JAVA省略了许多很少使用、理解不透彻、令人困惑的c++特性,在我们的经验中,这些特性带来的痛苦多于益处。这主要包括操作符重载(尽管它有方法重载)、多重继承和广泛的自动强制。

#5


3  

There is no concept of multiple inheritance in Java. Only multiple interfaces can be implemented.

在Java中没有多重继承的概念。只能实现多个接口。

#6


3  

Multiple Inheritance http://bit.ly/1Z62XjI

多重继承http://bit.ly/1Z62XjI

Assume B and C are overriding inherited method and their own implementation. Now D inherits both B & C using multiple inheritance. D should inherit the overridden method.The Question is which overridden method will be used? Will it be from B or C? Here we have an ambiguity. To exclude such situation multiple inheritance was not used in Java.

假设B和C是重写继承方法和它们自己的实现。现在D使用多重继承继承继承来继承B和C。D应该继承重写的方法。问题是使用哪个重写的方法?是B还是C?这里我们有一个模棱两可的地方。为了排除这种情况,Java中不使用多重继承。

#7


2  

Java didn't provide multiple inheritance.
When you say A extends B then it means that A extends B and B extends Object.
It doesn't mean A extends B, Object.

Java没有提供多重继承。当你说A扩展B那么它意味着A扩展B和B扩展对象。它并不意味着A扩展了B,对象。

class A extends Object
class B extends A

类A扩展对象类B扩展对象A

#8


2  

java can not support multiple inheritence.but u can do this in this way

java不能支持多重继承。但是你可以这样做

class X
{
}
class Y extends X
{
}
class Z extends Y{
}

#9


0  

Java does not allow extending multiple classes.

Java不允许扩展多个类。

Let's assume C class is extending A and B classes. Then if suppose A and B classes have method with same name(Ex: method1()). Consider the code:

假设C类扩展了A类和B类。如果假设A和B类有相同名称的方法(Ex: method1())。考虑一下代码:

C obj1 = new C(); obj1.method1(); - here JVM will not understand to which method it need to access. Because both A and B classes have this method. So we are putting JVM in dilemma, so that is the reason why multiple inheritance is removed from Java. And as said implementing multiple classes will resolve this issue.

C obj1 =新C();obj1.method1();-这里JVM不理解需要访问哪个方法。因为A类和B类都有这个方法。因此,我们将JVM置于进退两难的境地,这就是从Java中删除多重继承的原因。如前所述,实现多个类将解决这个问题。

Hope this has helped.

希望这个有帮助。

#10


0  

Hello please note like real work.

你好,请注意真正的工作。

Children can not have two mother

孩子不能有两个母亲

So in java, subclass can not have two parent class.

在java中,子类不能有两个父类。

#11


0  

Most of the answers given seem to assume that all the classes we are looking to inherit from are defined by us.

给出的大多数答案似乎都假设我们要继承的所有类都是由我们定义的。

But what if one of the classes is not defined by us, i.e. we cannot change what one of those classes inherits from and therefore cannot make use of the accepted answer, what happens then?

但是,如果其中一个类不是由我们定义的,比如我们不能改变其中一个类继承的内容,因此不能使用已接受的答案,那么会发生什么呢?

Well the answer depends on if we have at least one of the classes having been defined by us. i.e. there exists a class A among the list of classes we would like to inherit from, where A is created by us.

答案取决于我们是否至少有一个类是由我们定义的。也就是说,在我们想要继承的类列表中存在一个类a,其中a是我们创建的。

In addition to the already accepted answer, I propose 3 more instances of this multiple inheritance problem and possible solutions to each.

除了已经接受的答案之外,我还提出了3个多继承问题的实例和每个可能的解决方案。

Inheritance type 1

Ok say you want a class C to extend classes, A and B, where B is a class defined somewhere else, but A is defined by us. What we can do with this is to turn A into an interface then, class C can implement A while extending B.

假设你想要一个类C来扩展类,a和B,其中B是一个定义在其他地方的类,而a是由我们定义的。我们能做的就是把A变成一个接口,那么C类就可以在扩展B的同时实现A。

class A {}
class B {} // Some external class
class C {}

Turns into

变成

interface A {}
class AImpl implements A {}
class B {} // Some external class
class C extends B implements A

Inheritance type 2

Now say you have more than two classes to inherit from, well the same idea still holds - all but one of the classes has to be defined by us. So say we want class A to inherit from the following classes, B, C, ... X where X is a class which is external to us, i.e. defined somewhere else. We apply the same idea of turning all the other classes but the last into an interface then we can have:

现在假设你有两个以上的类要继承,同样的想法仍然存在——除了一个类之外,所有的类都必须由我们定义。假设我们想要A类从以下类继承,B C。X是一个外部的类,即定义在其他地方。我们将所有其他类(最后一个类)转化为接口的想法是一样的,我们可以:

interface B {}
class BImpl implements B {}
interface C {}
class CImpl implements C {}
...
class X {}
class A extends X implements B, C, ...

Inheritance type 3

Finally, there is also the case where you have just a bunch of classes to inherit from, but none of them are defined by you. This is a bit trickier, but it is doable by making use of delegation. Delegation allows a class A to pretend to be some other class B but any calls on A to some public method defined in B, actually delegates that call to an object of type B and the result is returned. This makes class A what I would call a Fat class

最后,还有一种情况,您只需要继承一堆类,但没有一个类是由您定义的。这有点棘手,但利用委托是可行的。委托允许一个类a伪装成另一个类B,但是任何对a调用在B中定义的某个公共方法的调用,实际上是委托那些调用类型B的对象的调用,然后返回结果。这就形成了A类,我称之为肥胖类

How does this help?

这将如何帮助?

Well it's simple. You create an interface which specifies the public methods within the external classes which you would like to make use of, as well as methods within the new class you are creating, then you have your new class implement that interface. That may have sounded confusing, so let me explain better.

这是简单的。您将创建一个接口,该接口指定您想要使用的外部类中的公共方法,以及您正在创建的新类中的方法,然后您的新类将实现该接口。这听起来可能让人困惑,所以让我更好地解释一下。

Initially we have the following external classes B, C, D, ..., X, and we want our new class A to inherit from all those classes.

一开始我们有以下的外部类B, C, D,…我们希望我们的新类A从所有这些类中继承。

class B {
    public void foo() {}
}

class C {
    public void bar() {}
}

class D {
    public void fooFoo() {}
}

...

class X {
    public String fooBar() {}
}

Next we create an interface A which exposes the public methods that were previously in class A as well as the public methods from the above classes

接下来,我们创建一个接口A,它公开以前在类A中的公共方法以及来自上面类的公共方法

interface A {
    void doSomething(); // previously defined in A
    String fooBar(); // from class X
    void fooFoo(); // from class D
    void bar(); // from class C
    void foo(); // from class B
}

Finally, we create a class AImpl which implements the interface A.

最后,我们创建了一个实现接口a的类AImpl。

class AImpl implements A {
    // It needs instances of the other classes, so those should be
    // part of the constructor
    public AImpl(B b, C c, D d, X x) {}
    ... // define the methods within the interface
}

And there you have it! This is sort of pseudo-inheritance because an object of type A is not a strict descendant of any of the external classes we started with but rather exposes an interface which defines the same methods as in those classes.

就这样!这是一种伪继承,因为A类型的对象不是我们刚开始的任何外部类的严格继承,而是公开了一个接口,该接口定义了与这些类相同的方法。

You might ask, why we didn't just create a class that defines the methods we would like to make use of, rather than defining an interface. i.e. why didn't we just have a class A which contains the public methods from the classes we would like to inherit from? This is done in order to reduce coupling. We don't want to have classes that use A to have to depend too much on class A (because classes tend to change a lot), but rather to rely on the promise given within the interface A.

您可能会问,为什么我们不创建一个类来定义我们想要使用的方法,而不是定义接口。例如,为什么我们没有一个类a包含我们想要继承的类的公共方法?这样做是为了减少耦合。我们不希望使用A的类必须过分依赖类A(因为类往往变化很大),而希望依赖于在接口A中给出的承诺。


推荐阅读
  • 探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 本文探讨了如何在 Pug 模板中正确地使用 JSON 插值,并解决了相关文档不足的问题。我们将介绍通过 gulp-pug 处理 JSON 数据的具体方法,以及如何在模板中插入和显示这些数据。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 本文探讨了如何在Java中使用JAXB解组两个具有相同名称但不同结构的对象。我们将介绍一个抽象类Bar及其具体实现,并展示如何正确地解析XML文档以获取正确的对象实例。 ... [详细]
  • 在寻找轻量级Ruby Web框架的过程中,您可能会遇到Sinatra和Ramaze。两者都以简洁、轻便著称,但它们之间存在一些关键区别。本文将探讨这些差异,并提供详细的分析,帮助您做出最佳选择。 ... [详细]
  • 当unique验证运到图片上传时
    2019独角兽企业重金招聘Python工程师标准model:public$imageFile;publicfunctionrules(){return[[[na ... [详细]
  • 本文探讨了在iOS平台上开发BLE(蓝牙低功耗)应用程序时遇到的挑战,特别是如何实现应用在后台模式下仍能持续扫描并连接蓝牙设备。文章提供了具体的配置方法和常见的问题解决方案。 ... [详细]
  • NTP服务器配置详解:原理与工作模式
    本文深入探讨了网络时间协议(NTP)的工作原理及其多种工作模式,旨在帮助读者全面理解NTP的配置参数和应用场景。NTP是基于RFC 1305的时间同步标准,广泛应用于分布式系统中,确保设备间时钟的一致性。 ... [详细]
  • CentOS 6.8 上安装 Oracle 10.2.0.1 的常见问题及解决方案
    本文记录了在 CentOS 6.8 系统上安装 Oracle 10.2.0.1 数据库时遇到的问题及解决方法,包括依赖库缺失、操作系统版本不兼容、用户权限不足等问题。 ... [详细]
author-avatar
可怜的绷带_565
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有