実装と拡張:いつ使用するか?違いは何ですか?


回答:


735

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

オブジェクト指向プログラミングにおける動的バインディング、ポリモーフィズム、および一般的な継承についてさらに調査することをお勧めします


46
インターフェースには、メソッド宣言よりもはるかに多くの定数フィールド、アノテーション、インターフェース、さらにはクラスを含めることができます。
Philipp Reichart、

ルビのモジュールやミックスインのようなものですか?
user2492854

@ user2492854は少しですが、インターフェースに実装されたメソッドはありません。これは文字通りインターフェースの記述であり、実装ではありません。
ロブ・グラント

34
Java 8の新機能によりdefault、インターフェースでのメソッドの動作の実装が可能になり、それらのメソッドのカスタム実装がオプションになります。したがって、「メソッドのみを指定でき、それらを実装することはできません」という文は、Java 7以前では完全に正しいだけです。
ADTC、2014年

5
「extendsはクラスを拡張するためのものです」とは少し混乱します。インターフェイスをサインインし、インターフェイスも拡張します。例:public interface ListIterator<E> extends Iterator<E>
weiheng

78

プロファイルにC ++の質問があることに気づきました。C ++からの多重継承の概念(他の複数のクラスから特性を継承するクラスを指す)を理解している場合、Javaはこれを許可しませんがinterface、C ++の純粋な仮想クラスのようなキーワードを持っています。多くの人が述べたように、あなたextendはクラス(そしてあなたは1つからしか拡張できません)とあなたimplementはインターフェースです-しかしあなたのクラスは好きなだけインターフェースを実装することができます。

つまり、これらのキーワードとその使用を管理するルールは、Javaでの複数継承の可能性を示しています(スーパークラスは1つだけですが、複数のインターフェースを実装できます)。


51

一般に用具を実現するために使用するインターフェースを延びるために使用される拡張基底クラス挙動または抽象クラス。

extends:派生クラスは基本クラスを拡張できます。確立された関係の動作を再定義できます。派生クラス " "基本クラス型です

implements:契約を実装しています。インターフェイスを実装するクラスには、「」機能があります。

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

理解すべき重要なポイント:

  1. は動物であり、remember()とprotectOwner()から共有することで拡張さname,lifeExpentencyれましたAnimal
  2. 猫は登ることができますが、犬は登ることができません。犬はthink()できますが、猫はできません。これらの特定の機能が追加されているCatし、Dogその機能を実装することによって。
  3. 人間は動物ではありませんが Think,Learn,Apply,Climb

これらの例を見ると、あなたはそれを理解することができます

関連のないクラスはインターフェースを通じて機能を持つことができますが、関連するクラスは基本クラスの拡張を通じて動作をオーバーライドします。


1
非常によく説明されました。クリックしただけです。本当にありがとう!
Emir Memic 2016

本当にそうですか?「持っている」とは何かを持っていること、所有していることを指すといつも思っていました。その猫は登山能力を「持っている」と言うことができますが、私はあなたの例を言い換えます。猫は「クライマー」であり、男性は「シンカー」、「学習者、クライマー」です。男性は「シンカー」なので、思想家ができることを実行できます。いくつかのプロトコルを使用すると、さらに明確になります。家を持って、それはドアを持っていますが、それはpushingHandleを実装していないそれはまた重力に従うためのインタフェースを実装する意味、MaterialObject「ある」、それが「GravityObeyingSkill」または類似した何かを持っていません。。
MatthewRock

男が思想家であれば、私は実装ではなく拡張との関係を確立します。思想家にはいくつかの状態やその他の役割/機能があるかもしれませんが、私は思考機能をインターフェースのみで実装します。IS Aは、継承に使用される標準的な用語です。
Ravindra babu 2017年

@Ravindrababuこのような明確な説明に感謝します。
kanudo 2017年

1
説明しました!
2017


34

A classはのみを「実装」できinterfaceます。クラスはを「拡張」するだけclassです。同様に、interfaceは別のを拡張できinterfaceます。

A classが拡張できるのは1つだけclassです。Aはclass、いくつか実装することができますinterface秒。

代わりにabstract classesとinterfaces をいつ使用するかを知りたい場合は、次のスレッドを参照してください:インターフェイスvs抽象クラス(一般的なOO)


2
インターフェースを拡張することもできます。
Mark Peters、

2
class1つしか実装できませんinterface。はclass他のいくつかのクラスを拡張できます。私はあなたがこれを逆に得たと信じています。
pb2q

pb2qによるコメントを明確にするために、回答は既に編集/修正されています。「クラスは他の1つのクラスしか拡張できません。クラスは複数のインターフェースを実装できます」は正しい説明です。
wisbucky

29

インターフェースは、オブジェクトが実行できるアクションの説明です。たとえば、ライトスイッチを切り替えると、ライトが点灯します。どのように動作するかは関係ありません。オブジェクト指向プログラミングでは、インターフェイスは、オブジェクトが「X」になるために必要なすべての関数の記述です。繰り返しになりますが、例として、ライトの「ACTS LIKE」には、turn_on()メソッドとturn_off()メソッドが必要です。インターフェイスの目的は、コンピューターがこれらのプロパティを適用できるようにし、TYPE Tのオブジェクト(インターフェイスが何であれ)がX、Y、Zなどと呼ばれる関数を持っている必要があることを認識することです。

インターフェイスは、コンピューターがオブジェクト(クラス)に特定のプロパティを適用できるようにするプログラミング構造/構文です。たとえば、車のクラスとスクーターのクラスとトラックのクラスがあるとします。これら3つのクラスにはそれぞれ、start_engine()アクションが必要です。各車両の「エンジンの起動」方法は特定のクラスごとに任されていますが、start_engineアクションが必要なのはインターフェースのドメインです。


4
素晴らしい説明; より認識に値する。
Arvindh Mani 2017

22

以下の図に示すように、クラスは別のクラスを拡張し、インターフェースは別のインターフェースを拡張しますが、クラスはインターフェースを実装します。 ここに画像の説明を入力してください

詳しく


16

Extends:これは、親クラスの属性を基本クラスに取得するために使用され、子クラスでオーバーライドできる定義済みのメソッドを含むことができます。

実装:これは、子クラスで定義することにより、インターフェース(関数シグネチャのみで定義は含まない親クラス)を実装するために使用されます。

特別な条件が1つあります。「新しいインターフェイスを既存のインターフェイスの子にしたい場合」上記の条件では、子インターフェース親インターフェースを拡張します。


15
  • AはBを拡張します。

    AとBは両方ともクラスまたは両方のインターフェースです

  • AはBを実装

    Aはクラス、Bはインターフェース

  • AがインターフェースでBがクラスである残りのケースは、Javaでは無効です。


12

Implementsはインターフェイスに使用され、extendsはクラスの拡張に使用されます。

簡単に言えば、インターフェースは、サウンドのようなものです-インターフェース-モデル。アイデアに沿って、適用する必要があります。

Extendはクラスに使用されます。ここでは、機能を追加することにより、すでに存在するものを拡張します。

さらにいくつかのメモ:

インターフェースは別のインターフェースを拡張できます。

また、特定のシナリオに合わせてインターフェースを実装するか、クラスを拡張するかを選択する必要がある場合は、インターフェースを実装してください。クラスは複数のインターフェースを実装できますが、拡張できるのは1つのクラスだけだからです。


7

サブクラスがクラスを拡張すると、サブクラスはスーパータイプで定義されたコードを継承(再利用)およびオーバーライドできます。クラスがインターフェースを実装すると、そのクラスから作成されたオブジェクトを、インターフェースの値が必要なあらゆるコンテキストで使用できるようになります。

ここでの真の問題は、何かを実装している間は、それらのメソッドをそのまま使用しているということです。値と戻り値の型に変更の余地はありません。

しかし、何かを拡張する場合、それはクラスの拡張になります。これを変更、使用、再利用できます。スーパークラスと同じ値を返す必要はありません。


私は3年以上経った今、9月19日に私が書いたこの答えを読んでいます。私が書いたたわごとが理解できないことを私は誓います。今はもっと良い答えを書くことができました。奇妙なこと。
Nikhil Arora

7

私たちは、使用サブクラスが拡張するスーパークラスをサブクラスが既に宣言されているいくつかの機能(メソッドやインスタンス変数)を使用したい場合にのみ、スーパークラスを、または私は少しの機能を変更する場合は、スーパークラス(メソッドのオーバーライドを)。しかし、たとえば、Animalクラス(SuperClass)とDogクラス(SubClass)があり、Animalクラスで定義したメソッドがいくつかあるとします。doEat(); 、doSleep(); ... などなど。

これで、私のDogクラスは単にAnimalクラスを拡張できます。Animalクラスで宣言されているメソッドを犬に使用させたい場合は、Dogオブジェクトを作成するだけでそれらのメソッドを呼び出すことができます。このようにして、私は食べて寝ることができ、犬にしたいことを何でもできる犬がいることを保証できます。

想像してみてください。ある日、ある猫愛好家が私たちのワークスペースに来て、彼女は動物クラスを拡張しようとします(猫も食べて寝ます)。彼女は猫オブジェクトを作成し、メソッドの呼び出しを開始します。

しかし、たとえば、誰かがAnimalクラスのオブジェクトを作成しようとしています。猫の眠り方、犬の食べ方、象の飲み方がわかります。しかし、Animalクラスのオブジェクトを作成することには意味がありません。これはテンプレートであり、一般的な食べ方をしたくないからです。

したがって、代わりに、誰もインスタンス化できないが他のクラスのテンプレートとして使用できる抽象クラスを作成することを好みます。

結論として、インターフェースは抽象クラス(純粋な抽象クラス)にすぎず、メソッド実装は含まれておらず、定義(テンプレート)のみが含まれています。したがって、インターフェイスを実装する人は、doEat()のテンプレートを持っていることを知っています。およびdoSleep(); ただし、独自のdoEat()を定義する必要があります。およびdoSleep(); 彼らの必要性に応じた方法。

スーパークラスの一部を再利用する場合にのみ拡張します(ただし、必要に応じてスーパークラスのメソッドをいつでもオーバーライドできることに注意してください)。テンプレートが必要で、独自に定義する場合に実装します。 (必要に応じて)。

コードの一部を紹介します。さまざまな入力のセットで試して、結果を確認します。

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();

}

7

両方のキーワードは、Java言語で独自の新しいクラスを作成するときに使用されます。

違い: implementsクラスでJavaインターフェースの要素を使用していることを意味します。 extends拡張している基本クラスのサブクラスを作成していることを意味します。子クラスで拡張できるクラスは1つだけですが、必要な数のインターフェイスを実装できます。

詳細については、インターフェースに関するOracleのドキュメントページを参照してください。

これは、インターフェースとは何か、およびそれらの使用に関する規則を明確にするのに役立ちます。


7

最も簡単な用語では、extendsクラスから継承するために使用され、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


5

クラスインターフェースはどちらもコントラクトです。これらは、アプリケーションの他の部分が依存するメソッドとプロパティを提供します。

このコントラクトの実装の詳細に関心がない場合は、インターフェースを定義します。注意すべき唯一のことは、コントラクト(インターフェース)が存在することです。

この場合は、インターフェイスが実装されているクラスに任せて、コントラクトがどのように履行されるかについての詳細を考慮します。クラスのみがインターフェースを実装できます。

extendsは、既存の契約の詳細を置き換えたい場合に使用されます。この方法で、契約を履行する1つの方法を別の方法で置き換えます。クラスは他のクラスを拡張でき、インターフェースは他のインターフェースを拡張できます。


3

Extends子クラス/インターフェースに親クラス/インターフェースのimplements属性が必要な場合に使用され、クラスにインターフェースの属性が必要な場合に使用されます。

例:

  1. クラスを使用して拡張

    クラスParent {

    }

    クラス子は親を拡張します{

    }

  2. インターフェースを使用して拡張

    インターフェースParent {

    }

    子が親を拡張するインターフェース{

    }

  3. 実装

インターフェースA {

}

クラスBはA {

}

拡張と実装の組み合わせ

interface A{

}

class B

{

}

class C implements A,extends B{

}

2

伸びる

  • クラスは1つのクラスのみを拡張します
  • インターフェースは1つ以上のインターフェースを拡張します

実装する

  • クラスは1つ以上のインターフェースを実装します
  • インターフェイスは何も実装できません

抽象クラスも拡張および実装され、クラスのように機能します


0

これら2つのキーワードは、継承に直接関連付けられています。これは、OOPのコアコンセプトです。一部のクラスを別のクラスに継承する場合は、extendsを使用できます、一部のインターフェイスをクラスに継承する場合は、extendsを使用できません。implementsを使用extendsキーワードを使用し、別のインターフェイスからインターフェイスを継承できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.