2016-06-29 8 views
-4

このコードに関する何かが私を混乱させます。最初のプリントラインは1600です。私はそれがSportクラスではなく、Carである静的クラスと関係があることを理解しています。しかし、私たちはSportscarとしてオブジェクトを作成しました。なぜ、ボリュームフィールド3500はありませんか?ありがとう。Javaコードの混乱 - 静的バインディングに関連しています。

public class Car { 
public int volume; 

public Car() { this(1600); } 
public Car(int volume) { this.volume = volume; } 
public String toString() { return "Car:" + volume; } 
} 



public class SportsCar extends Car { 
public int volume; 

SportsCar() { this(3000); } 
SportsCar(int volume) { this.volume = volume; } 
public String toString() {return "SportsCar:"+volume;} 
} 



public class CarApplication { 
public static void main(String [] args) { 
Car car = new SportsCar(3500); 

System.out.println(car.volume); 
System.out.println(car.toString()); 
System.out.println(car); 
} 
} 
+0

http://stackoverflow.com/questions/685300/is-thereにキャストされていますので、この意志出力3500、:

別のオプションは、このことだろう-a-way-to-override-class-variables-in-java –

+0

あなたの投稿は有効なコードのみを含むように編集してください - つまり、行番号を取り除いてください。 –

答えて

1

あなたはこのように何かを宣言する場合:

ParentClass variable = new ChildClass(Args); 

ParentClassにおけるメソッドやフィールドが使用可能な唯一のものです。タイプをParentClassと宣言したため、制限されています。 Carのボリュームが1600で、オブジェクトがParentClassに制限されているのメソッドやフィールドなので、それが印刷さ1600

次のように例は次のようになります。

は、私はAppleのクラスとフルーツのクラスを持っていた考えてみましょう:

public class Fruit { 
    private String type; 

    public Fruit(String type) { 
     this.type = type; 
    } 

    public String getType() { 
     return type; 
    } 
} 

そしてアップルクラス:

public class Apple extends Fruit { 
    private String variant; 

    public Apple(String variant) { 
      System.out.println("I like " + variant + apples too!"); 
      super("Apple"); 
    } 

    public String getVariant() { 
      return variant; 
    } 
} 

そして今、私は次のようにインスタンス化します。

Fruit ap = new Apple("Fiji"); 

私はにアクセスすることはできません。アップルではなく、親クラスのタイプなので、アップルクラスにはアクセスできません。私はgetType()することができるだろうが、それはそれです。あなたのケースでは

public class SportsCar extends Car { 
    public int volume; 

    SportsCar() { 
     this(3000); 
    } 

    SportsCar(int volume) { 
     this.volume = volume; 
    } 

    public String toString() { 
     return "SportsCar:"+volume; 
    } 
} 

SportsCarは、それが自分のボリュームの独自のコンストラクタだと取る持っているが、親クラスCarは、1600年にvolumeを設定するため、呼び出されるCarコンストラクタを引き起こし、実際の型です。 SportsCarオブジェクトを指定するには、次の操作を行います。

SportsCar sc = new SportsCar(3500); 
System.out.print(sc.toString()); 

これは、プリントアウトします:

SportsCar:3500 

はまたそうのようにそれを型キャストすることができます

Car c = new SportsCar(1600); 
System.out.print(((SportsCar) c).toString()); 
+0

おかげさまで、なぜ車の量が印刷されているのか分かりますが、いつ1600に設定しましたか? – Gray

+0

@Barこれはデフォルトのコンストラクタで設定します。私は例です: – Li357

1

だからここでのポイントは、あなたがcar.volumeを使用しているとき、車の変数の型が車であり、オブジェクト参照が型スポーツカーであるということです。両方のクラスが同じ要素という名前のボリュームを持っていて、親オブジェクト変数を通してそれを参照するようにしようとしているとして、あなたは型キャストして、ボリュームをチェックする場合は

、それとして3500が返されます、1600

を返します以下のコードごと:

System.out.println(((SportsCar)car).volume); 
0

アマンチャブラの答えは正しいです。 Car "family"のSportCarオブジェクトを作成しました。そしてあなたが印刷しているのは、SportCarの量ではなく、Carの量です。

もう1つの方法は、Carの代わりにSportsCarオブジェクトを作成することです。

P.s:あなたは常にあなたのクラスはprivateとして属性を設定する必要があります:)

+0

あなたが誰かに同意するならば、それらをupvoteしてください。答えを投稿しないでください。 – Li357

2

まず第一に、あなたはSportsCarのコンストラクタを呼び出すときにJavaが自動的にその親クラス、Carのデフォルトコンストラクタを呼び出すことに注意してください。これにより、オブジェクトの親のCarクラスのvolumeフィールドが1600に設定されます。

Javaでは、フィールドの多型はありません。そのため、SportsCarクラス内のtoString()メソッドは常にその親クラス(Car)クラスのメソッドをオーバーライドしますが、同じ名前のインスタンス変数へのアクセス方法のルールは少し異なります。

SportsCarクラスからvolumeにアクセスする場合は、volumeSportsCarが使用されます。クラス自体の外から(したがって、あなたがCarApplicationから呼び出すとき)、どのインスタンス変数がアクセスされるかは、問題のオブジェクトのタイプのコンパイル時に依存します。 carのタイプをCarと宣言しているため、Carクラスのvolumeの値が使用されます。したがって、1600が出力されます。代わりにcarSportsCarと指定した場合は、3500が出力されます。

System.out.println(((SportsCar)car).toString());

carのタイプはSportsCar.

関連する問題