多重继承java

Today we will look into Multiple Inheritance in Java. Sometime back I wrote few posts about inheritance, interface and composition in java. In this post, we will look into java multiple inheritance and then compare composition and inheritance.

今天,我们将研究Java中的多重继承。 有时我写了几篇有关Java 继承接口组成的文章。 在本文中,我们将研究Java多重继承,然后比较组成和继承。

Java中的多重继承 (Multiple Inheritance in Java)

Multiple inheritance in java is the capability of creating a single class with multiple superclasses. Unlike some other popular object oriented programming languages like C++, java doesn’t provide support for multiple inheritance in classes.

Java中的多重继承是创建具有多个超类的单个类的能力。 与其他一些流行的面向对象的编程语言(如C ++)不同, java不提供对类中多重继承的支持

Java doesn’t support multiple inheritances in classes because it can lead to diamond problem and rather than providing some complex way to solve it, there are better ways through which we can achieve the same result as multiple inheritances.

Java不支持类中的多重继承,因为它可能导致菱形问题 ,而不是提供一些复杂的方法来解决它,而是有更好的方法来实现与多重继承相同的结果。

Java中的钻石问题 (Diamond Problem in Java)

To understand diamond problem easily, let’s assume that multiple inheritances were supported in java. In that case, we could have a class hierarchy like below image.

为了轻松理解钻石问题, 我们假设java中支持多个继承 。 在这种情况下,我们可以像下面的图像那样有一个类层次结构。

Let’s say SuperClass is an abstract class declaring some method and ClassA, ClassB are concrete classes.

假设SuperClass是一个抽象类,声明了一些方法,而ClassA,ClassB是具体类。

SuperClass.java

SuperClass.java

package com.journaldev.inheritance;public abstract class SuperClass {public abstract void doSomething();
}

ClassA.java

ClassA.java

package com.journaldev.inheritance;public class ClassA extends SuperClass{@Overridepublic void doSomething(){System.out.println("doSomething implementation of A");}//ClassA own methodpublic void methodA(){}
}

ClassB.java

ClassB.java

package com.journaldev.inheritance;public class ClassB extends SuperClass{@Overridepublic void doSomething(){System.out.println("doSomething implementation of B");}//ClassB specific methodpublic void methodB(){}
}

Now let’s say ClassC implementation would be something like below and it’s extending both ClassA and ClassB.

现在,让我们说ClassC的实现类似于下面的内容,它扩展了ClassA和ClassB。

ClassC.java

ClassC.java

package com.journaldev.inheritance;// this is just an assumption to explain the diamond problem
//this code won't compile
public class ClassC extends ClassA, ClassB{public void test(){//calling super class methoddoSomething();}}

Notice that test() method is making a call to superclass doSomething() method. This leads to the ambiguity as the compiler doesn’t know which superclass method to execute. Because of the diamond-shaped class diagram, it’s referred to as Diamond Problem in java. The diamond problem in Java is the main reason java doesn’t support multiple inheritances in classes.

注意, test()方法正在调用超类doSomething()方法。 由于编译器不知道要执行哪个超类方法,因此这导致了歧义。 由于菱形类图,在Java中被称为Diamond Problem。 Java中的菱形问题是Java不支持类中的多个继承的主要原因。

Notice that the above problem with multiple class inheritance can also come with only three classes where all of them has at least one common method.

请注意,具有多个类继承的上述问题也可能只出现在三个类中,它们全部具有至少一个通用方法。

Java接口中的多重继承 (Multiple Inheritance in Java Interfaces)

You might have noticed that I am always saying that multiple inheritances is not supported in classes but it’s supported in interfaces. A single interface can extend multiple interfaces, below is a simple example.

您可能已经注意到,我一直在说类不支持多重继承,但接口则支持多重继承。 单个接口可以扩展多个接口,下面是一个简单的示例。

InterfaceA.java

InterfaceA.java

package com.journaldev.inheritance;public interface InterfaceA {public void doSomething();
}

InterfaceB.java

InterfaceB.java

package com.journaldev.inheritance;public interface InterfaceB {public void doSomething();
}

Notice that both the interfaces are declaring the same method, now we can have an interface extending both these interfaces like below.

注意,两个接口都声明了相同的方法,现在我们可以拥有一个扩展这两个接口的接口,如下所示。

InterfaceC.java

InterfaceC.java

package com.journaldev.inheritance;public interface InterfaceC extends InterfaceA, InterfaceB {//same method is declared in InterfaceA and InterfaceB bothpublic void doSomething();}

This is perfectly fine because the interfaces are only declaring the methods and the actual implementation will be done by concrete classes implementing the interfaces. So there is no possibility of any kind of ambiguity in multiple inheritances in Java interfaces.

这很好,因为接口仅声明方法,并且实际实现将由实现接口的具体类完成。 因此,Java接口中的多重继承不存在任何歧义。

That’s why a java class can implement multiple interfaces, something like below example.

这就是为什么Java类可以实现多个接口的原因,例如下面的示例。

InterfacesImpl.java

InterfacesImpl.java

package com.journaldev.inheritance;public class InterfacesImpl implements InterfaceA, InterfaceB, InterfaceC {@Overridepublic void doSomething() {System.out.println("doSomething implementation of concrete class");}public static void main(String[] args) {InterfaceA objA = new InterfacesImpl();InterfaceB objB = new InterfacesImpl();InterfaceC objC = new InterfacesImpl();//all the method calls below are going to same concrete implementationobjA.doSomething();objB.doSomething();objC.doSomething();}}

Did you noticed that every time I am overriding any superclass method or implementing any interface method, I am using @Override annotation. Override annotation is one of the three built-in java annotations and we should always use override annotation when overriding any method.

您是否注意到,每次我重写任何超类方法或实现任何接口方法时,我都使用@Override注释。 覆盖注释是三个内置的Java注释之一 , 在覆盖任何方法时 ,我们都应始终使用覆盖注释 。

救援人员组成 (Composition for the rescue)

So what to do if we want to utilize ClassA function methodA() and ClassB function methodB() in ClassC. The solution lies in using composition. Here is a refactored version of ClassC that is using composition to utilize both classes methods and also using doSomething() method from one of the objects.

那么如果我们想在ClassC利用ClassA函数methodA()ClassB函数methodB() ClassC 。 解决方案在于使用组合 。 这是ClassC的重构版本,它使用合成来利用两个类方法以及一个对象中的doSomething()方法。

ClassC.java

ClassC.java

package com.journaldev.inheritance;public class ClassC{ClassA objA = new ClassA();ClassB objB = new ClassB();public void test(){objA.doSomething();}public void methodA(){objA.methodA();}public void methodB(){objB.methodB();}
}

组合与继承 (Composition vs Inheritance)

One of the best practices of Java programming is to “favor composition over inheritance”. We will look into some of the aspects favoring this approach.

Java编程的最佳实践之一是“偏向于继承而不是继承”。 我们将研究有利于这种方法的某些方面。

  1. Suppose we have a superclass and subclass as follows:

    ClassC.java

    package com.journaldev.inheritance;public class ClassC{public void methodC(){}
    }

    ClassD.java

    The above code compiles and works fine but what if ClassC implementation is changed like below:

    ClassC.java

    package com.journaldev.inheritance;public class ClassC{public void methodC(){}public void test(){}
    }

    Notice that test() method already exists in the subclass but the return type is different. Now the ClassD won’t compile and if you are using any IDE, it will suggest you change the return type in either superclass or subclass.

    Now imagine the situation where we have multiple levels of class inheritance and superclass is not controlled by us. We will have no choice but to change our subclass method signature or its name to remove the compilation error. Also, we will have to make a change in all the places where our subclass method was getting invoked, so inheritance makes our code fragile.

    The above problem will never occur with composition and that makes it more favorable over inheritance.

    ClassC.java

    ClassD.java

    package com.journaldev.inheritance;public class ClassD extends ClassC{public int test(){return 0;}
    }

    上面的代码可以编译并正常工作,但是如果ClassC实现更改如下:

    ClassC.java

    请注意,子类中已经存在test()方法,但返回类型不同。 现在,ClassD将无法编译,并且如果您使用的是任何IDE,它将建议您更改超类或子类中的返回类型。

    现在想象一下我们具有多个级别的类继承和超类不受我们控制的情况。 我们别无选择,只能更改子类方法签名或其名称以消除编译错误。 同样,我们将必须在所有调用子类方法的地方进行更改,因此继承会使我们的代码易碎。

    上面的问题永远不会在组合中发生,这使其比继承更有利。

  2. Another problem with inheritance is that we are exposing all the superclass methods to the client and if our superclass is not properly designed and there are security holes, then even though we take complete care in implementing our class, we get affected by the poor implementation of the superclass.

    Composition helps us in providing controlled access to the superclass methods whereas inheritance doesn’t provide any control of the superclass methods, this is also one of the major advantages of composition over inheritance.

    组合可以帮助我们提供对超类方法的受控访问,而继承不提供对超类方法的任何控制,这也是组合优于继承的主要优势之一。

  3. Another benefit with composition is that it provides flexibility in the invocation of methods. Our above implementation of ClassC is not optimal and provides compile-time binding with the method that will be invoked, with minimal change we can make the method invocation flexible and make it dynamic.

    ClassC.java

    package com.journaldev.inheritance;public class ClassC{SuperClass obj = null;public ClassC(SuperClass o){this.obj = o;}public void test(){obj.doSomething();}public static void main(String args[]){ClassC obj1 = new ClassC(new ClassA());ClassC obj2 = new ClassC(new ClassB());obj1.test();obj2.test();}
    }

    Output of above program is:

    This flexibility in method invocation is not available in inheritance and boosts the best practice to favor composition over inheritance.

    ClassC实现不是最佳的,它提供了与将要调用的方法的编译时绑定,只需进行很小的更改,我们就可以灵活地使方法调用并使之动态。

    ClassC.java

    package com.journaldev.inheritance;public class ClassC{SuperClass obj = null;public ClassC(SuperClass o){this.obj = o;}public void test(){obj.doSomething();}public static void main(String args[]){ClassC obj1 = new ClassC(new ClassA());ClassC obj2 = new ClassC(new ClassB());obj1.test();obj2.test();}
    }

    上面程序的输出是:

    这种方法调用的灵活性在继承中不可用,并提倡了最佳实践,即在继承方面偏向于组合。

  4. Unit testing is easy in composition because we know what all methods we are using from superclass and we can mock it up for testing whereas in inheritance we depend heavily on superclass and don’t know what all methods of superclass will be used, so we need to test all the methods of superclass, that is an extra work and we need to do it unnecessarily because of inheritance.单元测试很容易组合,因为我们知道超类中正在使用的所有方法,并且可以对其进行模拟,而在继承中,我们很大程度上依赖于超类,并且不知道将使用所有超类方法,因此我们需要要测试超类的所有方法,这是一项额外的工作,由于继承,我们不需要这样做。

That’s all for multiple inheritances in java and a brief look at composition.

这就是java中的多个继承以及对组合的简要介绍。

翻译自: https://www.journaldev.com/1775/multiple-inheritance-in-java

多重继承java

多重继承java_Java中的多重继承相关推荐

  1. 多重继承java_Java中的多重继承与组合vs继承

    多重继承java 有时我写了几篇有关Java 继承 , 接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能 ...

  2. java可以多重继承吗_Java中的多重继承与组合vs继承

    java可以多重继承吗 有时我写了几篇有关Java继承,接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能 ...

  3. Java中的多重继承与组合vs继承

    有时我写了几篇有关Java 继承 , 接口和组成的文章. 在这篇文章中,我们将研究多重继承,然后学习组成优于继承的好处. Java中的多重继承 多重继承是创建具有多个超类的单个类的能力. 与其他一些流 ...

  4. php中多重继承,PHP面向对象之多重继承与接口用法

    介绍接口之前,我们要知道,为什么要使用接口,这里向大家介绍一下. 那为什么要使用接口呢? 计算机语言中,只有少数的面向对象支持多重继承,我们所学习的PHP语言和大多数语言一样,并不支持多重继承.说白了 ...

  5. C++中的多重继承(二)

    1,本文分析另一个多重继承问题及其工程中的解决方案,单继承加多接口实现的开发方式: 2,多重继承的问题三: 1,多重继承可能产生多个虚函数表: 1,实际工程中可能造成不可思议的问题,并且这些问题很难以 ...

  6. Java中的多重继承问题

    继承是面向对象编程 (OOP) 语言(如Java)的主要功能之一.它是一种以增强软件设计中类重用能力的方式组织类的基本技术.多重继承是众多继承类型之一,是继承机制的重要原则.但是,它因在类之间建立模棱 ...

  7. java实现多重继承_Java 程序实现多重继承

    Java 程序实现多重继承 在此示例中,我们将学习在Java中实现多重继承. 要理解此示例,您应该了解以下Java编程主题: 当子类从多个超类继承时,称为多重继承.但是,Java不支持多重继承. 要在 ...

  8. Python中使用多重继承

    在Python中(包括比较成熟的面向对象语言,比如Java, C#)中,一般只能进行单继承,当然C++是多继承的.多继承会使得继承结构比较复杂,不容易理清,这估计就是为什么后来新的面向对象语言中,没有 ...

  9. Python中的多重继承

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net 继承是面向对象编程的一个重要的方式,通过继承,子类就 ...

最新文章

  1. Linux系统下给Qt应用程序配置图标(其余的应用程序也是可以实现添加图标的)
  2. Spring Cloud Alibaba - 02 SpringCloud 、 SpringCloud Alibaba 、SpringBoot的生产版本选择
  3. Android makefile编译流程(二)
  4. centos7怎么重置mysql密码_centOS7.4 重置mysql 密码
  5. java 压缩 乱码_如何解决java压缩文件乱码问题
  6. Python:IndentationError: unexpected indent
  7. lacp静态和动态区别_TTM、静态和动态市盈率的区别,三种市盈率看哪个?
  8. Android广播机制(2)
  9. eclipse mac常用快捷键
  10. 指示灯亮着,但是右边的数字小键盘不可用
  11. 修改整个app的字体
  12. 使用 docker-pan 一键搭建可离线磁力种子的私有云盘
  13. 微信小程序switch组件尺寸控制
  14. 重庆GDP超过了广州,纯属正常?
  15. 加载网页时弹出div
  16. Enolsoft PDF Converter with OCR Mac(PDF格式转换及OCR识别软件)
  17. 水文气象学数据可视化——Panoply软件的下载
  18. H264—帧,片,参数集,NALU等概念
  19. 磁粉制动器磁滞特性的研究笔记
  20. pytorch 定义torch类型数据_PyTorch官方中文文档:torch.Tensor

热门文章

  1. Java程序猿从笨鸟到菜鸟之(九十二)深入java虚拟机(一)——java虚拟机底层结构具体解释...
  2. Google Java编程风格指南中文版(转)
  3. SharePoint 2010 technology stack
  4. ubuntu下安装beanstalkd
  5. [转载] python 时间sleep() 的方法
  6. [转载] python数字类型(一)
  7. [转载] python 装饰器
  8. libstdc和glibc的一些共享库问题
  9. 浅谈数据结构之顺序队列(五)
  10. 20150917-html第二次课