Javaでダウンキャスト+変数の引数を持つメソッドを呼び出します

Mukund銀行:

私が呼ぶときa.displayName("Test")、それはクラスアイスクリームのメソッドを呼び出します。displayName(String...s)この方法は、可変引数に取ります。出力-

test Icecream
test Faloodeh 
test Faloodeh:  Faloodeh
test Faloodeh:  Faloodeh

私は方法を変更する場合でも、displayName(String s)(私はコード内のそのセクションをコメントアウトしている)、それはクラスファールーデのメソッドを呼び出します。新しい出力-

test Faloodeh 
test Faloodeh 
test Faloodeh:  Faloodeh
test Faloodeh:  Faloodeh

私はそれが起こるん理由を知りたいと思いました。

class Icecream{
    public void displayName(String...s){
        System.out.println(s[0]+" "+"Icecream");
    }
    /*public void displayName(String s){
        System.out.println(s+" "+"Icecream");
    }
    */
    public void describe(String s) {
        System.out.println(s+" "+"Icecream: Ice cream");
    }
}
class Faloodeh extends Icecream {
    public void displayName (String s){
        System.out.println(s+" "+"Faloodeh ");
    }

    public void describe (String s) {
        System.out.println(s+" "+"Faloodeh:  Faloodeh");
    }
}
 class Test {
    public static void main(String arg[]) {
       Icecream a=new Faloodeh ();
       Faloodeh b=( Faloodeh)a;
        a.displayName("test");
        b.displayName("test");
        a.describe("test");
        b.describe("test");
    }
}

**編集 - **答えてくれてありがとう。別の疑いで私を助けてください。私はにコードを変更します -

class Icecream{
    public void displayName(String s){
        System.out.println(s+" "+"Icecream");
    }
    /*public void displayName(String s){
        System.out.println(s+" "+"Icecream");
    }
    */
    public void describe(String s) {
        System.out.println(s+" "+"Icecream: Ice cream");
    }
}
class Faloodeh extends Icecream {
    public void displayName (String...s){
        System.out.println(s+" "+"Faloodeh ");
    }

    public void describe (String s) {
        System.out.println(s+" "+"Faloodeh:  Faloodeh");
    }
}
 class Test {
    public static void main(String arg[]) {
       Icecream a=new Faloodeh ();
       Faloodeh b=( Faloodeh)a;
        a.displayName("test");
        b.displayName("test");
        a.describe("test");
        b.describe("test");
    }
}

さて、これは次のように出力 - 与えます

test Icecream
test Icecream
test Faloodeh:  Faloodeh
test Faloodeh:  Faloodeh

あなたはすべて説明したように、ここでBは、クラスファールーデの目的です。そして、displayName(String...s)クラスのファールーデはオーバーライドを取得していません。それでも出力で、それが表示さtest Icecreamなぜ?

スイーパー:

ここで重要なポイントは変化するということであるdisplayName(String... s)displayName(String s)原因displayName(String s)でメソッドFaloodehオーバーライドし、そのスーパークラスのメソッドを。

Icecream.displayName(String... s)そしてFaloodeh.displayName(String s)、彼らはお互いを上書きしないように、異なるシグネチャを持っています。しかし、一つを受け入れるように元を変更するStringだけで発生するオーバーライド原因と同じシグネチャを持つためにそれらの原因となります。

(:詳細はJavaでは、メソッド呼び出しは、大きく3つの段階で解決されているJLS 15.12、私はまた、より詳細に説明こちら):

  1. 適用可能な方法を検索するためのクラスを検索します。これは、あなたがメソッドを呼び出すされているオブジェクトのコンパイル時の型に基づいています。この場合は、aaコンパイル時の型があるIcecreamので、唯一、Icecreamsの方法を考えます"。それが見つからないことに注意してくださいdisplayName方法をFaloodehのコンパイル時の型があるためaですIcecream
  2. あなたが渡された引数に基づいて呼び出すメソッドのオーバーロードを決定します。ここで一つだけの選択肢があります。変更前と変更後の両方として、displayNameあなたが渡された引数と互換性のある唯一のオーバーロードです。
  3. あなたがメソッドを呼び出しているオブジェクトの実行時の型に基づいて呼び出すメソッドのどの実装を決定します。a実行時の型がありますFaloodeh変更前、displayNameでオーバーライドされていないFaloodeh、それはスーパークラスの実装を呼び出しますので、。変更後は、displayName上書きされてしまう、そうで実装がFaloodeh呼ばれています。

あなたの編集について:

コンパイル時の型があるため、この場合に、bであるFaloodeh、検索に対してクラスがあるFaloodeh(ステップ1)。しかし、あなたが与えた引数(ステップ2)に一致する2つの方法があります。

  • displayName(String...)ここで宣言されているFaloodeh、と。
  • displayName(String) これは継承されています。

そのようなAの状況では、コンパイラは常に変数アリティせずに過負荷を好みます - displayName(String)これは、明らかに指定されているJLS§15.12.2具体的には、ステップ2は、3つ以上のサブステップにさらに分割されます。最初のサブステップは、可変アリティ方法を可能にすることなく、方法を見つけようと、任意のサブステップは、任意の方法を発見した場合、残りのサブステップはスキップされます。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=410000&siteId=1
おすすめ