Ответ 1
Вы более или менее правы относительно большинства фактов, которые вы указали, если вы посмотрите на них глазами ООП. Но у нас их больше.
Объект
Объекты в Scala видны с точки зрения функционального программирования в качестве модулей. Они служат для объединения аналогичных функций, которые вы назвали "служебными функциями". Но они также имеют дополнительные значения.
An object
можно рассматривать как одноэлементный объект, так как вы можете иметь object
, который наследует конкретный trait
или class
.
trait Bird
object Duck extends Bird
У вас также есть понятие сопутствующего объекта. Это объект, который имеет функции модуля, связанные с этим классом, и вы даже можете ссылаться на private
членов объекта из класса.
class Dog {
def eat(food: Food) = Dog.preferredFoods.contains(food)
}
object Dog {
private val preferredFoods = List(Ribeye, DogFood, Banana)
def walk(dog: Dog) = ???
}
Класс
Вы правы в занятиях. Они очень близки к понятию Java.
Тре
Один из способов просмотра trait
в Scala - это abstract class
. Но обратите внимание, что вы также можете иметь abstract class
в Scala, с тем же поведением, что и в Java. Итак, какая разница?
Как указано в комментарии, несколько trait
могут быть смешаны вместе.
Также trait
можно рассматривать как Java interface
, если он полностью абстрактный, то есть все методы абстрактны, как с Java. На самом деле, если вы нацеливаетесь на взаимодействие с Java, это способ объявить interface
.
A sealed trait
- это просто способ сообщить компилятору, что у вас не будет классов или других признаков, наследующих этот, кроме тех, которые находятся в одном файле. Это служит для сопоставления шаблонов, как вы отметили классы case, поэтому компилятор может определить, является ли соответствие шаблона исчерпывающим с предупреждением. Но также обратите внимание, что Scala имеет enum
.
Класс класса
Классы классов могут использоваться с sealed trait
для соответствия шаблону. Но case class
больше похож на "класс значений". case
заставляет компилятор генерировать кучу кода шаблона, поэтому вам не нужно.
У вас есть автоматический "объект-компаньон", поэтому вы можете создать объект без new
с автоматически созданной функцией apply
.
У вас есть автоматические реализации hashCode
, equals
, toString
и copy
. И у вас есть автоматический val
для всех параметров конструктора.
scala> case class Room(area: Int)
defined class Room
scala> var r = Room(16)
r: Room = Room(16)
scala> r.hashCode
res2: Int = 1313771839
scala> r == Room(16)
res3: Boolean = true
scala> r == Room(15)
res4: Boolean = false
scala> r.toString
res5: String = Room(16)
scala> r.area
res6: Int = 16
scala> case class Point(x: Int, y: Int)
defined class Point
scala> val p = Point(1, 1)
p: Point = Point(1,1)
scala> val p1 = p.copy(y = 0)
p1: Point = Point(1,0)