Переопределение метода перечисления в Scala 3
Есть ли способ переопределить метод в перечислении Scala 3, как в Java?
public enum Test {
ONE {
@Override
public int calc() {
return 1;
}
},
TWO {
@Override
public int calc() {
return 2;
}
};
public abstract int calc();
}
Я пробовал что-то подобное, но безрезультатно. Также не нашел ничего о переопределении методов перечисления в документации.
enum Test {
def calc(): Int ={
0
}
case One
override def calc(): Int ={
1
}
case Two
override def calc(): Int ={
2
}
}
Может, есть другой способ добиться подобной функциональности?
3 ответа
Кажется, что то, что вы хотите, в настоящее время невозможно, но есть другие способы сделать это. Вы можете попробовать запечатанную черту старой школы с объектами, которые имеют приоритет.
sealed trait Test:
def calc: Int
object One extends Test:
def calc = 1
object Two extends Test:
def calc = 2
Функцию также можно сделать параметром
Test
, хотя мне этот способ меньше нравится.
enum Test(calc: () => Int):
case One extends Test(() => 1)
case Two extends Test(() => 2)
Другой способ сделать это - использовать один метод и сопоставление с образцом, как это сделали Джанлука Агуцци и Андрей Тюкин, хотя метод расширения не нужен.
Если
calc
должно быть функцией, я бы предложил первый подход или сопоставление с образцом, если вы считаете, что он вам больше подходит. Запечатанные черты также являются хорошим вариантом, если вы хотите переопределить несколько методов, поскольку вам не нужно отдельно выполнять сопоставление с образцом или объединять кучу лямбда-выражений в вызов конструктора. Если это не функция, мне кажется, лучше всего подойдет вторая.
В
enum
запечатан, поэтому не может быть продлен постфактум, поэтому нет никаких причин для чего-либо. Просто соберите все дела в одном месте, а вместо нескольких
override
-methods, напишите один единственный метод, который охватывает все случаи:
enum A:
case X(x: Int)
case Y(y: String)
def foo: String = this match {
case X(x) => s"X = ${x}"
case Y(y) => y
}
val x = new A.X(42)
val y = new A.Y("y")
println(x.foo) // X = 42
println(y.foo) // y
В scala 3 можно добиться аналогичного результата, комбинируя
enum
с участием
extension method
:
enum Test {
case One, Two
}
extension (test: Test)
def calc() : Int = test match {
case Test.One => 1
case Test.Two => 2
}
Надеюсь, я вам помог :)