композиция над наследованием в scala

Я создал код, который фактически использует наследование

Любой другой альтернативный способ сделать это, если я хочу использовать для этого композицию

 case class Test(message:msg)

 abstract class MsgValuetype(value: myString) {
  override def toString = s"${value.value}"
 }

case class msg(id:String) extends MsgValuetype(myString(id))

case class myString(value: String){
    override def toString = s"$value"
 }

Ниже приведен мой последний вызов для проверки вышеизложенного. Я хочу, чтобы передавалась только строка. Обратите внимание, что фактические классы более сложны в моем случае использования. Я только что попытался указать простой способ получить альтернативное решение.

Test(msg("123"))

Обновление 1

Если я попытаюсь сделать MsgValuetype частью класса case msg вместо его расширения.

case class Test(message:msg)

case class  MsgValuetype(value: myString) {
  override def toString = s"${value.value}"
 }

 case class msg(id:String,myType:MsgValuetype) 

 case class myString(value: String){
    override def toString = s"$value"
 }

Мне нужно сделать ниже вызов для инициализации

 Test(msg("123",MsgValuetype(myString("123")))) 

Я только хочу позвонить, как

     Test(msg("123"))

person coder25    schedule 11.08.2017    source источник
comment
Я немного смущен тем, что вы пытаетесь здесь сделать? Вы просто хотите иметь возможность инициализировать Test, передав строку? В этом случае наиболее разумным решением будет использование перегруженного метода apply в объекте-компаньоне.   -  person puhlen    schedule 11.08.2017
comment
Что вы пытаетесь сочинить? Ваш пример недостаточно объясняет, чего вы пытаетесь достичь. Просто msg содержит поле MsgValueType вместо его расширения?   -  person puhlen    schedule 11.08.2017
comment
@puhlen я обновил вопрос, надеюсь, он прояснил   -  person coder25    schedule 11.08.2017


Ответы (2)


Что-то вроде этого, наверное?

 case class msg(id: String) { val myType = MsgValuetype(myString(id)) }
person Dima    schedule 11.08.2017
comment
используя ваш код, нет ошибок, но я не могу распечатать сообщение 123, которое печатает Test (msg (123)) - person coder25; 11.08.2017
comment
также есть один ответ, связанный с использованием метода применения. Какой способ лучше всего использовать - person coder25; 11.08.2017
comment
Использование apply лучше, если вам иногда нужно, чтобы значение myType отличалось. В противном случае это на самом деле хуже, потому что позволяет создать msg с неправильным значением типа. Что касается печати 123, я понятия не имею, о чем вы говорите. Этот код ничего не печатает. - person Dima; 11.08.2017
comment
@ Дима, ОП, просто хочет, чтобы этот метод был там override def toString = s"${myType.value.value}" - person Alvaro Carrasco; 11.08.2017
comment
@Dima, я не понял, потому что он позволяет создавать сообщения с неправильным значением типа - person coder25; 12.08.2017
comment
@coder25 Итак, с моим решением msg("foo") всегда будет иметь тип MsgValuetype(myString("foo")). С другим подходом (с пользовательским методом apply) вы все равно можете иметь msg("foo", MsgValueType(myString("bar"))) Итак, это зависит от того, что имеет больше смысла в вашей конкретной ситуации - всегда ли тип msg определяется значением или иногда может быть другим? - person Dima; 12.08.2017
comment
спасибо принял ответ. Не могли бы вы проверить этот stackoverflow.com/questions/45650111/ - person coder25; 12.08.2017

То, как вы сделали это в своем обновлении, - это путь, определите msg следующим образом

case class msg(id:String,myType:MsgValuetype) 

Единственное, что вам нужно добавить, это объект-компаньон для msg с перегруженным методом применения.

object msg {
  def apply(id : String): msg = msg(id, MsgValuetype(myString(id)))
}

нельзя создать тест

Test(msg("123"))
person puhlen    schedule 11.08.2017
comment
Я получаю перегруженный метод с ошибкой. Применение требует определения типа результата. - person coder25; 11.08.2017
comment
@coder25 извините, ошибка копирования. Как говорит ошибка, вам просто нужно добавить возвращаемый тип метода применения (def apply(id : String): msg = ...). Я обновил свой ответ, чтобы исправить его. - person puhlen; 11.08.2017
comment
Теперь он работает, но печатает Test(msg(123,123)) вместо 123 - person coder25; 11.08.2017
comment
Ответ @Dima также действителен. Я не уверен в лучшем методе применения или использовании varibale внутри класса case. - person coder25; 11.08.2017