2

シナリオは次のとおりです。-

class Canine{
  public void roam(){
    System.out.println("Canine-Roam");
  }
}

public interface Pet{    
  public abstract void roam();
}


class Dog extends Canine implements Pet{

  public void roam(){
    System.out.println("Dog Roam");
  }
  public static void main(String [] args){
    Dog adog = new Dog();
    adog.roam();
  }
}

JVMは、実行するメソッドを選択する際に混乱してはならないことを認識しています。つまり、どのメソッドがオーバーライドされるかを意味します。しかし、とにかく私は混乱しています。なぜこのプログラムはコンパイルされるのですか?

4

4 に答える 4

8

いいえ-同じメソッドをクラスに2回存在させることはできません。

インターフェイスは、特定のメソッドを実装するためのクラスの要件を宣言するだけです。実際にはそのメソッドを作成しません。

したがって、継承を通じてメソッドの実装を取得するクラスには、そのメソッドが定義されています。この(単一の)実装は、インターフェースの要件を満たします。

あなたの場合:

  1. Dogextendsは、 fromメソッドが使用可能であり、オーバーライドされない場合はDogオブジェクトのメソッドとして公開されるCanineことを意味します。roam()Canine
  2. しかし、Dogその後、スーパークラスのメソッドを独自の定義でオーバーライドroam()します。これは許可されていますが、呼び出される明確なメソッドは1つだけです。それroam()Dog、新しいオーバーライドです。
  3. Dogを実装します。これは、メソッドPetが必要であることを意味します。roam()そうです-したがって、これはこのインターフェースの有効な実装です。
于 2012-10-26T10:17:57.070 に答える
2

あなたのケースは完全に問題なく実行され、出力されますDog RoamDogこれは、クラス内の関数が実行されることを意味します。

Dogのメソッドは、インターフェイスで宣言された抽象メソッドを実装しており、偶然にもこのメソッドのメソッドシグネチャが親クラスと一致するため、コンパイル時エラーは発生しませんでした。

于 2012-10-26T10:20:21.983 に答える
1

私はあなたが2つのことを混同していると思います:

  • 実装:何が行われますか?参照:Canine.roam()およびDog.roam()
  • インターフェース:どのように呼び出しますか?見る:Pet.roam()

roam()2つのクラスに2つの「実装」があることは明らかです。

  • Canine.roam()
  • Dog.roam()

同じクラスに2つの同じメソッドが存在することはありません。

また、DogextendsCanineであるため、メソッドCanine.roam()がオーバーライドされました。関数代わりにmain()を使用します。 Dog.roam()

于 2012-10-26T10:31:02.293 に答える
0

Dogタイプのオブジェクトを作成し、それをDog参照タイプに割り当てました。
オーバーライド、ここでは何の関係もありません。犬から犬のクラスを拡張しましたが、どちらも2つの異なるタイプです。
コンパイル時に、コンパイラはメソッド定義が参照型に存在するかどうかをチェックします。それでおしまい。そしてそれはそこに存在しなければなりません。実行時に、JVMは最初に参照型のメソッドをチェックし、次に「参照型の」サブクラスに存在する同じメソッドのオーバーライドされたバージョンがあるかどうかを検出します。
存在する場合は実行されます。それ以外の場合は、参照型のメソッドが実行されます。

すなわち

Canine c=new Dog(); 

Dogのメソッドを実行します。

于 2012-10-26T11:06:33.040 に答える