Andruhon
@Andruhon
Software Developer

Как работают val параметры с именами совпадающими с parameterless методами в Scala?

Допустим имеем такой код в scala worksheet:
class Point (val x: Int, val y: Int)

trait Rectangular {
  def topLeft: Point
  def bottomRight: Point
  def left = topLeft.x
  def right = bottomRight.x
  def width = right - left
  override def toString = topLeft.x + ", " + topLeft.y + " - " + bottomRight.x + ", " + bottomRight.y
}

class Rectangle(val topLeft: Point, val bottomRight: Point) extends Rectangular

val rect = new Rectangle(new Point(1,1), new Point(10, 10))
//rect: Rectangle = 1, 1 - 10, 10

rect.width
//res0: Int = 9


Не совсем понятно как раскрывается часть кода в классе Rectangle. Документация говорит, что мы не можем иметь поле и parameterless метод с одинаковым именем в одном классе. Здесь возникает вопрос, что происходи с функциями topLeft и bottomRight в момент когда определяется класс Rectangle?

Я полагаю, что класс Rectangle на самом деле подразумевает следующее
class Rectangle(override val topLeft: Point, override val bottomRight: Point) extends Rectangular

и override просто опущены, поскольку оригинальные методы в Rectangular являются абстрактными.

Как вы можете пояснить происходящее в этом коде?
  • Вопрос задан
  • 147 просмотров
Решения вопроса 1
Конструкция
class Rectangle(val topLeft: Point, val bottomRight: Point)

подразумевает под собой, что для класса сгенирируется конструктор с параметрами topLeft, bottomRight, в классе будут созданы соответствующие поля, и для этих полей сгенерируются геттеры, с теми же названиями.
В случае когда мы обращаемся к полю по сути мы обращаемся всё равно к геттеру. И в данном случае этот геттер будет иметь соответствующее описание, подходящее под def topLeft: Point.

Соответственно никаких противоречей не возникает, у нас есть геттер, который подходит под интерфейс класса от которого мы наследуемся. Если же мы объявим класс, например, как:
class Rectangle(val topLeft: Int, val bottomRight: Point) extends Rectangular

То программа не скомпилируется, соответственно.

Если углубиться глубже то на самом деле скала старается на различать val и def. Это оба равноправные объявления. Отличие между ними заключается в стратегии исполнения. Подробнее:
https://class.coursera.org/progfun-005/lecture/4
https://class.coursera.org/progfun-005/lecture/5
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы