热门标签 | 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中给出的承诺。


推荐阅读
  • 在上篇文章的基础上,本文将继续探讨 Linux 设备驱动中的设备模型与 `devicedriverbus` 机制。在将设备注册到总线之前,需要先创建 `device` 对象。可以通过静态定义 `device` 结构体变量,并调用 `device_register` 函数来完成这一过程。此外,文章还将详细解析设备模型的内部工作机制,以及 `devicedriverbus` 机制如何实现设备与驱动的自动匹配和管理。 ... [详细]
  • 深入解析Android中图像资源的内存占用问题及其优化策略
    在Android开发过程中,图像资源的内存占用是一个值得关注的问题。本文将探讨图像内存占用与哪些因素相关,包括设备性能的影响,并提供一系列优化策略,帮助开发者有效管理图像资源,提升应用性能。 ... [详细]
  • 在安装 Greenplum 的过程中,正确配置 `gpinitsystem_config` 文件是至关重要的一步。本文详细介绍了如何优化该文件,以确保数据库集群的高效初始化和稳定运行。通过调整关键参数,用户可以更好地适应不同的硬件环境和业务需求,从而提升系统的整体性能。 ... [详细]
  • 本章深入探讨了Java中的多态特性,这是面向对象编程的核心概念之一。多态指的是同一操作作用于不同的对象时,可以有不同的解释和执行方式。在Java中,多态通过父类引用变量引用子类对象来实现,即 `父类类型 引用变量名 = new 子类类型();`。这种方式允许程序在运行时根据实际对象的类型动态地选择合适的方法执行,从而提高代码的灵活性和可扩展性。此外,本章还详细介绍了多态的应用场景和注意事项,帮助读者更好地理解和运用这一重要概念。 ... [详细]
  • 本文深入探讨了Google Guava库中的Optional类,详细解析了其设计原理和使用方法,并结合实际应用场景展示了如何有效避免空指针异常,提高代码的健壮性和可读性。通过具体示例,文章还介绍了Optional类在数据处理、函数式编程等方面的优势,为开发者提供了实用的参考。 ... [详细]
  • 本文深入探讨了Android事件分发机制的源代码,重点分析了DecorView作为Activity根布局的角色及其在事件传递中的作用。同时,详细解析了PhoneWindow在Activity窗口管理中的关键功能,以及它如何与DecorView协同工作,确保用户交互事件的高效处理。 ... [详细]
  • 教程:使用Source Monitor进行代码质量分析
    Source Monitor 是一款强大的代码分析工具,能够对 Java、C++、C、C# 和 Delphi 等多种编程语言进行复杂度分析,帮助开发者有效评估和提升代码质量。通过详细的指标和报告,该工具可辅助团队识别潜在问题并优化代码结构。 ... [详细]
  • 探讨 javax.jms.JMSException 中 getLocalizedMessage 方法的应用与实例代码分析 ... [详细]
  • 基于灰度直方图的水果识别系统开发:MATLAB源代码及图形用户界面设计
    基于灰度直方图的水果识别系统开发:MATLAB源代码及图形用户界面设计 ... [详细]
  • 在探讨Java动态代理机制时,本文深入分析了其核心原理与实现方式,并详细讨论了该机制在Spring框架中的应用,特别是在AOP(面向切面编程)中的作用。通过实例解析,读者可以更好地理解如何利用动态代理增强代码的灵活性和可维护性。 ... [详细]
  • c#学Java–Java基本语法1.类比JAVA .NETJVM CLRJDK  FCL2.java命名约定类名称应以大写字母开头,并成为容易理解的名词或组合。如 ... [详细]
  • 后端开发|php教程numbering,addClass,COOKIE,POST,instanceof后端开发-php教程一:php变量商场项目源码,ubuntu安装其他系统,to ... [详细]
  • 【高德地图Android开发套件】详尽视频教程
    前两天参加了高德在北航举办的公开课,感觉非常不错。完成老师布置的作业之后,还顺利地拿到了高德开发者认证证书!!现在来跟大家分享一下,如何快速学习【高德地图AndroidSDK】的开发。一天包会!连 ... [详细]
  • 优化后的标题:在Android中利用GridView实现动态视觉效果
    项目中用到的一些动画,GridView的Item依次从屏幕外飞入到相应位置,附上相关代码: MainActivity.java packa ... [详细]
  • 本文出处:炎之铠csdn博客:http:blog.csdn.nettotond炎之铠邮箱:yanzhikai_yjk@qq.com本文原创,转载请注明本出处!前言 ... [详细]
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社区 版权所有