精华内容
下载资源
问答
  • 这篇文章,我们将研究多重继承,然后了解组成优于继承的好处。 Java中多重继承 多重继承是创建具有多个超类的单个类的能力。 与其他一些流行的面向对象的编程语言(例如C ++)不同, java不提供对类中多重继承...
    java可以多重继承吗

    java可以多重继承吗

    有时我写了几篇有关Java继承接口组成的文章。 在这篇文章中,我们将研究多重继承,然后了解组成优于继承的好处。

    Java中的多重继承

    多重继承是创建具有多个超类的单个类的能力。 与其他一些流行的面向对象的编程语言(例如C ++)不同, java不提供对类中多重继承的支持。 Java不支持类中的多重继承,因为它可能导致钻石问题,而不是提供一些复杂的方法来解决它,而是有更好的方法来实现与多重继承相同的结果。

    钻石问题

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

    钻石问题多重继承

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

    超类.java

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

    ClassA.java

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

    ClassB.java

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

    现在,让我们说ClassC的实现如下所示,它扩展了ClassA和ClassB。

    ClassC.java

    package com.journaldev.inheritance;
    
    public class ClassC extends ClassA, ClassB{
    
    	public void test(){
    		//calling super class method
    		doSomething();
    	}
    
    }

    注意, 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 both
    	public void doSomething();
    
    }

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

    这就是为什么Java类可以实现多重继承的原因,例如下面的示例。

    接口Impl.java

    package com.journaldev.inheritance;
    
    public class InterfacesImpl implements InterfaceA, InterfaceB, InterfaceC {
    
    	@Override
    	public 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 implementation
    		objA.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编程的最佳实践之一是“通过接口支持组合”,我们将研究一些偏爱这种方法的方面。

    1. 假设我们有一个超类和子类,如下所示:

      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,它将建议您更改超类或子类中的返回类型。

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

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

    2. 继承的另一个问题是,我们将所有超类方法公开给客户端,并且如果我们的超类设计不当且存在安全漏洞,那么即使我们在实现类时全神贯注,我们也会受到不良实现的影响。超类。组合可以帮助我们提供对超类方法的受控访问,而继承不提供对超类方法的任何控制,这也是组合优于继承的主要优势之一。
    3. 组合的另一个好处是它提供了方法调用的灵活性。 我们上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

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

    4. 单元测试很容易组合,因为我们知道超类中正在使用的所有方法,并且可以对其进行模拟,而在继承中,我们很大程度上依赖于超类,并且不知道将使用所有超类方法,因此我们需要要测试超类的所有方法,这是一项额外的工作,由于继承,我们不需要这样做。

    理想情况下,仅当在所有情况下父类和子类的“ is-a ”关系均成立时才应使用继承,否则我们应该继续进行组合。

    翻译自: https://www.javacodegeeks.com/2013/08/multiple-inheritance-in-java-and-composition-vs-inheritance.html

    java可以多重继承吗

    展开全文
  • 主要介绍了java为什么不允许多重继承允许接口多重继承,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Java中多重继承

    千次阅读 2015-11-07 10:00:22
    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。 有些时候我们会认为如果系统需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要...

         

    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。

    有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要思考的不是怎么使用多重继承,而是您的设计是否存在问题.但有时候我们确实是需要实现多重继承,而且现实生活中也真正地存在这样的情况,比如遗传:我们即继承了父亲的行为和特征也继承了母亲的行为和特征。可幸的是Java是非常和善和理解我们的,它提供了两种方式让我们曲折来实现多重继承:接口和内部类。


    一、 接口


           在介绍接口和抽象类的时候了解到子类只能继承一个父类,也就是说只能存在单一继承,但是却可以实现多个接口,这就为我们实现多重继承做了铺垫。

           对于接口而已,有时候它所表现的不仅仅只是一个更纯粹的抽象类,接口是没有任何具体实现的,也就是说,没有任何与接口相关的存储,因此也就无法阻止多个接口的组合了。

    interface CanFight {
        void fight();
    }
    
    interface CanSwim {
        void swim();
    }
    
    
    interface CanFly {
        void fly();
    }
    
    public class ActionCharacter {
        public void fight(){
            
        }
    }
    
    public class Hero extends ActionCharacter implements CanFight,CanFly,CanSwim{
    
        public void fly() {
        }
       
        public void swim() {
        }
    
        /**
         * 对于fight()方法,继承父类的,所以不需要显示声明
         */
    }

    二、内部类


           上面使用接口实现多重继承是一种比较可行和普遍的方式,在介绍内部类的时候谈到内部类使的多继承的实现变得更加完美了,同时也明确了如果父类为抽象类或者具体类,那么我就仅能通过内部类来实现多重继承了。如何利用内部类实现多重继承,请看下面实例:儿子是如何利用多重继承来继承父亲和母亲的优良基因。

           首先是父亲Father和母亲Mother:

    public class Father {
        public int strong(){
            return 9;
        }
    }
    
    public class Mother {
        public int kind(){
            return 8;
        }
    }

      重头戏在这里,儿子类Son:

    public class Son {
        
        /**
         * 内部类继承Father类
         */
        class Father_1 extends Father{
            public int strong(){
                return super.strong() + 1;
            }
        }
        
        class Mother_1 extends  Mother{
            public int kind(){
                return super.kind() - 2;
            }
        }
        
        public int getStrong(){
            return new Father_1().strong();
        }
        
        public int getKind(){
            return new Mother_1().kind();
        }
    }

    测试程序:

    public class Test1 {
    
        public static void main(String[] args) {
            Son son = new Son();
            System.out.println("Son 的Strong:" + son.getStrong());
            System.out.println("Son 的kind:" + son.getKind());
        }
    
    }
    ----------------------------------------
    Output:
    Son 的Strong:10
    Son 的kind:6

      儿子继承了父亲,变得比父亲更加强壮,同时也继承了母亲,只不过温柔指数下降了。这里定义了两个内部类,他们分别继承父亲Father类、母亲类Mother类,且都可以非常自然地获取各自父类的行为,这是内部类一个重要的特性:内部类可以继承一个与外部类无关的类,保证了内部类的独立性,正是基于这一点,多重继承才会成为可能。




    展开全文
  • Java中关于多重继承的问题标签(空格分隔): Java多重继承的含义 多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而Java为了保证数据安全,它只允许单继承。 有时候我们确实是需要实现多重...

    Java中关于多重继承的问题

    标签(空格分隔): Java


    多重继承的含义

        多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而Java为了保证数据安全,它只允许单继承。
        有时候我们确实是需要实现多重继承,以达到不同的需求。而且现实生活中也真正地存在这样的情况,比如遗传:我们即继承了父亲的行为和特征也继承了母亲的行为和特征。幸运的是,Java还是为我们提供了两种方式让我们曲折来实现多重继承:接口和内部类。
    

    一.用接口实现多重继承

     Java通过采用实现多个接口和继承一个父类的形式来达到多重继承的效果
    
    
    interface CanFight {
        void fight();
    }
    interface CanSwim {
        void swim();
    }
    interface CanFly {
        void fly();
    }
    class ActionCharacter {
        public void fight() {
    
        }
    }
    
    
    class Hero extends ActionCharacter implements CanFight,CanFly,CanSwim {
    
        /**
         * Hero沒有显示提供fight()的定义,因为所继承的类中包含fight()方法,所有可以
         * 成功创建Hero对象
         * 
         */
        @Override
        public void swim() {
            // TODO Auto-generated method stub
    
        }
    
        @Override
        public void fly() {
            // TODO Auto-generated method stub
    
        }
    
    }
    

    二.用内部类实现多重继承

        如果没有内部类提供的,可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决,从这个角度看,内部类使得多重继承的解决方案变得完整。也就是说,如果拥有的是抽象的类或具体的类,而不是接口,那就只能用内部类才能实现多重继承。`
        例子:
        class Dee1{}
        abstract class E {}
        class Cer1 {
            Dee1 makeD() {
                    return new Dee1() {};
                    }
            E makeE() {
                    return new E() {};
                    }
        }
    外部类里创建多个内部类以达到多重继承的目的,从而解决多重继承的问题,如果不需要解决多重继承问题,大可换其他方式,不必使用内部类。
    
    展开全文
  • 然后a12又多重继承了a1和a2。同样,a12获得了b方法的定义。 但是假设上述代码的接口都换成类,假如a12没有对b方法作覆盖,那么再假如a1对b方法作了实现,然后a2也对b方法作了实现,那么a12继承的b方法究竟来自...

    首先看下面这一段代码:(底下有热心网友更正,jdk1.8之后情况确实有点变化,等改天有空继续更)

    interface a{
        void b();
    }
    interface a1 extends a{
        void b();
    }
    interface a2 extends a{
        void b();
    }
    interface a12 extends a1,a2{
        void b();
    }
    public class Main {
        public static void main(String args[]){
    
        }
    }
    

    上面a1和a2都继承了接口a,都获得了b方法的定义。然后a12又多重继承了a1和a2。同样,a12获得了b方法的定义。

    但是假设上述代码中的接口都换成类,假如a12没有对b方法作覆盖,那么再假如a1对b方法作了实现,然后a2也对b方法作了实现,那么a12继承的b方法究竟来自于哪个类里的b方法呢?这里似乎舍弃掉哪个方法都不太好。

    所以类的多继承会出现矛盾。

    接口由于都没有具体实现,所以不会出现这个矛盾。

    有人可能会问,那既然没有实现就可以多继承,那么抽象类可以不可以多继承呢?

    答案是不可以的!

    具体为什么不可以,请继续关注我的博客~ 

    好了,还是现在就说吧,抽象类跟普通类在多继承这块我觉得是差不多的。

    看下面代码:

    abstract class a{
        abstract void b();
        void c(){
            System.out.println("c()");
        }
        abstract void d();
        abstract void e();
        abstract void f();
    }
    
    abstract class b extends a{
        abstract void b();
        abstract void d();
        abstract void e();
        void f(){
            System.out.println("f()");
        }
        /*abstract void f();*/
    }
    
    abstract class c extends a{
        abstract void b();
        abstract void d();
        abstract void e();
        abstract void f();
    }
    
    public class Main {
        public static void main(String args[]){
        }
    }

    假设我们有个类d要继承b和c,而且还不重写f方法,那么问题来了,类d里面的f方法是用谁的f方法呢?你可能会觉得,类b都实现了,当然是类b里已经实现的f方法啊?

    你这样认为的话,那java编译器还认为类c里面的抽象方法f也是一个值得保留的特性呢,这时候矛盾就来了...

    但是用接口的话,就很单一了,所有的接口都没有实现~所以随便从哪个接口里来继承并覆盖这个方法都无所谓~

    展开全文
  • 摘要:虽然Java允许多重继承,但是有些情况却允许其使用。本文将阐述一个Web应用模拟多重继承的技术。一般的开发Java的单继承限制一般不会引起什么问题。实际上,需要使用多重继承往往意味着糟糕的设计...
  • 摘要:虽然Java允许多重继承,但是有些情况却允许其使用。本文将阐述一个Web应用模拟多重继承的技术。一般的开发Java的单继承限制一般不会引起什么问题。实际上,需要使用多重继承往往意味着糟糕的设计...
  • java为什么不允许多重继承

    千次阅读 2016-08-17 13:58:37
    李四:假设java允许多重继承,那么Son就可以重载Father和Mother的方法,这两个方法的参数列表、方法签名都是一样的,java会搞不清楚到底是重载Father还是Mather的方法。但如果你把Father、Mother都改成interface,...
  • Java实现多重继承技巧

    千次阅读 2017-02-14 10:16:13
    Java实现多重继承
  • 概念 多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,C++是允许多继承的...但是也不排除它的使用场景,Spring的代码就有很多多重继承的使用场景。 这里讲述下Java提供了两种实现多重继承的方式...
  • java实现多重继承

    2016-12-27 10:04:18
    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要...
  • java多重继承

    2018-05-11 16:51:51
    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统需要使用多重继承往往都是糟糕的设计,这个时候我们往往...
  • Java实现多重继承

    千次阅读 2018-06-07 16:14:13
    多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。Java提供了两种方式让我们曲折来实现多重继承:接口和内部类。①接口和内部类的应用场景区别...
  • 1、interface不仅仅只是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类型的类,来实现某种类似C++多重继承变种的特性。 2、像类一样,可以interface关键字前面添加public关键字(但仅...
  • 多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要...
  • 多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要...
  • Java接口-多重继承-Java编程思想

    千次阅读 2018-01-20 15:43:03
    一个类同时继承基类和多个接口时,该类是否可以不实现接口的方法? 一个类同时实现多个接口,能否向上转型到各接口? 一个类同时实现多个接口,接口的方法签名是否可以保持一样? 代码解惑 package think...
  • Java 回答这种棘手问题的关键是准备好相关主题, 以应对后续的各种可能的问题。 这是非常经典的问题,与为什么 String Java 是不可变的很类似; 这两个问题之间的相似之处在于它们主要是由 Java 创作者的...
  • 多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统需要使用多重继承往往都是糟糕的设计,这个时候我们往往需要...
  • 为什么JAVA允许继承

    千次阅读 2015-09-09 08:50:49
     在Java语言禁止多重继承:一个类可以具有多个直接父类。多重继承不合法的原因是容易引发意义不明确。例如,有一个类C,如果允许它同时继承A类与B类(class C extends A,B{}),假如A、B两个类都有同一种方法fun...
  • JAVA 单继承 与 接口 多重继承

    千次阅读 2017-10-11 18:30:42
    又是一个牛角尖,只是语言不够严谨而已,Java中只支持类的单继承,接口之间的继承同样也是使用extends关键字,但是接口之间是支持多继承的,如下面的例子: [java] view plaincopy interface IP1 {  }...
  • Java中实现的多重继承

    千次阅读 2019-08-18 13:28:06
    首先,多重继承指的是一个类可以同时从多个的父类那里继承属性和行为,然而我们知道Java为了保证数据安全,它只允许单继承,使用关键字(extends)来完成。但是这样的话,我们设计程序会遇到一些麻烦。对于小编来说...
  • 在java.util.concurrent.RunnableFuture.class 有个接口,如下: /* * @(#)RunnableFuture.java 1.3 06/01/30 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/...
  • java允许继承

    千次阅读 2017-04-25 22:22:55
    java中类只能单继承,一个类只能有一个直接父类,可以有多个间接父类。 java通过接口来实现多继承,接口里只有方法的声明没有实现。 C++可以实现多继承, 多继承可能会多继承可能会导致钻石环问题---假设...
  • Python的多重继承Java的单继承

    千次阅读 2015-01-30 16:12:27
    最近学习Python,了解到Python是允许使用多重继承的,与Java的单继承不同。 仔细思考之后觉得Python的这种多重继承的设计更为合理些,更接近现实世界。因为我觉得一个物体不能严格的把它归为确定的某一类,拿动物...
  • 在Java语言禁止多重继承:一个类可以具有多个直接父类。多重继承不合法的原因是容易引发意义不明确。例如,有一个类C,如果允许它同时继承A类与B类(class C extends A,B{}),假如A、B两个类都有同一种方法fun()...
  • 前言: 我为什么要用这个问题单独发一篇文章呢?因为我发现这个问题很难回答,因为答对... Java 回答这种棘手问题的关键是准备好相关主题, 以应对后续的各种可能的问题。 这是非常经典的问题,与为什么 String...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 35,340
精华内容 14,136
关键字:

在java中允许多重继承

java 订阅