2016-06-29 3 views
-4

quelque chose à propos de ce code me confond. La première ligne d'impression est 1600. Je comprends que cela a quelque chose à voir avec la classe statique étant Car et non Sportscar. Mais nous avons créé l'objet comme une voiture de sport, alors pourquoi ne pas le champ de volume 3500? Merci.Confondre code java - lié à la liaison statique

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

le type de car http://stackoverflow.com/questions/685300/is-there -a-way-to-override-classe-variables-in-java –

+0

S'il vous plaît [modifier] votre message ne doit contenir que du code valide - c'est-à-dire se débarrasser des numéros de ligne. –

Répondre

1

Lorsque vous déclarez quelque chose de cette façon:

ParentClass variable = new ChildClass(Args); 

Les méthodes et les champs dans ParentClass sont les seuls disponibles pour vous. Il est restreint car vous avez déclaré le type ParentClass. Parce que Car « le volume de est 1600 et l'objet est limité à la ParentClass » méthodes et les champs s, il imprime 1600.

Un exemple serait comme suit:

Tenez compte que j'avais une classe Apple et une classe de fruits :

public class Fruit { 
    private String type; 

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

    public String getType() { 
     return type; 
    } 
} 

et la classe d'Apple:

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

Et maintenant, j'instancier comme ceci:

Fruit ap = new Apple("Fiji"); 

Je n'ai pas accès à getVariant() ou des méthodes dans la classe d'Apple parce que le type est de la classe parente, et non d'Apple. Je serais en mesure de faire getType() mais c'est tout.

Dans votre cas:

public class SportsCar extends Car { 
    public int volume; 

    SportsCar() { 
     this(3000); 
    } 

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

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

Bien que SportsCar a son propre constructeur et prend son propre volume, la classe parente Car est le type réel, ce qui provoque le constructeur Car à appeler, la mise donc volume-1600. pour spécifier un objet SportsCar, faites ceci:

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

cette imprimera:

SportsCar:3500 

Vous pouvez également Typecast comme si:

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

Merci, je vois maintenant pourquoi le volume de Car est imprimé, mais quand l'avons-nous fixé à 1600? – Gray

+0

@Bar Vous le définissez dans le constructeur par défaut et le mien est un exemple :) – Li357

1

Ainsi, le point est que lorsque vous utilisez car.volume, variable voiture est de type voiture et référence d'objet est de type SportsCar.

Comme les deux classes ont le même élément nommé volume et que vous essayez de le renvoyer par variable d'objet parent, il revient 1600.

Si vous cataloguée et vérifiez le volume, il retournera 3500 comme par le code ci-dessous:

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

Aman Chhabra réponse est vrai. Vous avez créé un objet SportCar qui provient de la "famille" Car. Et ce que vous imprimez est le volume de voiture, pas le volume de SportCar. Un autre moyen consiste à créer un objet SportsCar au lieu de Car.

P.s: vous devez toujours définir les attributs de votre classe comme privé :)

+0

Si vous êtes d'accord avec quelqu'un, votez pour eux. Ne postez pas de réponse. – Li357

2

Tout d'abord, notez que lorsque vous appelez le constructeur pour SportsCar Java appellera automatiquement le constructeur par défaut pour la classe parente, Car. Cela définira le champ volume de la classe Car parent de l'objet à 1600.

En Java, il n'y a pas de polymorphisme pour les champs. Ainsi, alors que la méthode toString() dans votre classe SportsCar remplace toujours celle de sa classe parente (Car), les règles d'accès aux variables d'instance nommées de manière identique sont un peu différentes. Si vous accédez à volume depuis la classe SportsCar, le volume de SportsCar sera utilisé. De l'extérieur de la classe elle-même (donc lorsque vous appelez de CarApplication) quelle variable d'instance est accédée dépend du type de l'objet en question à la compilation. Parce que vous déclarez le type de car à Car, la valeur volume de la classe parente Car est utilisée - d'où 1600 est imprimé. Si vous aviez déclaré car comme étant SportsCar, 3500 seraient imprimés.

Une autre option serait la suivante:

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

Affichera 3500, a depuis été jeté à SportsCar.