2016-06-29 15 views
-4

etwas über diesen Code verwirrt mich. Die erste Druckzeile ist 1600. Ich verstehe, dass es etwas mit der statischen Klasse zu tun hat, die Auto und nicht Sportwagen ist. Aber wir haben das Objekt als Sportwagen erschaffen, warum also nicht das Volumenfeld 3500? Vielen Dank.Confusing Java-Code - im Zusammenhang mit statischer Bindung

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 gegossen -a-way-to-override-class-variables-in-java –

+0

Bitte bearbeiten Sie Ihre Post, um nur gültigen Code zu enthalten - dh die Zeilennummern loszuwerden. –

Antwort

1

Wenn Sie erklären, was auf diese Weise:

ParentClass variable = new ChildClass(Args); 

Die Methoden und Felder in ParentClass sind die Einzigen, die Ihnen zur Verfügung. Es ist eingeschränkt, weil Sie den Typ als ParentClass deklariert haben. Da Car ‚s Volumen 1600 und das Objekt wird auf die ParentClass beschränkt‘ s Methoden und Felder, druckt es 1600.

Ein Beispiel wäre wie folgt:

Betrachten Ich hatte eine Apple-Klasse und eine Frucht Klasse :

public class Fruit { 
    private String type; 

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

    public String getType() { 
     return type; 
    } 
} 

und das Apple-Klasse:

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; 
    } 
} 

Und jetzt instanziiert ich wie folgt aus:

Fruit ap = new Apple("Fiji"); 

Ich habe keinen Zugriff auf getVariant() oder alle Methoden in der Apple-Klasse, weil die Art der Elternklasse ist, nicht von Apple. Ich könnte getType() tun, aber das ist es.

In Ihrem Fall:

public class SportsCar extends Car { 
    public int volume; 

    SportsCar() { 
     this(3000); 
    } 

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

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

Obwohl SportsCar seiner eigenen Konstruktor hat und nimmt seine eigene Band, die Elternklasse Car ist der tatsächliche Typ, wodurch der Car Konstruktor aufgerufen werden, damit volume-1.600 Einstellung. So geben Sie eine SportsCar Objekt, dies tun:

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

Dies ausdrucken:

SportsCar:3500 

Sie können typisieren es auch etwa so:

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

Danke, ich sehe jetzt warum das Volumen von Car gedruckt wird, aber wann haben wir es auf 1600 gesetzt? – Gray

+0

@Bar Sie setzen es in den Standardkonstruktor und meins ist ein Beispiel :) – Li357

1

Also hier der Punkt ist, dass, wenn Sie car.volume verwenden, Auto-Variable vom Typ Auto und Objektreferenz ist vom Typ SportsCar.

Da beide Klassen das gleiche Element mit dem Namen Volumen haben und Sie versuchen, es durch übergeordnete Objektvariable zu verweisen, ist es Rückkehr 1600.

Wenn Sie typisieren und dann die Lautstärke überprüfen, wird es zurückgeben 3500 als pro unter code:

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

Aman Chhabra Antwort ist richtig. Sie haben ein SportCar-Objekt aus der Car- "Familie" erstellt. Und was Sie drucken, ist das Volumen des Autos, nicht das Volumen von SportCar.

Eine andere Möglichkeit besteht darin, ein SportsCar-Objekt anstelle von Auto zu erstellen.

P. S: Sie sollten immer geben Sie Ihre Klassenattribute als privat :)

+0

Wenn Sie mit jemandem einverstanden sind, upvote sie. Schreibe keine Antwort. – Li357

2

Zunächst einmal, beachten Sie, dass, wenn Sie den Konstruktor für SportsCar Java rufen Sie den Standard-Konstruktor für seine Elternklasse automatisch aufrufen, Car. Dadurch wird das Feld volume der übergeordneten Klasse Car des Objekts auf 1600 gesetzt.

In Java gibt es keinen Polymorphismus für Felder. Während also die toString()-Methode in Ihrer -Klasse immer die der übergeordneten Klasse (Car) überschreibt, unterscheiden sich die Regeln für den Zugriff auf gleichnamige Instanzvariablen etwas.

Wenn Sie innerhalb der SportsCar-Klasse auf volume zugreifen, wird die volume von SportsCar verwendet. Von außerhalb der Klasse selbst (also wenn Sie von CarApplication aufrufen), auf welche Instanzvariable zugegriffen wird, hängt von dem Kompilierungszeit Typ des fraglichen Objekts ab. Da Sie den Typ car als Car deklarieren, wird der Wert volume der übergeordneten Klasse Car verwendet - daher wird 1600 gedruckt. Wenn Sie stattdessen car als SportsCar deklariert hätten, würde 3500 gedruckt.

wäre Eine andere Möglichkeit dies:

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

Dies wird Ausgabe 3500, da die Art der car hat SportsCar.