2016-07-27 13 views
0

Ich versuche scala selbst beizubringen. Ich versuchte, die Vererbung zu implementieren und stolperte über ein kleines Problem. Kann mir jemand dabei helfen?Konnte eine Methode von der Kindklasse in scala nicht überschreiben

Frage:

  1. In dem folgenden Code, warum bin ich nicht in der Lage für Objekte p6 Wert für x zu setzen, P7 und P8.
  2. Warum kann ich def defX in meiner Kindklasse nicht überschreiben?
object classes { 
    def main (args: Array[String]) { 
     //create objects for class Point 
     val p1 = new Point 
     println("P1 created using no argument constructor: "+p1.toString()) 

     val p2 = new Point 
     p2.setX(1) 
     println("P2 created using setter methods: "+p2.toString()) 

     val p3 = new Point(2) 
     println("P3 created using single argument constructor: "+p3.toString()) 

     val p4 = new Point(3,1) 
     //demonstrating how to use objects within println statement 
     println(s"P4 is created using default constructor and its x value is ${p4.getX} its y value is ${p4.getY} and its id is ${p4.id}") 

     val p5 = new ThreeD 
     println("P5 is created using no argument constructor of 3D class: "+p5.toString) 

     val p6 = new ThreeD(2) 
     println("P6 is created using single argument constructor of 3D class: "+p6.toString) 

     val p7 = new ThreeD(2,3) 
     println("P7 is created using two argument constructor of 3D class: "+p7.toString) 

     val p8 = new ThreeD(2,3,4) 
     p8.setX(5) // has no effect.. why?? 
     println("P8 is created using default constructor of 3D class: "+p8.toString) 
    } 

    //The class name works as a class constructor which can take a number of parameters. 
    class Point (var x: Int, var y: Int) { 
     //demonstrating how to protect the values 
     this.setX(x) 

     /* 
     Scala does not have static methods or static variables. 
     However we can mimic its behavior. 

     Outside the scope of the class, create a companion object for the class 
     Companion objects has same name as that of the class and holds the static members and functions. 
     */ 

     val id = Point.getId 

     //lets define getters and setters 
     def getX() : Int = x 
     def getY() : Int = y 

     def setX(x: Int) { 
      this.x = x 
     } 

     //this is how we override a function 
     //here we implement our custom toString() method 
     override def toString() : String = { 
      return "(%d, %d) and id is %d".format(this.x, this.y, this.id) 
     } 

     //lets define other constructors 

     //to define a constructor, we create a method called "this" 
     //constructor with no arguments 
     def this() { 
      this(0,0) 
     } 

     //constructor with 1 value 
     def this (x: Int) { 
      this(0,0) 
      this.setX(x) 
     } 


    } 

    object Point { 
     //static member 
     private var id = 0 

     //static method 
     private def getId() : Int = { id += 1; id} 
    } 

    //Inheritance 
    class ThreeD (x: Int, y: Int, z: Int) extends Point (x, y) { 
     def this(x: Int, y: Int) { 
      this(0,y,0) 
      this.setX(x) 
     } 

     def this(x: Int) { 
      this(0,0,0) 
      this.setX(x) 
     } 

     def this() { 
      this(0,0,0) 
     } 

     //to override parent class's setX method 
     override def setX(x: Int) { 
      super.setX(x) 
     } 

     override def toString() : String = { 
      return "(%d, %d, %d) and id is %d".format(this.x, this.y, this.z, this.id) 
     } 
    } 
} 
+0

Sie vermissen viel über Scala Fallklassen, Unveränderlichkeit und Eigenschaft. Ich würde vorschlagen, Sie bekommen ein gutes Buch oder Tutorial über thesz Themen – cchantep

+0

Ja @cchanstep stimme ich zu. Ich denke, das Tutorial, dem ich folgte, hilft mir nicht wirklich. Klar, mir fehlen viele Details. Kannst du mir gute Bücher empfehlen oder mich auf ein paar nette Dokumente hinweisen? – HKrishnan

Antwort

0

class ThreeD (x: Int, y: Int, z: Int) extends Point (x, y) tut nicht eine Klasse mit drei Mitgliedern erklären. x, y und z sind nicht Mitglieder der Klasse ThreeD, sie sind nur Konstruktor Argumente. (Sie würden sie als (val x: Int, val y: Int, val z: Int) deklarieren, wenn Sie wollten, dass sie Mitglieder sind ... oder eher (override var x: Int, override var y: Int, val z: Int) in diesem Fall ... aber machen Sie das nicht - siehe unten).

Da der Klassenkonstruktor in scala so ziemlich der gesamte Körper der Klasse ist, ist es manchmal schwer, den Unterschied zu erkennen: Sie können Konstruktorparameter innerhalb des Klassenkörpers beliebig referenzieren, als wären sie Mitglieder.

Es beginnt erst, wenn die Mitglieder veränderbar sind (nicht eine gute Sache im Allgemeinen, Sie nicht wollen änderbare Mitglieder als eine Frage der Politik haben). Hier :

override def toString() : String = { 
    return "(%d, %d, %d) and id is %d".format(this.x, this.y, this.z, this.id) 
} 

x, y und z beziehen sich auf den Konstruktor Parameter, nicht die überschriebenen Mitglieder der Point. Anruf tut ändern Sie den Wert von Mitglied x von p8, aber es ist nicht, was druckt - es druckt den Wert des Konstruktorarguments, das 2 ist.

Die nehmen von dieser weg:

  1. Vermeiden Sie wandelbar Mitglieder. Das brauchen Sie sehr selten in Scala. Wenn du denkst, dass du es brauchst ... denke nochmal nach.

  2. Geben Sie den Konstruktorargumenten nicht die gleichen Namen wie die von ihnen initialisierten Elemente, insbesondere, wenn Sie darauf innerhalb des Klassenrumpfs zugreifen möchten. Wenn Sie dies tun, deklarieren Sie sie als override val x, nicht nur x.

+0

Einige Dinge, die ich beobachtet habe 1. Die übergeordneten Klassenmitglieder und untergeordneten Klassenmitglieder müssen den gleichen Namen haben. Sonst kann die Variable 2 nicht gefunden werden.Ich bin nicht in der Lage, das Mitglied in der Kindklasse im Konstruktor zu überschreiben 'Klasse ThreeD (überschreiben var a: Int, überschreiben var b: Int, c: Int) erweitert Punkt (a, b) {' Ich bekomme die Folgefehler 'Fehler: überschreiben Variable a in der Klasse Punkt des Typs Int; Wert a kann eine veränderbare Variable nicht überschreiben – HKrishnan

+0

1. Ich weiß nicht, was Sie unter "muss der gleiche Name sein" verstehen. Sie können sicherlich Klassenmitglieder mit verschiedenen Namen haben :) 2. In der Tat, Sie können 'var' nicht überschreiben, weil es keinen Sinn ergibt: es ist veränderbar, und es müsste sowieso der gleiche Typ sein, also, das Überschreiben hätte genau den gleichen Effekt, als würde man einfach einen anderen Wert zuweisen. – Dima