2016-07-27 1 views
0

Я пытаюсь научить scala. Я пытался реализовать Наследование и наткнулся на небольшую проблему. Может ли кто-нибудь помочь мне с этим?Невозможно переопределить метод из дочернего класса в scala

Вопрос:

  1. В приведенном ниже коде, почему я не могу установить значение х для объектов p6, Р7 и Р8.
  2. Почему я не могу переопределить def setX в моем дочернем классе?
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

Вас не так много интересует классы, неизменяемость и черта Scala. Я бы предложил вам получить хорошую книгу или учебник по темам thesz – cchantep

+0

Да @cchantep Я согласен. Я думаю, что учебник, который я выполнял, не очень помогает мне. Ясно, что мне не хватает подробностей. Можете ли вы предложить хорошие книги или указать мне на некоторые хорошие документы? – HKrishnan

ответ

0

class ThreeD (x: Int, y: Int, z: Int) extends Point (x, y) делает не объявить класс с тремя членами. x, y и z являются не членами класса ThreeD, они являются аргументами-конструкторами. (Вы бы объявили их как (val x: Int, val y: Int, val z: Int), если вы хотели, чтобы они были участниками ... или, скорее, (override var x: Int, override var y: Int, val z: Int) в этом случае ... но не делайте этого - см. Ниже).

Потому что в scala конструктор классов - это почти все тело класса, иногда трудно сказать разницу: вы можете ссылаться на параметры конструктора в любом месте внутри тела класса, как если бы они были членами.

Это только начинает иметь значение, когда члены изменяются (не очень хорошо в целом, вы не хотите иметь изменчивых членов как вопрос политики). здесь:

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

x, y и z см с параметрами конструкторы, не переопределенными членами Point. p8.setX call делает изменяет значение члена xp8, но это не то, что p8.toString prints - он печатает значение аргумента конструктора, которое равно 2.

Забирать от этого:

  1. Избегайте использования изменяемых членов. Вы очень редко нуждаетесь в этом в scala. Если вы думаете, что вам это нужно ... подумайте еще раз.

  2. Не указывайте аргументы конструктора тем же именам, что и члены, которые они инициализируют, особенно если вы планируете получить к ним доступ внутри тела класса. Если вы это сделаете, объявите их как override val x, а не только x.

+0

Пара вещей, которые я наблюдал 1. Родительские члены класса и дочерние классы должны иметь одинаковое имя. В противном случае жалобы scala не могут найти переменную 2.Я не могу переопределить элемент в дочернем классе в конструкторе 'class ThreeD (переопределить var a: Int, переопределить var b: Int, c: Int) extends Point (a, b) {' Я получаю следующая ошибка 'error: переопределяющая переменная a в классе Point типа Int; Значение a не может переопределить изменчивую переменную. – HKrishnan

+0

1. Я не знаю, что вы подразумеваете под «должно быть одноименное имя». У вас наверняка есть члены класса с разными именами :) 2. Действительно, вы не можете переопределить 'var', потому что это не имеет никакого смысла: он изменен, и в любом случае он должен быть одного и того же типа, переопределение его будет иметь тот же эффект, что и просто присвоение ему другого значения. – Dima

Смежные вопросы