Implements vs extends: When to use? What's the difference?
请用易于理解的语言或某篇文章的链接进行解释。
接口和常规类的区别在于,在接口中,不能实现任何已声明的方法。只有"实现"接口的类才能实现这些方法。一个接口的C++等价物是抽象类(不是完全相同,而是相当多)。
同样,Java不支持类的多重继承。这可以通过使用多个接口来解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
现在扩展类
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++中的纯虚拟类。正如许多人所提到的,你的
IE,这些关键字和管理它们的规则描绘了Java中多重继承的可能性(您只能拥有一个超级类,但可以实现多个接口)。
这里是一个很好的起点:接口和继承。
通常实现用于实现接口,扩展用于扩展基类行为或抽象类。
扩展:派生类可以扩展基类。您可以重新定义已建立关系的行为。派生类"是"基类类型
实施:您正在实施合同。实现接口的类"具有"功能。
使用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 |
要理解的要点:
通过这些例子,你可以理解
无关类可以通过接口拥有功能,但相关类通过扩展基类来覆盖行为。
一个
如果您更希望知道何时使用
接口是对对象可以执行的操作的描述…例如,当你拨动一个灯开关,灯就会亮起来,你不在乎它是怎么亮起来的,只是这样而已。在面向对象编程中,接口是对对象必须具有的所有函数的描述,以便成为"X"。同样,作为一个例子,任何"像"灯的东西都应该有一个turn-on()方法和一个turn-off()方法。接口的目的是允许计算机强制执行这些属性,并知道T类型的对象(无论接口是什么)必须具有称为X、Y、Z等的函数。
接口是一种编程结构/语法,允许计算机对对象(类)强制执行某些属性。例如,假设我们有一个汽车类、一个滑板车类和一个卡车类。这三个类中的每一个都应该有一个start_engine()操作。每辆车的"发动机是如何启动"留给每一个特定的类别,但他们必须有一个启动发动机操作这一事实是接口的领域。
A扩展B:
A和B都是类或两个接口
工具B
A是一个类,B是一个接口
在Java中,A是接口和B是一个类的其余情况是不合法的。
扩展:用于将父类的属性获取到基类中,并且可能包含已定义的方法,这些方法可以在子类中被重写。
实现:通过在子类中定义接口来实现接口(仅具有函数签名的父类,而不是它们的定义)。
有一个特殊的条件:"如果我希望一个新接口成为现有接口的子接口,该怎么办?".在上述条件下,子接口扩展父接口。
如下图所示,一个类扩展另一个类,一个接口扩展另一个接口,但一个类实现了一个接口。
有关详细信息
实现用于接口,扩展用于扩展类。
为了让它更清晰,更简单地说,一个界面就像它听起来-一个界面-一个模型,你需要应用,遵循,连同你的想法到它。
extend用于类,这里,通过向类中添加更多功能来扩展已经存在的内容。
还有几条注释:
一个接口可以扩展另一个接口。
当您需要在实现接口或为特定场景扩展类之间进行选择时,请转到实现接口。因为一个类可以实现多个接口,但只能扩展一个类。
当子类扩展类时,它允许子类继承(重用)并重写在父类型中定义的代码。当类实现接口时,它允许在任何需要接口值的上下文中使用从类创建的对象。
这里真正的问题是,当我们实现任何东西时,它仅仅意味着我们正在使用这些方法。它们的值和返回类型没有变化的余地。
但是当我们扩展任何东西时,它就变成了类的扩展。您可以更改它、使用它、重用它,并且它不必像在超类中那样返回相同的值。
使用Java语言创建自己的新类时,都使用了两个关键字。
差异:EDCOX1(1)意味着你在你的类中使用Java接口的元素。
有关详细信息,请参阅界面上的"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(); } |
当需要子类/接口中父类/接口的属性时,使用
例子:
使用类扩展
类父代{
}
类子扩展父级{
}
使用接口扩展
接口父级{
}
子接口扩展父接口{
}
器具
接口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{ } |