扩展动态特征?

时间:2018-01-10 21:20:50

标签: algorithm scala

我是Scala的新手,我不知道如何调用这个问题,但基本上我有这个:

   trait Hi {
      protected val hi : String = "Hi"

   }

   trait HowAre {
      protected val howare : String = "How Are you?"

   }

   trait Text{
     protected val text :String = "Any Text"
   }

   class SeeText () extends Text {

     def SeeString() = {
        println(text)
     }

   }

   class SeeHi () extends Hi {

     def SeeString() = {
        println(hi)
     }

   }

   class SeeHowAre () extends HowAre {

     def SeeString() = {
        println(howare)
     }

   }

我在每个类中都有相同的函数来显示字符串,我不希望这样,我想使用只有一个函数并显示字符串的单个类,我想到了它:

   trait Hi {
      protected val hi : String = "Hi"
      def getString() : String = {hi}

   }

   trait HowAre {
      protected val howare : String = "How Are you?"
       def getString() : String = {howare}

   }

   trait Text{
     protected val text :String = "Any Text"
       def getString() : String = {text}
   }

   class SeeGeneral() extends Text with Hi with HowAre{
        def SeeString()={
          println( getString() )
        }
   }

但是如何控制String来显示?类可以动态扩展单个特征吗?我们的想法不是为每个特征创建一个类而不是编写更多代码,谢谢

2 个答案:

答案 0 :(得分:2)

您可以创建一个实现getString()的基本特征,并让您的所有特征扩展到该特征:

trait SupportsGetString {
  def getString: String
}

trait Hi extends SupportsGetString {
  protected val hi : String = "Hi"
  def getString() : String = {hi}

}

trait HowAre extends SupportsGetString  {
  protected val howare : String = "How Are you?"
  def getString() : String = {howare}
}

trait Text extends SupportsGetString {
  protected val text :String = "Any Text"
    def getString() : String = {text}
}

然后你的一般函数可以接受一个基本特征的实例。

def seeString(a: SupportsGetString) = a.getString

有时,您无法拥有共享基类。也许,也许你的一个特征是由第三方提供的,不能改变。当发生这种情况时,您可以使用类型类。此技术允许您描述从类型外的类型A中提取字符串的行为:

// A trait that knows how to get some inner string from a type A
trait GetString[A] {
  def getString(a: A): String
}

现在,让我们为您拥有的类型定义此特征的一些值:

object GetString {
    implicit val hiGetString: GetString[Hi] = new GetString[Hi] {
        def getString(a: Hi): String = a.hi
    }
    implicit val howAreGetString: GetString[HowAre] = new GetString[HowAre] {
        def getString(a: HowAre): String = a.howare
    }
}

现在,您可以在这里编写一个函数,该函数可以从任何A中获取一个字符串:{/ 1}}:

GetString[A]

答案 1 :(得分:0)

我不太确定你的实际问题,但我认为,你正在寻找可堆叠的特质模式:

 trait Text {
   def text: String = ""
 }

 trait Hi extends Text {
   override def text = super.text + "Hi"
 }

 trait HowAre extends Text { 
   override def text = super.text + ", how are"
 }

 trait You extends Text {
    override def text = super.text + " you?"
 }  

 class It extends Hi with HowAre with You {
    def seeString = println(text)
 }