制作公司网站设计要求,公众号怎么制作模版,网站300兆是多少钱,wordpress统计浏览量多重继承java有时我写了几篇有关Java 继承 #xff0c; 接口和组成的文章。 在这篇文章中#xff0c;我们将研究多重继承#xff0c;然后了解组成优于继承的好处。 Java中的多重继承 多重继承是创建具有多个超类的单个类的能力。 与其他一些流行的面向对象的编程语言#… 多重继承java 有时我写了几篇有关Java 继承 接口和组成的文章。 在这篇文章中我们将研究多重继承然后了解组成优于继承的好处。 Java中的多重继承 多重继承是创建具有多个超类的单个类的能力。 与其他一些流行的面向对象的编程语言如C 不同 java不提供对类中多重继承的支持 。 Java不支持类中的多重继承因为它可能导致菱形问题 而不是提供一些复杂的方法来解决它而是有更好的方法来实现与多重继承相同的结果。 钻石问题 为了轻松理解钻石问题我们假设Java中支持多重继承。 在这种情况下我们可以像下面的图像那样有一个类层次结构。 假设SuperClass是一个抽象类声明了一些方法而ClassAClassB是具体类。 超类.java package com.journaldev.inheritance;public abstract class SuperClass {public abstract void doSomething();
} 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 package com.journaldev.inheritance;public class ClassB extends SuperClass{Overridepublic void doSomething(){System.out.println(doSomething implementation of B);}//ClassB specific methodpublic void methodB(){}
} 现在让我们说ClassC的实现类似于以下内容它扩展了ClassA和ClassB。 ClassC.java package com.journaldev.inheritance;public class ClassC extends ClassA, ClassB{public void test(){//calling super class methoddoSomething();}} 注意 test()方法正在调用超类doSomething()方法这导致歧义因为编译器不知道要执行哪个超类方法并且由于菱形类图它被称为Diamond Problem这是Java不支持类中的多重继承的主要原因。 请注意具有多个类继承的上述问题也可能只出现在三个类中它们全部具有至少一个通用方法。 接口中的多重继承 您可能已经注意到我一直在说类不支持多重继承但接口支持多重继承并且单个接口可以扩展多个接口下面是一个简单的示例。 接口A.java package com.journaldev.inheritance;public interface InterfaceA {public void doSomething();
} 接口B.java package com.journaldev.inheritance;public interface InterfaceB {public void doSomething();
} 注意两个接口都声明了相同的方法现在我们可以拥有一个扩展这两个接口的接口如下所示。 接口C.java package com.journaldev.inheritance;public interface InterfaceC extends InterfaceA, InterfaceB {//same method is declared in InterfaceA and InterfaceB bothpublic void doSomething();} 这样做非常好因为接口仅声明方法并且实际实现将由实现接口的具体类来完成因此在接口的多重继承中不存在任何歧义的可能性。 这就是为什么Java类可以实现多重继承的原因例如下面的示例。 接口Impl.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();}} 您是否注意到每当我覆盖任何超类方法或实现任何接口方法时我都使用Override注释它是三个内置的Java注释之一并且在覆盖任何方法时都应始终使用覆盖注释 。 救援人员组成 因此如果我们想在ClassC使用ClassA函数methodA和ClassB函数methodB 该解决方案在于使用composition 这是ClassC的重构版本该版本使用了composition来利用这两种类方法以及doSomething 方法来自其中一个对象。 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();}
}组合与继承 Java编程的最佳实践之一是“通过接口支持组合”我们将研究一些偏爱这种方法的方面。 假设我们有一个超类和子类如下所示 ClassC.java package com.journaldev.inheritance;public class ClassC{public void methodC(){}
} ClassD.java package com.journaldev.inheritance;public class ClassD extends ClassC{public int test(){return 0;}
} 上面的代码可以编译并正常工作但是如果ClassC实现更改如下 ClassC.java package com.journaldev.inheritance;public class ClassC{public void methodC(){}public void test(){}
} 请注意子类中已经存在test方法但返回类型有所不同现在ClassD将无法编译并且如果您使用的是任何IDE它将建议您更改超类或子类中的返回类型。 现在想象一下这样的情况我们具有多个级别的类继承并且超类不受我们控制我们别无选择只能更改子类方法签名或名称以消除编译错误我们还必须在所有方面进行更改子类方法被调用的地方因此继承使我们的代码易碎。 上面的问题永远不会在组合中发生这使其比继承更有利。 继承的另一个问题是我们将所有超类方法公开给客户端并且如果我们的超类设计不当且存在安全漏洞那么即使我们在实现类时全神贯注我们也会受到不佳实现的影响。超类。 组合可以帮助我们提供对超类方法的受控访问而继承不提供对超类方法的任何控制这也是组合优于继承的主要优势之一。 组合的另一个好处是它提供了方法调用的灵活性。 我们上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();}
} 上面程序的输出是 doSomething implementation of A
doSomething implementation of B 这种方法调用的灵活性在继承中不可用并提倡了最佳实践即在继承方面偏向于组合。 单元测试很容易组合因为我们知道超类中正在使用的所有方法并且可以对其进行模拟而在继承中我们很大程度上依赖于超类并且不知道将使用所有超类方法因此我们需要要测试超类的所有方法这是一项额外的工作由于继承我们不需要这样做。 理想情况下仅当在所有情况下父类和子类的“ is-a ”关系均成立时才应使用继承否则我们应该继续进行组合。 参考 Developer Recipes博客上的JCG合作伙伴 Pankaj Kumar的Java多重继承与Composition vs Inheritance 。 翻译自: https://www.javacodegeeks.com/2013/08/multiple-inheritance-in-java-and-composition-vs-inheritance.html多重继承java