关于java:Implements vs extends:何时使用? 有什么不同?

Implements vs extends: When to use? What's the difference?

请用易于理解的语言或某篇文章的链接进行解释。


extends用于扩展类。

implements用于实现接口

接口和常规类的区别在于,在接口中,不能实现任何已声明的方法。只有"实现"接口的类才能实现这些方法。一个接口的C++等价物是抽象类(不是完全相同,而是相当多)。

同样,Java不支持类的多重继承。这可以通过使用多个接口来解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 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
     }
 }

现在扩展类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 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;
     }
 }

在这种情况下

1
2
3
4
5
6
7
  Subclass s = new SubClass();
  s.getNb(); //returns 1
  s.getNb2(); //returns 3

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

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


我注意到你的配置文件中有一些C++问题。如果您从C++理解了多重继承的概念(指从多个其他类继承特征的类),Java不允许这样做,但它确实具有关键字EDCOX1×7,它类似于C++中的纯虚拟类。正如许多人所提到的,你的extend是一个类(你只能从一个类扩展),而你的implement是一个接口——但是你的类可以实现任意多的接口。

IE,这些关键字和管理它们的规则描绘了Java中多重继承的可能性(您只能拥有一个超级类,但可以实现多个接口)。


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

implements用于实现接口时。

这里是一个很好的起点:接口和继承。


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

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

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

使用Java 8发布,接口可以在接口中提供默认方法,这在接口本身中提供了实现。

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

接口与抽象类(常规OO)

以身作则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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;
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
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

要理解的要点:

  • 狗和猫是动物,它们通过分享来自Animalname,lifeExpentency,扩展了rememberprotectOwner
  • 猫可以爬升,但狗不能爬升。狗会思考,猫不会。这些特定的能力通过实现该能力被添加到CatDog中。
  • 人不是动物,但他可以
  • 通过这些例子,你可以理解

    无关类可以通过接口拥有功能,但相关类通过扩展基类来覆盖行为。


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

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

    如果您更希望知道何时使用abstract classes和interfaces,请参考此线程:接口与抽象类(常规OO)


    接口是对对象可以执行的操作的描述…例如,当你拨动一个灯开关,灯就会亮起来,你不在乎它是怎么亮起来的,只是这样而已。在面向对象编程中,接口是对对象必须具有的所有函数的描述,以便成为"X"。同样,作为一个例子,任何"像"灯的东西都应该有一个turn-on()方法和一个turn-off()方法。接口的目的是允许计算机强制执行这些属性,并知道T类型的对象(无论接口是什么)必须具有称为X、Y、Z等的函数。

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


    • A扩展B:

      A和B都是类或两个接口

    • 工具B

      A是一个类,B是一个接口

    • 在Java中,A是接口和B是一个类的其余情况是不合法的。


    扩展:用于将父类的属性获取到基类中,并且可能包含已定义的方法,这些方法可以在子类中被重写。

    实现:通过在子类中定义接口来实现接口(仅具有函数签名的父类,而不是它们的定义)。

    有一个特殊的条件:"如果我希望一个新接口成为现有接口的子接口,该怎么办?".在上述条件下,子接口扩展父接口。


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

    有关详细信息


    实现用于接口,扩展用于扩展类。

    为了让它更清晰,更简单地说,一个界面就像它听起来-一个界面-一个模型,你需要应用,遵循,连同你的想法到它。

    extend用于类,这里,通过向类中添加更多功能来扩展已经存在的内容。

    还有几条注释:

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

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


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

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

    但是当我们扩展任何东西时,它就变成了类的扩展。您可以更改它、使用它、重用它,并且它不必像在超类中那样返回相同的值。


    使用Java语言创建自己的新类时,都使用了两个关键字。

    差异:EDCOX1(1)意味着你在你的类中使用Java接口的元素。extends意味着您正在创建要扩展的基类的子类。在子类中只能扩展一个类,但可以实现任意多个接口。

    有关详细信息,请参阅界面上的"Oracle文档"页。

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


    在最简单的术语中,扩展用于继承类,实现用于在类中应用接口。

    延伸:

    1
    2
    3
    4
    5
    6
    public class Bicycle {
        //properties and methods
    }
    public class MountainBike extends Bicycle {
        //new properties and methods
    }

    工具:

    1
    2
    3
    4
    5
    6
    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.htmlhttps://docs.oracle.com/javase/tutorial/java/iandi/usinginterface.html网站


    只有当子类想要使用一些已经在超类中声明的功能(方法或实例变量),或者如果我想稍微修改超类的功能(方法重写),我们才使用子类扩展超类。但是,比如说,我有一个动物类(超类)和一个狗类(子类),并且我在动物类中定义的方法很少,例如doeat();,dosleep();…还有更多。

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

    现在,想象一下,有一天,某个爱猫的人来到我们的工作区,她试图延长动物课程(猫也吃和睡)。她创建了一个cat对象并开始调用这些方法。

    但是,比如说,有人试图成为动物类的一个对象。你可以告诉猫睡得怎么样,你可以告诉狗吃得怎么样,你可以告诉大象喝得怎么样。但是,把动物类作为一个对象是没有意义的。因为它是一个模板,我们不想要任何一般的饮食方式。

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

    总之,接口只是一个抽象类(纯抽象类),它不包含方法实现,只包含定义(模板)。因此,任何实现接口的人都知道他们有doeat();和dosleep()的模板;但是他们必须根据需要定义自己的doeat();和dosleep();方法。

    只有当您希望重用超类的某些部分(但请记住,您始终可以根据需要重写超类的方法)时才进行扩展,并且当您希望模板并且希望自己定义它们(根据需要)时才进行实现。

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    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

    }


    }

    定义的接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public interface AnimalInterface {

    public void eating();

    }


    interface Herbi {

    public void herbiEating();

    }

    当需要子类/接口中父类/接口的属性时,使用Extends;当需要类中接口的属性时,使用implements

    例子:

  • 使用类扩展

    类父代{

    }

    类子扩展父级{

    }

  • 使用接口扩展

    接口父级{

    }

    子接口扩展父接口{

    }

  • 器具

  • 接口A

    }

    B类实现A{

    }

    扩展和工具的组合

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    interface A{

    }

    class B

    {

    }

    class C implements A,extends B{

    }