학습
Scala 특질 (Traits)
Scala 특질 (Traits) — 중급
특질 (Traits)
1. 도입 (왜 배워야 하는가)
Scala에서 특질(Traits)은 객체 지향 프로그래밍에서 다중 상속의 문제를 해결하기 위한 강력한 도구입니다. 실무에서는 공통된 행동을 여러 클래스에 재사용할 수 있게 해주기 때문에 코드의 유지보수성과 가독성을 향상시킵니다. 특질을 사용하지 않으면 중복된 코드가 생기거나, 특정 클래스가 다른 클래스의 기능을 불필요하게 상속받아야 하는 상황이 발생할 수 있습니다. 이는 코드의 복잡성을 증가시키고, 버그를 유발할 수 있습니다.
2. 핵심 개념 설명
- 특질(Trait): 클래스가 특정 행동을 구현할 수 있도록 정의된 일종의 인터페이스입니다. 특질은 클래스와 유사하지만 인스턴스를 만들 수 없고, 주로 상속을 통해 기능을 확장하는 데 사용됩니다.
비유: 특질은 마치 '요리 레시피'와 같습니다. 레시피는 요리할 때 따라야 할 지침을 제공하지만, 요리 그 자체는 아닙니다. 각각의 요리사는 이 레시피를 바탕으로 자신의 스타일로 요리를 만들어냅니다.
관련 용어 정리
| 용어 | 설명 |
|---|---|
| 클래스 | 객체를 생성하기 위한 청사진입니다. |
| 믹스인 | 특질을 클래스에 추가하여 기능을 확장하는 방법입니다. |
| 다중 상속 | 하나의 클래스가 여러 클래스로부터 상속받는 것입니다. |
3. 기본 코드 예제
// 특질 정의
trait Animal {
def sound: String // 추상 메소드
}
// 특질을 상속받는 클래스
class Dog extends Animal {
def sound: String = "멍멍"
}
// 특질을 상속받는 또 다른 클래스
class Cat extends Animal {
def sound: String = "야옹"
}
// 객체 생성
val dog = new Dog()
val cat = new Cat()
// 결과 출력
println(dog.sound) // 멍멍
println(cat.sound) // 야옹
실행 결과
멍멍
야옹
코드 설명
trait Animal:Animal이라는 특질을 정의하며,sound라는 추상 메소드를 선언합니다.class Dog extends Animal:Dog클래스가Animal특질을 상속받아sound메소드를 구현합니다.class Cat extends Animal:Cat클래스도 마찬가지로Animal특질을 상속받고sound메소드를 구현합니다.val dog = new Dog():Dog클래스의 인스턴스를 생성합니다.val cat = new Cat():Cat클래스의 인스턴스를 생성합니다.println(dog.sound):dog객체의sound메소드를 호출하여 결과를 출력합니다.println(cat.sound):cat객체의sound메소드를 호출하여 결과를 출력합니다.- 잘못된 코드:
Dog클래스가sound메소드를 구현하지 않았습니다. - 올바른 코드:
def sound: String = "멍멍"메소드를 구현하여 오류를 해결합니다. - 잘못된 코드:
Vehicle특질의drive()메소드를 구현하지 않았습니다. - 올바른 코드:
def drive(): Unit = println("차가 달린다.")로 구현합니다. - 특질은 다중 상속을 효과적으로 지원하여 코드의 재사용성을 높입니다.
- 특질을 통해 공통된 행동을 여러 클래스에 쉽게 적용할 수 있습니다.
- 특질은 클래스와 유사하지만 인스턴스를 생성할 수 없다는 점을 기억해야 합니다.
- 다음에 학습하면 좋은 주제: 믹스인(Mixin), 함수형 프로그래밍.
4. 실전 활용 예제
예제 1: 쇼핑몰에서 장바구니를 구현할 때
trait Item {
def price: Double
}
class Book(val price: Double) extends Item
class Electronic(val price: Double) extends Item
class ShoppingCart {
private var items: List[Item] = List()
def addItem(item: Item): Unit = {
items = item :: items
}
def totalPrice: Double = items.map(_.price).sum
}
// 사용 예
val cart = new ShoppingCart()
cart.addItem(new Book(29.99))
cart.addItem(new Electronic(199.99))
println(s"총 가격: ${cart.totalPrice}") // 총 가격: 229.98
상황 설명: 이 예제에서는 Item 특질을 통해 여러 종류의 상품을 처리할 수 있는 장바구니를 구현했습니다. Book과 Electronic 클래스는 가격 정보를 제공하며, ShoppingCart는 이들 상품을 관리합니다.
예제 2: 다양한 동물 소리 구현
trait Sound {
def makeSound(): String
}
class Dog extends Sound {
def makeSound(): String = "멍멍"
}
class Cat extends Sound {
def makeSound(): String = "야옹"
}
val animals: List[Sound] = List(new Dog(), new Cat())
animals.foreach(animal => println(animal.makeSound()))
상황 설명: 다양한 동물 클래스를 통해 다형성을 활용하여 각 동물의 소리를 출력합니다. Sound 특질을 사용하여 동물의 소리를 쉽게 확장할 수 있습니다.
5. 흔한 실수와 주의사항
실수 1: 특질의 추상 메소드를 구현하지 않기
trait Animal {
def sound: String
}
class Dog extends Animal {
// def sound: String = "멍멍" // 구현하지 않음
}
실수 2: 특질을 잘못 사용하기
trait Vehicle {
def drive(): Unit
}
class Car extends Vehicle {
// drive 메소드 구현하지 않음
}
val car = new Car() // 오류 발생