【问题标题】:Implements vs extends: When to use? What's the difference?实现与扩展:何时使用?有什么不同?
【发布时间】:2012-06-06 00:52:56
【问题描述】:

请用通俗易懂的语言或文章的链接进行说明。

【问题讨论】:

  • link 这个例子很容易理解接口和抽象类,即在java中实现和扩展。
  • extends 是扩展空间的一个元素

标签: java inheritance interface extends implements


【解决方案1】:

extends 用于扩展一个类。

implements 用于实现一个接口

接口和普通类的区别在于,在接口中你不能实现任何声明的方法。只有“实现”接口的类才能实现方法。接口的 C++ 等价物将是一个抽象类(不完全相同,但几乎相同)。

java 也不支持类的多重继承。这是通过使用多个接口来解决的。

 public interface ExampleInterface {
    public void doAction();
    public String doThis(int number);
 }

 public class sub implements ExampleInterface {
     public void doAction() {
       //specify what must happen
     }

     public String doThis(int number) {
       //specfiy what must happen
     }
 }

现在扩展一个类

 public class SuperClass {
    public int getNb() {
         //specify what must happen
        return 1;
     }

     public int getNb2() {
         //specify what must happen
        return 2;
     }
 }

 public class SubClass extends SuperClass {
      //you can override the implementation
      @Override
      public int getNb2() {
        return 3;
     }
 }

在这种情况下

  Subclass s = new SubClass();
  s.getNb(); //returns 1
  s.getNb2(); //returns 3

  SuperClass sup = new SuperClass();
  sup.getNb(); //returns 1
  sup.getNb2(); //returns 2

另外,请注意,实现接口不需要@Override 标签,因为在原始接口方法中没有任何内容要被覆盖

我建议您对面向对象编程中的动态绑定、多态性和一般继承进行更多研究

【讨论】:

  • 一个接口可以包含的不仅仅是方法声明:常量字段、注释、接口甚至类。
  • 它们是否类似于 ruby​​ 中的模块和 mixin?
  • @user2492854 一点点,但接口中不会有任何实现的方法。它实际上是对接口的描述,而不是实现。
  • Java 8 中的一项新功能允许为接口中的方法实现default 行为,从而使这些方法的自定义实现成为可选的。因此,“您只能指定方法,但不能实现方法” 语句仅在 Java 7 及更低版本 中完全正确。
  • "extends 是为了扩展一个类",有点混乱。正弦接口并扩展接口。例如:public interface ListIterator<E> extends Iterator<E>
【解决方案2】:

我注意到您的个人资料中有一些 C++ 问题。如果你从 C++ 中理解多重继承的概念(指从多个其他类继承特征的类),Java 不允许这样做,但它确实有关键字interface,即有点像 C++ 中的纯虚拟类。正如很多人所提到的,您extend 一个类(并且您只能从一个类扩展),而您implement 一个接口——但您的类可以实现任意数量的接口。

也就是说,这些关键字及其使用规则描述了 Java 中多重继承的可能性(您只能拥有一个超类,但可以实现多个接口)。

【讨论】:

    【解决方案3】:

    通常实现用于实现接口扩展用于扩展基类行为或抽象类。

    扩展:派生类可以扩展基类。您可以重新定义已建立关系的行为。派生类“是一个”基类类型

    实施:您正在实施合同。实现接口“具有”功能的类。

    随着java 8的发布,接口中可以有default方法,接口本身提供了实现。

    请参阅此问题了解何时使用它们:

    Interface vs Abstract Class (general OO)

    理解事物的例子。

    public class ExtendsAndImplementsDemo{
        public static void main(String args[]){
    
            Dog dog = new Dog("Tiger",16);
            Cat cat = new Cat("July",20);
    
            System.out.println("Dog:"+dog);
            System.out.println("Cat:"+cat);
    
            dog.remember();
            dog.protectOwner();
            Learn dl = dog;
            dl.learn();
    
            cat.remember();
            cat.protectOwner();
    
            Climb c = cat;
            c.climb();
    
            Man man = new Man("Ravindra",40);
            System.out.println(man);
    
            Climb cm = man;
            cm.climb();
            Think t = man;
            t.think();
            Learn l = man;
            l.learn();
            Apply a = man;
            a.apply();
    
        }
    }
    
    abstract class Animal{
        String name;
        int lifeExpentency;
        public Animal(String name,int lifeExpentency ){
            this.name = name;
            this.lifeExpentency=lifeExpentency;
        }
        public void remember(){
            System.out.println("Define your own remember");
        }
        public void protectOwner(){
            System.out.println("Define your own protectOwner");
        }
    
        public String toString(){
            return this.getClass().getSimpleName()+":"+name+":"+lifeExpentency;
        }
    }
    class Dog extends Animal implements Learn{
    
        public Dog(String name,int age){
            super(name,age);
        }
        public void remember(){
            System.out.println(this.getClass().getSimpleName()+" can remember for 5 minutes");
        }
        public void protectOwner(){
            System.out.println(this.getClass().getSimpleName()+ " will protect owner");
        }
        public void learn(){
            System.out.println(this.getClass().getSimpleName()+ " can learn:");
        }
    }
    class Cat extends Animal implements Climb {
        public Cat(String name,int age){
            super(name,age);
        }
        public void remember(){
            System.out.println(this.getClass().getSimpleName() + " can remember for 16 hours");
        }
        public void protectOwner(){
            System.out.println(this.getClass().getSimpleName()+ " won't protect owner");
        }
        public void climb(){
            System.out.println(this.getClass().getSimpleName()+ " can climb");
        }
    }
    interface Climb{
        public void climb();
    }
    interface Think {
        public void think();
    }
    
    interface Learn {
        public void learn();
    }
    interface Apply{
        public void apply();
    }
    
    class Man implements Think,Learn,Apply,Climb{
        String name;
        int age;
    
        public Man(String name,int age){
            this.name = name;
            this.age = age;
        }
        public void think(){
            System.out.println("I can think:"+this.getClass().getSimpleName());
        }
        public void learn(){
            System.out.println("I can learn:"+this.getClass().getSimpleName());
        }
        public void apply(){
            System.out.println("I can apply:"+this.getClass().getSimpleName());
        }
        public void climb(){
            System.out.println("I can climb:"+this.getClass().getSimpleName());
        }
        public String toString(){
            return "Man :"+name+":Age:"+age;
        }
    }
    

    输出:

    Dog:Dog:Tiger:16
    Cat:Cat:July:20
    Dog can remember for 5 minutes
    Dog will protect owner
    Dog can learn:
    Cat can remember for 16 hours
    Cat won't protect owner
    Cat can climb
    Man :Ravindra:Age:40
    I can climb:Man
    I can think:Man
    I can learn:Man
    I can apply:Man
    

    需要理解的要点:

    1. DogCat 是动物,它们通过从 Animal 共享 name,lifeExpentency 扩展了 remember() 和 protectOwner()
    2. 猫可以攀爬(),但狗不能。狗会思考(),但猫不会。这些特定功能通过实现该功能添加到CatDog
    3. 人不是动物,但他可以Think,Learn,Apply,Climb

    通过这些例子,你可以理解

    不相关的类可以通过接口获得能力,但相关类通过基类的扩展覆盖行为。

    【讨论】:

    • 真的是这样吗?我一直认为“拥有”是指拥有某物,拥有它。您可以说猫“具有”攀爬能力,但我想说改写您的示例。猫“是”攀登者“,人“是”“思考者、学习者、攀登者”。由于人“是”思考者,他可以做思考者能做的事情。使用某些协议时会更清楚——如果你有房子,有门,但它没有实现 pushHandle。它也是“一个”MaterialObject,意思是它实现了服从重力的接口;它没有“GravityObeyingSkill”或类似的东西。
    • 如果人是思想家,我将建立与扩展而不是实现的关系。 Thinker 可能有一些状态和其他角色/功能,但我将仅通过接口实现思考能力。 IS A 是用于继承的标准术语。
    【解决方案4】:

    如下图所示,一个类扩展了另一个类,一个接口扩展了另一个接口,但一个类实现了一个接口。

    了解更多details

    【讨论】:

    • 如果这些数字使用正确的 UML 符号(空心三角形),这个答案将是完美的。
    【解决方案5】:

    extends 用于从 基类 继承(即扩展其功能)。

    implements 用于实现接口

    这是一个很好的起点:Interfaces and Inheritance

    【讨论】:

    • 扩展接口也适用于扩展接口:-)。
    【解决方案6】:

    class 只能“实现”interface。一个类只“扩展”class。同样,interface 可以扩展另一个 interface

    class 只能扩展另一个 class。一个class 可以实现多个interfaces。

    如果您更想知道何时使用 abstract classes 和 interfaces,请参阅此主题:Interface vs Abstract Class (general OO)

    【讨论】:

      【解决方案7】:

      界面是对对象可以执行的操作的描述...例如,当您拨动电灯开关时,灯会亮起,您不在乎如何,它就是这样做的。在面向对象编程中,接口是对对象必须具有的所有功能的描述,以便成为“X”。同样,作为一个例子,任何“像”灯一样的东西都应该有一个 turn_on() 方法和一个 turn_off() 方法。接口的目的是允许计算机强制执行这些属性,并知道类型 T 的对象(无论接口是什么)必须具有称为 X、Y、Z 等的函数。

      接口是一种编程结构/语法,它允许计算机在对象(类)上强制执行某些属性。例如,假设我们有汽车类、踏板车类和卡车类。这三个类中的每一个都应该有一个 start_engine() 动作。每个车辆的“引擎如何启动”留给每个特定的类,但它们必须有一个 start_engine 操作这一事实是 interface 的域。

      【讨论】:

        【解决方案8】:

        Extends :这用于将父类的属性获取到子类中,并且可能包含可以在子类中覆盖的已定义方法。

        实现:这用于通过在子类中定义接口来实现接口(仅具有函数签名但不具有其定义的父类)。

        有一个特殊条件:“如果我想让一个新接口成为现有接口的子接口怎么办?”。在上述情况下,子接口扩展父接口。

        【讨论】:

          【解决方案9】:

          在使用 Java 语言创建您自己的新类时会使用这两个关键字。

          区别:implements 表示您在类中使用 Java 接口的元素。 extends 表示您正在创建要扩展的基类的子类。您只能在子类中扩展一个类,但您可以实现任意数量的接口。

          有关更多详细信息,请参阅interface 上的 Oracle 文档页面。

          这有助于阐明接口是什么,以及使用它们的约定。

          【讨论】:

            【解决方案10】:
            • A 扩展 B:

              A 和 B 都是类或都是接口

            • A 实现 B

              A 是类,B 是接口

            • A 是接口而 B 是类的其余情况在 Java 中是不合法的。

            【讨论】:

              【解决方案11】:

              Implements 用于接口,extends 用于扩展类。

              为了用更简单的术语更清晰,界面就像它的声音 - 一个界面 - 一个模型,您需要应用、遵循以及您的想法。

              Extend 用于类,在这里,您通过向其添加更多功能来扩展已经存在的东西。

              还有一些注意事项:

              一个接口可以扩展另一个接口。

              当您需要在实现接口或为特定场景扩展类之间做出选择时,请选择实现接口。因为一个类可以实现多个接口,但只能扩展一个类。

              【讨论】:

                【解决方案12】:

                我们使用 SubClass extends SuperClass 只有当子类想要使用已经在 SuperClass中声明的某些功能(方法或实例变量)时>,或者如果我想稍微修改 SuperClass 的功能(方法覆盖)。但是说,我有一个 Animal 类(SuperClass)和一个 Dog 类(SubClass),并且我在 Animal 类中定义的方法很少,例如。 (); , 睡眠(); ...等等。

                现在,我的 Dog 类可以简单地扩展 Animal 类,如果我希望我的狗使用 Animal 类中声明的任何方法,我可以通过简单地创建 Dog 对象来调用这些方法。所以这样我就可以保证我有一只能吃能睡的狗,可以做任何我想让狗做的事情。

                现在,想象一下,有一天某个爱猫的人来到我们的工作区,她试图扩展 Animal 类(猫也吃和睡)。她制作了一个 Cat 对象并开始调用方法。

                但是,比如说,有人试图创建 Animal 类的对象。你可以告诉猫如何睡觉,你可以告诉狗如何吃东西,你可以告诉大象如何喝水。 但是在创建 Animal 类的对象时没有任何意义。因为它是一个模板,我们不想要任何一般的吃法。

                因此,我更愿意创建一个没有人可以实例化但可以用作其他类的模板的抽象类。

                总而言之,接口只是一个抽象类(纯抽象类),它不包含方法实现,只包含定义(模板)。所以实现接口的人只知道他们有 doEat() 的模板;和 doSleep();但他们必须定义自己的doEat();和 doSleep();方法根据他们的需要。

                只有在你想重用 SuperClass 的某些部分时才进行扩展(但请记住,你总是可以根据需要覆盖 SuperClass 的方法)并且在你想要模板并且想要定义它们时实现你自己(根据你的需要)。

                我将与您分享一段代码:您尝试使用不同的输入集并查看结果。

                class AnimalClass {
                
                public void doEat() {
                    
                    System.out.println("Animal Eating...");
                }
                
                public void sleep() {
                    
                    System.out.println("Animal Sleeping...");
                }
                
                }
                
                public class Dog extends AnimalClass implements AnimalInterface, Herbi{
                
                public static void main(String[] args) {
                    
                    AnimalInterface a = new Dog();
                    Dog obj = new Dog();
                    obj.doEat();
                    a.eating();
                    
                    obj.eating();
                    obj.herbiEating();
                }
                
                public void doEat() {
                    System.out.println("Dog eating...");
                }
                
                @Override
                public void eating() {
                    
                    System.out.println("Eating through an interface...");
                    // TODO Auto-generated method stub
                    
                }
                
                @Override
                public void herbiEating() {
                    
                    System.out.println("Herbi eating through an interface...");
                    // TODO Auto-generated method stub
                    
                }
                
                
                }
                

                定义的接口

                public interface AnimalInterface {
                
                public void eating();
                
                }
                
                
                interface Herbi {
                
                public void herbiEating();
                
                }
                

                【讨论】:

                  【解决方案13】:

                  在最简单的术语中,extends 用于继承 classimplements 用于应用 interface强>在你的班里

                  扩展

                  public class Bicycle {
                      //properties and methods
                  }
                  public class MountainBike extends Bicycle {
                      //new properties and methods
                  }
                  

                  实现

                  public interface Relatable {
                      //stuff you want to put
                  }
                  public class RectanglePlus implements Relatable {
                      //your class code
                  }
                  

                  如果您仍然感到困惑,请阅读以下内容:https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html https://docs.oracle.com/javase/tutorial/java/IandI/usinginterface.html

                  【讨论】:

                    【解决方案14】:

                    当子类扩展类时,它允许子类继承(重用)和覆盖超类型中定义的代码。 当一个类实现一个接口时,它允许从该类创建的对象在任何需要接口值的上下文中使用。

                    这里真正的问题是,当我们实现任何东西时,它仅仅意味着我们正在使用这些方法。它们的值和返回类型没有变化的余地。

                    但是当我们扩展任何东西时,它就会成为您类的扩展。你可以改变它,使用它,重用它,它不一定需要返回与在超类中相同的值。

                    【讨论】:

                      【解决方案15】:

                      接口都是契约。 它们提供应用程序其他部分所依赖的方法和属性。

                      当您对该合约的实现细节不感兴趣时​​,您定义一个接口。唯一需要关心的是合约(接口)是否存在。

                      在这种情况下,您将其留给实现接口的类来关心合同如何履行的细节。只有类可以实现接口。

                      extends 在您想要替换现有合同的详细信息时使用。 这样,您就可以用另一种方式替换履行合同的一种方式。类可以扩展其他类,接口可以扩展其他接口。

                      【讨论】:

                        【解决方案16】:

                        extends 用于在您的子类/接口中需要父类/接口的属性时使用,implements 用于在您的类中需要接口的属性时使用。

                        例子:

                        1. 使用类扩展

                          class Parent{
                          
                          }
                          
                          class Child extends Parent {
                          
                          }
                          
                        2. 使用接口扩展

                          interface Parent {
                          
                          }
                          
                          interface Child extends Parent {
                          
                          }
                          
                        3. 实现

                          interface A {
                          
                          }
                          
                          class B implements A {
                          
                          }
                          
                        4. 扩展和实现的组合

                           interface A {
                          
                           }
                          
                           class B {
                          
                           }
                          
                           class C implements A, extends B {
                          
                           }
                          

                        【讨论】:

                          【解决方案17】:

                          扩展

                          • 类只扩展一个类
                          • 接口扩展了一个或多个接口

                          实现

                          • 类实现一个或多个接口
                          • 接口“不能”实现任何东西

                          抽象类也像类一样,带有扩展和实现

                          【讨论】:

                            【解决方案18】:

                            在 Java 中,一个类(子类)扩展了另一个类(超类),并且可以覆盖超类中定义的方法。

                            虽然当一个类试图声明在接口中定义的方法时使用implements,但该类正在扩展。

                            【讨论】:

                              【解决方案19】:

                              这两个关键字直接与继承相关,它是OOP的核心概念。 当我们将某个类继承到另一个类时,我们可以使用extends,但是当我们要为我们的类继承某些接口时,我们不能使用extends,我们应该使用implements,我们可以使用extends关键字从另一个接口继承接口。

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 2016-07-23
                                • 1970-01-01
                                • 2016-12-14
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2016-11-09
                                • 1970-01-01
                                相关资源
                                最近更新 更多