2017-08-29 25 views
0

Je pratique ce code depuis JavaTpoint pour apprendre l'héritage dans Scala. Mais je ne peux pas accéder au membre Bike de la classe Vehicle dont la valeur est initialisée à zéro. J'ai essayé par super référence de type mais il montre toujours la valeur remplacée. Pourquoi ne permet-il pas d'accéder au champ de super classe et dirige vers le champ de sous-classe surchargé (vitesse). voici le code et la sortie. En remerciant d'avance.Scala: Pourquoi ne pouvons-nous pas faire super.val?

class Vehicle { 
    val speed = 0 
    println("In vehicle constructor " +speed) 
    def run() { 
    println(s"vehicle is running at $speed") 
    } 
} 

class Bike extends Vehicle { 
    override val speed = 100 
    override def run() { 
    super.run() 
    println(s"Bike is running at $speed km/hr") 
    } 
} 

object MainObject3 { 
    def main(args:Array[String]) { 
    var b = new Bike() 
    b.run() 
    var v = new Vehicle() 
    v.run() 
    var ve:Vehicle=new Bike() 
    println("SuperType reference" + ve.speed) 
    ve.run() 
    } 
} 

How do I get the result using instance of Bike.

Répondre

1

Comme nous le savons, après Scala décompiler, Scala sera transféré à bytecode Java, il est compatible avec pour JVM.

Et pour la classe Vehicle variables val speed, après compilez il est visible pour sa sous-classe Bike (la variable protected), nous pouvons voir la bytecode de Vehicle:

public Vehicle(); 
    Code: 
     0: aload_0 
     1: invokespecial #63     // Method java/lang/Object."<init>":()V 
     4: aload_0 
     5: bipush  10 
     7: putfield  #13     // Field speed:I 
     10: return 

Comme on peut le voir, il est initialisation du speed Valeur dans la méthode constructeur Vehicle.

et nous pouvons également trouver l'action init dans Bike méthode constructeur:

public Bike(); 
    Code: 
     0: aload_0 
     1: invokespecial #67     // Method Vehicle."<init>":()V 
     4: aload_0 
     5: bipush  100 
     7: putfield  #13     // Field speed:I 
     10: return 

il est pour la mise en 100speed dans la méthode constructeur.

donc quand init l'objet Bike, la valeur du champ speed a été mis à jour dans le 100superclassVehicle. donc super.val n'aura pas de sens là-dedans.

et il y a un autre besoin de chose à appeler: lorsque vous utilisez le super.speed directement dans votre sous-classe Bike, le compilateur jeter:

super may not be used on value speed 

donc cette erreur du compilateur jeté est également causée par la raison ci-dessus.

+0

"Comme nous le savons, après la compilation de Scala, il sera transféré au bytecode Java pour être compatible avec JVM." Cette phrase n'a aucun sens. Avez-vous utilisé google translator? – pedrofurla

+0

@pedrofurla,;) – chengpohi

3

réponses à des questions similaires ici overriding-vals-in-scala, ou ici cannot-use-super-when-overriding-values disent: Scala compiler does not allow to use super on a val

Pourquoi? La discussion dans le dernier lien pointe vers: SI-899. Et le premier commentaire dit là-bas: it was changed so that traits could override vals to be more uniform with classes