2016-12-30 19 views
-1

インスタンス変数を使用してインターフェイス変数をシャドーイングするときに問題があります。私はメソッドをオーバーライドし、メソッド内で変数を手動で割り当てることでこれを行う方法を知っていますが、メソッドを呼び出すオブジェクトのインスタンス化された変数を使用する方法を理解することはできません。インスタンス変数を使用してインターフェイス変数をシャドーする方法

public interface ShakesHands { 

    static final String name = "Gabe"; 

    public void shakeHands (ShakesHands other); 
} 

class Student implements ShakesHands{ 

    String name; 

    @Override 
    public void shakeHands(ShakesHands other) { 
     String othersName = other.name; 
     System.out.println(name + " shook " + othersName + "'s hand."); 
    } 
} 

class Parent implements ShakesHands{ 

    String name; 

    @Override 
    public void shakeHands(ShakesHands other) { 
     String othersName = other.name; 
     System.out.println(name + " shook " + othersName + "'s hand."); 
    } 
} 

public class App { 

    public static void main(String[] args) { 

     Student student1 = new Student(); 
     student1.name = "Bob"; 

     Parent parent1 = new Parent(); 
     parent1.name = "Sally"; 

     student1.shakeHands(parent1); 
    } 
} 

このコードは "Bob shook Gabe's hand"を出力します。インターフェース名 "Gabe"を参照するのをやめて、インスタンス名 "Sally"を参照して "BobがSallyの手を振った"ようにする方法はありますか?スタイルとクリーンなコードをコーディングに関する質問をともかく

+0

なぜ、 'ShakesHands'は最初に' name'を持っていますか? –

+0

フィールドに直接アクセスするのではなく、アクセサー(セッターとゲッター)を使用します。あなたの例はかなり疑わしいです。私はこのコーディングスタイルの有効な使用について考えることはできません。 – markspace

+0

ShakesHandsに名前を割り当てないと、 "名前を解決できないか、フィールドではありません"というエラーが発生します。 –

答えて

0

は、ここにあなたのコードは常にプリントは「...ゲイブの手を横に振った。」なぜです:

ShakesHandsインスタンスから手参照 『name』を振っのメソッド実装実装クラスの1つではありません。 ShakesHandsの唯一の "名前"はここでは "範囲内"なので、常に値 "Gabe"の静的変数を使用することになります。

実際には、実装するクラスの変数(そのような変数が存在する場合)を使用するのではなく、常に静的な変数の値を使用する方がコンパイラにとっては良い方法です。派生クラスまたは実装クラスのデータ型は、スーパークラス/インタフェースと同じである必要はありません。そのため、ShakeHandの名前を生徒の名前と異なるタイプにすることができます。

例:私の呼び出し例については

public interface ShakesHands { 

    String name = "Gabe"; 

    public void shakeHands(ShakesHands other); 
} 

class Student implements ShakesHands { 

    Integer name = Integer.valueOf(0); 

    @Override 
    public void shakeHands(ShakesHands other) { 
     System.out.println(name.getClass().getSimpleName() + " (in this class) with value "+name+" vs. " + other.name.getClass().getSimpleName()+" (in other class) with value "+other.name); 
    } 
} 

printetテキストは「値ゲイブと(他のクラスの)値7対文字列で(このクラスの)整数」でした。

もう1つのこと:プログラムのすべての実装では、実装クラスに「名前」変数があります。コンパイル時に、コンパイラは実行時にそれが当てはまるかどうかを知りません。あなたのJARは、 "名前"変数を持たない "無名習慣"クラスを定義した別のプログラムで使用されるかもしれません。その後何が起こるはずですか?実装クラスが別のクラスで "名前"を定義した場合、コードにはどのようなことが起こりますか?あなたの "String othersName = other.name;"のために "ClassCastException"がスローされるべきですか?命令?

ショートストーリーを短くするには: "ShakesHands"インターフェースに "String getName()"メソッドを導入してください。各実装クラスは名前の変数値を返すことができ、すべてが問題ありません。

+0

また、コーディング規則に従ってください。定数は 'NAME'と綴られていて、混乱がなくなっていたはずです。 –

関連する問題