实现vs扩展:何时使用? 有什么不同?
请用易于理解的语言或某篇文章的链接来解释。
extends
是为了扩展一个类。
implements
是为了实现一个接口
接口和常规类的区别在于,在一个接口中,你不能实现任何声明的方法。 只有“实现”接口的类才能实现这些方法。 一个接口的C ++等价物将是一个抽象类(不完全相同,但非常相似)。
另外java不支持类的多重inheritance 。 这是通过使用多个接口解决的。
public interface ExampleInterface{ public void do(); public String doThis(int number); } public class sub implements ExampleInterface{ public void do(){ //specify what must happen } public String doThis(int number){ //specfiy what must happen } }
现在扩大class级
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
我build议你在dynamic绑定,多态性和面向对象编程中的一般inheritance方面做更多的研究
我注意到你的configuration文件中有一些C ++的问题。 如果你理解C ++的多重inheritance的概念(指的是inheritance超过一个其他类的特性的类),Java不允许这样做,但是它具有关键字interface
,就像C ++中的纯虚拟类。 正如许多人提到的,你extend
了一个类(你只能从一个类扩展),并且implement
了一个接口 – 但是你的类可以实现尽可能多的接口。
也就是说,这些关键字及其使用规则描述了Java中多重inheritance的可能性(只能有一个超类,但可以实现多个接口)。
当你从一个基类inheritance时(即扩展它的function),扩展是。
implements
是为了当你实现一个接口 。
这是一个很好的开始: 接口和inheritance 。
一个class
只能“实现”一个interface
。 一个类只“扩展”一个class
。 同样,一个interface
可以扩展另一个interface
。
一个class
只能扩展一个class
。 一个class
可以实现多个interface
。
相反,如果您更了解何时使用abstract class
和interface
s,请参阅此线程: 接口与抽象类(通用OO)
一般用于实现接口的实现, 扩展用于扩展基类行为或抽象类。
扩展 :派生类可以扩展基类。 你可能会重新定义已build立关系的行为。 派生类是 “基类”types
执行 :您正在执行合同。 实现接口的类“ 有一个 ”的能力。
在java 8版本中,接口可以在接口中有默认的方法,它在接口本身提供了实现。
请参阅此问题以了解何时使用它们:
界面与抽象类(通用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
需要了解的重点:
- 狗和猫是动物,他们通过分享
Animal
name,lifeExpentency
,延长remember
()和protectOwner
() - 猫可以爬()但狗不会。 狗可以认为()但猫没有 。 通过实现这些function,这些特定的function被添加到
Cat
。 - 人不是动物,但他可以
Think,Learn,Apply,Climb
通过这些例子,你可以理解这一点
无关的类可以通过接口具有function,但相关的类通过扩展基类来覆盖行为。
一个接口是一个对象可以做的动作的描述…例如,当你打开一个灯开关时,灯会亮,你不在乎怎么做。 在面向对象编程中,接口是对象为了成为“X”而必须具有的所有function的描述。 再举一个例子,任何一个“作用”灯都应该有一个turn_on()方法和一个turn_off()方法。 接口的目的是允许计算机执行这些属性,并且知道typesT(无论接口是什么)的对象必须具有称为X,Y,Z等的函数
接口是一种编程结构/语法,允许计算机在对象(类)上执行某些属性。 比如说,我们有一个汽车class,一个滑板车class和一个卡车class。 这三个类中的每一个都应该有一个start_engine()动作。 每个车辆的“引擎启动”是如何留给每个特定的类别的,但是他们必须具有start_engine动作的事实是接口的领域。
-
A延伸B:
A和B都是类或两个接口
-
A实现B.
A是一个类,B是一个接口
-
A是接口而B是类的其余情况在Java中是不合法的。
实现用于接口,扩展用于扩展一个类。
为了使它更清晰一些,界面就像声音 – 一个界面 – 一个模型,你需要应用,跟随你的想法。
Extend用于类,在这里,你正在扩展一些已经存在的东西,通过增加更多的function。
还有一些注意事项:
一个接口可以扩展另一个接口。
而当你需要在实现一个接口或者为特定场景扩展一个类之间进行select时,请去实现一个接口。 因为一个类可以实现多个接口,但只能扩展一个类。
扩展 :用于将父类的属性获取到基类中,并可能包含已在子类中重写的已定义方法。
实现 :通过在子类中定义它来实现一个接口(只有函数签名的父类,但不包含它们的定义)。
有一个特殊的条件:“如果我想让一个新的接口成为现有接口的孩子呢? 在上述情况下,子接口扩展了父接口。
当一个子类扩展一个类时,它允许子类inheritance(重用)并覆盖在超types中定义的代码。 当一个类实现一个接口时,它允许一个从该类创build的对象被用在任何期望接口值的上下文中。
这里真正的问题是,我们正在实施任何事情,只是意味着我们正在使用这些方法。 它们的值和返回types没有改变的余地。
但是,当我们延伸任何东西,那么它就成为你们class级的延伸。 你可以改变它,使用它,重复使用它,它不一定需要像超类一样返回相同的值。
在使用Java语言创build自己的新类时使用这两个关键字。
差异: implements
意味着您正在使用您的类中的Java接口的元素。 extends
意味着您正在创build您正在扩展的基类的子类。 你只能在你的子类中扩展一个类,但是你可以实现尽可能多的接口。
有关更多详细信息,请参阅界面上的oracle文档页面。
这可以帮助澄清接口是什么,以及使用它们的惯例。
在最简单的术语中, extends用于从类inheritance, implements用于在类中应用接口
扩展 :
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
只有当子类想要使用已经在SuperClass中声明的一些function(方法或实例variables)时,或者我想略微修改SuperClass (方法重写)的function时,我们才使用SubClass extends SuperClass 。 但是,举个例子,我有一个Animal类( SuperClass )和一个Dog类( SubClass ),并且在Animal类中定义的方法很less。 doEat (); , doSleep (); … 还有很多。
现在,我的Dog类可以简单地扩展Animal类,如果我想让我的狗使用Animal类中声明的任何方法,我可以通过简单地创build一个Dog对象来调用这些方法。 所以这样我可以保证我有一只狗可以吃,睡觉,做任何我想要的狗做的事情。
现在想象一下,有一天,一些猫爱好者进入我们的工作空间,她试图扩展动物类(猫也吃和睡)。 她制作一个Cat对象并开始调用这些方法。
但是,也就是说,有人试图制作一个动物类的对象。 你可以告诉猫如何睡觉,你可以告诉狗如何吃,你可以告诉大象如何喝。 但是在制作Animal类的对象时没有任何意义。 因为它是一个模板,我们不想要任何一般的饮食方式。
所以相反,我更喜欢创build一个抽象类,这个类没有人可以实例化,但可以用作其他类的模板。
因此总而言之,Interface只不过是一个抽象类(一个纯粹的抽象类),它不包含方法实现,而只包含定义(模板)。 所以实现这个接口的人只知道他们有doEat ()的模板; 和doSleep (); 但他们必须定义自己的doEat (); 和doSleep (); 方法根据他们的需要。
只有当你想要重用SuperClass的某些部分时(但请记住,你可以根据你的需要总是覆盖你的SuperClass的方法),并且当你想要这些模板时你需要实现,并且你想自己定义它们(根据你的需要)。
我将与您分享一段代码:您可以尝试使用不同的input集并查看结果。
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(); }
如下图所示,一个类扩展了另一个类,一个接口扩展了另一个接口,但是一个类实现了一个接口。
欲了解更多详情