본문 바로가기
language/Scala

[Scala] 스칼라 배우기 5. 스칼라 기본 문법4(trait, singleton object)

by 스파이디웹 2023. 6. 11.
728x90

Trait(트레잇)

  • 트레잇(trait)은 자바의 인터페이스와 유사
  • 메소드를 정의만 해놓을 수도 있고, 기본 구현을 할 수도 있음
  • 추상 클래스와 달리 생성자 파라미터는 가질 수 없음
  • 트레잇에서는 가변 변수, 불변 변수 모두 선언 가능
  • 트레잇을 구현하는 클래스에서 가변 변수는 수정이 가능하지만, 불변 변수는 수정할 수 없음
  • 트레잇의 기본 메소드는 상속되고, override 키워드를 이용하여 메소드를 재정의 할 수 있음
  • 트레잇은 extends를 사용하여 상속가능하고, 여러개의 트레잇을 with 키워드로 동시에 구현 가능
  • 멤버변수를 가질 수는 없음
  • 추상클래스는 하나만 상속할 수 있지만, 트레잇은 여러개를 상속 할 수 있음
  • 생성자 멤버변수가 필요하면 추상클래스를 이용하는 것이 좋고, 멤버 변수가 필요 없다면 트레잇을 이용하는 것이 좋음
// Machine 트레잇 
trait Machine {
  val serialNumber: Int = 1
  def work(message: String)
}

// KrMachine 트레잇 
trait KrMachine {
  var conturyCode: String = "kr"
  def print() = println("한글 출력")    // krprint 기본 구현 
}

// Computer 클래스는 Machine, KrMachine를 둘다 구현합니다. 
class Computer(location: String) extends Machine with KrMachine {
  this.conturyCode = "us"   // code 값 변경 
  def work(message: String) = println(message)
}

// Car 클래스는 Machine, KrMachine를 둘다 구현합니다.
class Car(location: String) extends Machine with KrMachine {
  def work(message: String) = println(message)
  override def print() = println("운전중입니다.") // print 재정의
}

var machine = new Computer("노트북")
var car = new Car("포르쉐")

scala> machine.work("computing...")
computing...

scala> machine.print()
한글 출력

scala> println(machine.conturyCode)
us

scala> car.work("driving...")
driving...

scala> car.print() 
운전중입니다.

scala> println(car.conturyCode)
kr

singleton object(싱글톤 객체)

  • object 선언자로 싱글톤 객체를 생성
  • 싱글톤 객체의 메서드는 전역적으로 접근하고 참조할 수 있음
  • 싱글톤 객체는 직접적으로 접근해서 사용할 수도 있고, import 를 선언하여 이용할 수도 있음
object Bread {
  val name: String = "기본빵"
  def cooking() = println("빵만드는 중...")
}

// import 이용
scala> import Bread.cooking
scala> cooking
빵만드는 중...

// 직접 접근 
scala> Bread.cooking
빵만드는 중...

컴패니언

  • 싱글톤 객체와 클래스가 같은 이름을 사용하면 컴패니언(Companions)이라고 함
  • 정적 메소드의 보관 장소를 제공
  • 자바의 static을 이용한 정적 데이터는 스칼라에서는 컴패니언을 이용하여 처리하는 것을 추천
  • 팩토리 메소드 같은 정적 메소드는 컴패니언을 이용하여 작성하고, 일반적인 데이터는 클래스를 이용하여 정적 데이터와 일반 데이터를 분리하여 관리할 수 있음
class Dog

object Dog {
    def bark = println("bark")
}

scala> Dog.bark
bark
// 팩토리 예제
class Email(val username: String, val domainName: String)

object Email {
  def fromString(emailString: String): Option[Email] = {
    emailString.split('@') match {
      case Array(a, b) => Some(new Email(a, b))
      case _ => None
    }
  }
}

val scalaCenterEmail = Email.fromString("scala.center@epfl.ch")
scalaCenterEmail match {
  case Some(email) => println(
    s"""Registered an email
       |Username: ${email.username}
       |Domain name: ${email.domainName}
     """)
  case None => println("Error: could not parse email")
}

scala> 
Registered an email
Username: scala.center
Domain name: epfl.ch
728x90

댓글