관리 메뉴

HAMA 블로그

스칼라 강좌 (18) -trait 본문

Scala

스칼라 강좌 (18) -trait

[하마] 이승현 (wowlsh93@gmail.com) 2016. 8. 6. 19:07

trait


*  Scala 는 interface 가 없으며 대신  trait 을 사용한다. 

*  Scala 의 trait 는 자바의 interface 와 달리 구현 가능하다. (자바8 부터는 자바인터페이스도 디폴트메소드등 구현)

*  하나의 부모클래스를 갖는 클래스의 상속과 달리 트레이트는 몇개라도 조합해 사용 가능하다. 

 * Scala 의 trait 는 자바의  인터페이스와 추상클래스의 장점을 섞었다. 

 * 트레이트를 믹스인 할때는 extends 키워드를 이용한다. 

 * extends 를 사용하면 trait 의 슈퍼클래스를 암시적으로 상속하고 , 본래 trait 를 믹스인한다. 

*  trait 는 어떤 슈퍼클래스를 명시적으로 상속한 클래스에 혼합할 수 있다. 

   그때 슈퍼클래스는 extends 를 사용하고, trait 는 with 로 믹스인한다. 


예1) 


trait Car {
  val brand: String
}

trait Shiny {
  val shineRefraction: Int
}
class BMW extends Car {
  val brand = "BMW"
}

클래스는 여러 트레잇를 with 키워드를 사용해 확장할 수 있다.

class BMW extends Car with Shiny {
  val brand = "BMW"
  val shineRefraction = 12
}


예2)



 trait Philosophical {
      def philosophize() {
        println("I consume memory, therefore I am!")
      }
    }

Listing 12.1 - The definition of trait Philosophical.


 class Frog extends Philosophical {

    override def toString = "green"
  }

 Listing 12.2 - Mixing in a trait using extends.


 scala> val frog = new Frog
  frog: Frog = green
  
 scala> frog.philosophize()
  I consume memory, therefore I am!

 scala> val phil: Philosophical = frog  
  phil: Philosophical = green
  
 scala> phil.philosophize()
  I consume memory, therefore I am!

 class Animal
  
 class Frog extends Animal with Philosophical {
   override def toString = "green"
 }

Listing 12.3 - Mixing in a trait using with.


class Animal
trait HasLegs
  
class Frog extends Animal with Philosophical with HasLegs {
  override def toString = "green"
}

Listing 12.4 - Mixing in multiple traits.

class Animal
  
class Frog extends Animal with Philosophical {
  override def toString = "green"
  override def philosophize() {
    println("It ain't easy being "+ toString +"!")
  }
 }

 scala> val phrog: Philosophical = new Frog
  phrog: Philosophical = green
  
 scala> phrog.philosophize()
  It ain't easy being green!

trait 는 클래스를 정의하면서 할 수 있는 모든것을 할 수 있다. 
문법 경우 2가지를 제외하고 정확히 같다.

첫째. 트레이트는 '클래스' 파라미터를 가질 수 없다.
둘째 클래스는 super 호출을 정적으로 바인딩하지만, 트레이는 동적으로 바인딩한다.

class Point(x: Int, y: Int)
trait NoPoint(x: Int, y: Int) // trait 는 클래스 파라미터를 가질수 없다. 


trait   vs  추상클래스 


스택 오버플로우에서 아래를 참고 하라. 

트레잇과 추상 클래스의 비교
추상 클래스와 트레잇의 차이
스칼라 프로그래밍: 트레잇냐 아니냐 그것이 문제로다?  

자바8에서 인터페이스 기능이 대폭 증가한것을 기점으로  스칼라  trait vs 자바 interface 비교를 해야 할 듯싶다.


Orderd trait 


  class Rational(n: Int, d: Int) {
    // ...
    def < (that: Rational) = 
      this.numer * that.denom > that.numer * this.denom
    def > (that: Rational) = that < this
    def <= (that: Rational) = (this < that) || (this == that)
    def >= (that: Rational) = (this > that) || (this == that)
  }


  class Rational(n: Int, d: Intextends Ordered[Rational] {
    // ...
    def compare(that: Rational) =
      (this.numer * that.denom) - (that.numer * this.denom)
  }


  scala> val half = new Rational(12)
  half: Rational = 1/2
  
scala> val third = new Rational(13) third: Rational = 1/3
scala> half < third res5: Boolean = false
scala> half > third res6: Boolean = true


  trait Ordered[T] {
    def compare(that: T): Int
  
  def <(that: T): Boolean = (this compare that) < 0   def >(that: T): Boolean = (this compare that) > 0   def <=(that: T): Boolean = (this compare that) <= 0   def >=(that: T): Boolean = (this compare that) >= 0 }


Comments