2017-01-18 15 views
4

私はJava認証の質問とその出力の種類から特定のコードを取得しました。ここでは、コード継承の予期しない出力

class Baap { 
    public int h = 4; 
    public int getH() { 
     System.out.println("Baap " + h); 
     return h; 
    } 
} 

class Beta extends Baap { 
    public int h = 44; 
    public int getH() { 
     System.out.println("Beta " + h); 
     return h; 
    } 
    public static void main(String[] args) { 
     Baap b = new Beta(); 
     System.out.println(b.h + " " + b.getH()); 
    } 
} 

出力されている。

Beta 44 
4 44 

私はそれがあることを期待していた。

4 Beta 44 
44 

は、なぜそれがこの出力を生成しますか?

+2

'System.out.println(bh +" "+ b.getH());'行を実行すると、単一の 'String'を' System.out.println'と 'getH'呼び出しに渡しています最初に完了しなければなりません。そうでなければ 'System.out.println'に渡す' String'はありません –

答えて

3

出力は2つの部分からなる:

  1. getH()
  2. 内部getH()によって生産ラインがmain()によって生産ラインの前に印刷されmain()

内部印刷ラインを印刷ライン、 mainが出力を終了する前にgetH()が終了しなければならないためです。

今、出力は明らかである:getHへの呼び出しがmain内部で行われる前4を評価されていても、それがgetH()後に戻ってきたを印刷します。

3

System.out.println(b.h + " " + b.getH())の前に何かを印刷するには、b.h + " " + b.getH()を評価する必要があります。

b.getH()Beta 44を出力するBetaのメソッドを呼び出します(基本クラスメソッドをオーバーライドするため)。

b.getH()(44)の結果にb.h(4)を追加し、4 44printlnとします。 bのコンパイル時の型は、Baap(基底クラス)であり、変数は上書きできないので

b.hは、基底クラス(4)のh変数の値を返します。一方、b.getH()は、メソッドがオーバーライドできるので、サブクラス(44)の変数hの値を返します。

0
public static void main(String[] args) { 
     Baap b = new Beta(); 
     System.out.print(b.h + " "); 
     System.out.print(b.getH()); 
    } 
+0

関数呼び出しのプロセスを理解する必要があります。 – vonzhou

+0

私は、あなたの答えの周りにいくつかの文脈を追加してほしいかもしれません。コードのみの回答は理解しにくいです。あなたの投稿にさらに情報を追加することができれば、これはAskerと将来の読者に役立ちます。 – RBT

1

答えがここにJLSである:

15.7.2。すべての||、& &条件演算子を除く演算子のオペランド(、と?:)は、操作自体のいずれかの部分が実行される前に完全に評価されるように表示されていることを操作

前にオペランドJavaプログラミング言語の保証を評価します。

副作用があり、そのメソッドを呼び出す式が完全に評価される前に1がを観察することができるgetH()あなたの方法。

String baapBetaStr = b.h + " " + b.getH(); 

A)文字列連結

B)その文字列を連結するために、メソッド呼び出し

そしてもちろん、すべての部分:2つの部分があるよう

最初に評価される必要があります。