2012-01-13 10 views
0

次の問題があります。多相呼び出しを作成しようとしていますが、その結果は基底クラスに応じて値を変更する変数に依存します。しかし、それは動作しません別のものを試してみました。何が変わるべきか教えてください。多型呼び出しは変数に依存する

class Cycle{ 
    private int w = 0; 
    public void move(){ 
     System.out.println("Cycle moving"); 
    } 
    public int wheels(Cycle c){ 
     switch (c.w){ 

      case 1:  return 1; 
      case 2:  return 2; 
      case 3:  return 3; 
      default: return 0; 
     } 
    } 
} 
class Unicycle extends Cycle{ 
    public int w = 1; 
    public void go(){ 
     System.out.println("Unicycle go"); 
    } 
} 
class Bicycle extends Cycle{ 
    public int w = 2; 
    public void go(){ 
     System.out.println("Bicycle go"); 
    } 
} 
class Tricycle extends Cycle{ 
    public int w = 3; 
    public void go(){ 
     System.out.println("Tricycle go"); 
    } 
} 

public class TestCycle { 

    public static void ride(Cycle c){ 
     c.move(); 
     int now = c.wheels(c); 
     System.out.println(now); 

    } 

    public static void main(String[] args){ 
     Bicycle b = new Bicycle(); 
     ride(b); 
     Unicycle u = new Unicycle(); 
     ride(u); 
     Tricycle t = new Tricycle(); 
     ride(t); 
    } 

} 
+0

あなたのコードには本当に悪いことがあります:サブクラスで 'int w'を再宣言します。変数をシャドーイング(または隠す)と呼ばれています。私はなぜ言語のデザイナーがそれを許したのか理解していない。 – toto2

+1

また、あなたの3つのサブクラスに 'go'メソッドがあることは奇妙に見えます。彼らは 'go'メソッドを持つ何かのサブクラスでなければなりません。 – toto2

+0

@ toto2 'Cycle.w'はプライベートなので、それは働きます。それは継承者からは理解できません。したがって、シャドーイングはありません。 – Viruzzo

答えて

2

あなたの問題(そのうちの1つ)は、あなたのサブクラスのそれぞれでクラス変数 'w'を再定義していることです。それを 'Cycle'のメンバとして定義し、それぞれのサブクラスがそのコンストラクタで正しく設定されるようにします。

class Cycle{ 
    protected int w; 
    public void move(){ 
     System.out.println("Cycle moving"); 
    } 
    public int wheels(){ 
     return w; 
    } 
} 

class Unicycle extends Cycle{ 
    public Unicycle() { 
     w = 1; 
    } 
    public void go(){ 
     System.out.println("Unicycle go"); 
    } 
} 

スーパークラスで 'wheels()'という抽象メソッドを定義し、サブクラスでオーバーライドできます。それは味の問題です。

+0

この場合、 'w'は' private'ではなく 'protected'でなければなりません。それ以外の場合、サブクラスはアクセスできません。 – Poindexter

+0

ありがとうPoindexter、私はちょうどOPのコードをコピーして貼り付けていた – brain

+0

コンストラクタなしでそれを行う方法はありますか?むしろ多態的な方法が好きです。ありがとう – aretai

1

車輪方法がより

ようにすべきである:問題は、0に初期ここで0に適切なクラスからの1つは、常にデフォルト値を読み取るされ、wはCWは、ローカル変数の両方を読み出しがコードであるということです
public int getWheelCount(){ 
    return this.w; 
} 

インスタンスでインスタンスを呼び出すと、引数を渡す必要はありません。現在のインスタンスが三輪車の場合、メソッドは3などを返します。

+0

それはプライベートだからアクセスしないでください。 – Viruzzo

+0

Viruzzo、高すぎる、私はそれを逃したとは思わない。 – hvgotcodes

+0

私はそれを試みましたが、それでもCycleからwである0を返します。フルコードを表示できますか? – aretai

1

これはおそらくあなたが探している答えではありませんが、以下のように動作します。あなたがしようとしていることの詳細を教えてください。私はそれが今までインスタンス化したくないので、私はCycleabstractを作っ

public abstract class Cycle { 
    protected int nWheels; 
    protected String goText; 

    // no constructor. 

    public void go() { 
    System.out.println(goText); 
    } 

    public int wheels() { 
    return nWheels; 
    } 
} 
... 

public class Unicycle extends Cycle { 

    public Unicycle() { 
     nWheels = 1; 
     goText = "Unicycle go"; 
    } 
} 

注意。

EDIT

public static int getNumberOfWheels(Cycle cycle) { 
    return cycle.wheels(); 
} 

cycle.wheels()への単純な呼び出しはこの関数を呼び出すのと同じことをするだろうので、明らかに非常に有用ではありません。

コンストラクタを避けたい理由はわかりません。たぶんあなたは答えようとしている正確な質問を書くべきでしょう。

+0

はい、動作します。それぞれのクラスのコンストラクタを使わずに、適切なメソッドを使って作成する方法はありますか? – aretai

+0

私はあなたが何か他のことをしようとしていたと感じていました。私の編集を参照してください。 – toto2

1

Cycle.wはプライベートなので、継承者からは見えません。つまり、Tricycle.wは「同じ」変数ではなく、Cycleでは表示されません(そのため、常に0になります)。 Cycle.wを少なくとも保護し、すべてのサブクラスからwを削除し、各サブクラスのコンストラクタ内の値を必要なものに設定する必要があります。