2016-06-19 8 views
1

現在、私はJAVAプログラミング言語を学んでいます。JAVAプログラムの出力[多型、メソッドのオーバーライド]

class Base{ 
    void g(){ 
    System.out.print("g-Base "); 
    } 
    void f(){ 
    System.out.print("f-Base "); 
    g(); 
    } 
} 
class Derived extends Base{ 
    public static void main(String[] args) { 
     Base b = new Derived(); b.f(); 
    } 
    void g() { 
     System.out.print("g-Derived "); 
    } 
    void f() { 
     System.out.print("f-Derived "); super.f(); 
    } 
} 

質問は次のとおりです:このプログラムの出力が何であるかを私の講師のメモでは、私は次のコードスニペットを見つけました。 f-Derived f-Base g-Derived 私はf-Derivedとf-Baseの部分を理解していますが、なぜ最後のステップで "g-Derived"を印刷したのですか? "g-Base"であった。

+0

'' 'Base b = new Derived();と同じです。 b.g(); '' 'g-Derived''を表示します。 –

+0

はい、コードがsuper.f()にジャンプしてそこからg()を呼び出すと、スーパーからg()を呼び出す必要はありませんか? – SalysBruoga

+0

いいえ、 '' 'this''すなわち' '' this.g() '' 'の動的呼び出し(実行時に起こります)です。 '' 'this''は動的型' 'Derived''を持っているので、' 'Derived :: g'''が呼び出されます。 –

答えて

1

は、コンパイラは、次のルールを知っている:メソッドはsuperキーワードなしで呼び出され

場合Derived バージョンを呼び出すが、方法がsuperキーワードで呼び出された場合Base バージョンを呼び出します。喜ん

だからsuper.f()f()Baseバージョンが呼び出された呼び出されたときしかしg()Baseバージョン内で呼び出されたときにこの呼び出しはsuperキーワードなしであるので(thisDerivedオブジェクトを参照暗黙thisキーワードで)コンパイラDerivedバージョンを呼び出し、出力はg-Derivedとなります。お役に立てれば。

+0

すごい説明!どうもありがとう! – SalysBruoga

2

はのは、実行の順序を追跡してみましょう:

  1. Derived#fが呼び出され、プリント ` "F由来" されます。
  2. Derived#fBase#fを意味するsuper.f()を呼び出します。
  3. Base#fプリント"f-Base"
  4. Base#fは、g()を呼び出します。 g()Derivedに上書きされているので、Derived#gが呼び出されます。
  5. Derived#gプリント"g-Derived"
+0

しかし、ベース#fがg()を呼び出すとき、それはベースの代わりにオーバーライドされたg()を使うべきであることをコンパイラが知っていますか?私はおそらくロジックの小さな部分が欠けていると思う。回答ありがとう: – SalysBruoga

関連する問題