240513_디모의 코틀린 강의 #11강. 오버라이딩과 추상화

2024. 5. 14. 14:12TIL(Today I Learned)

유튜브 - 디모의 코틀린 문법 강의 정리

 

#11강. 오버라이딩과 추상화

 

1. 오버라이딩: 클래스 상속 시 예외적으로 슈퍼클래스와 이름/형태가 같은 함수를 서브클래스에서 구현할 수 있는 기능

 

open Animal {
	open fun eat(){
    // 오버라이딩을 하려면 수퍼클래스 내에 오버라이딩을 허용하려는 함수에 'open' 키워드를 붙여줌
    	println("음식 먹기")
    }
}

// 서브클래스 타이거 생성
class Tiger : Animal() {
	overriide fun eat(){
    // 오버라이딩하려는 함수 앞에 override 키워드를 붙여주기
    	println("고기 먹기")
        // 수퍼클래스와 이름이 같은 eat() 함수인데 다른 기능을 구현
    }
}

 

2. 추상화: 선언부만 있고 기능은 구현되지 않은 추상함수 및 추상클래스로 구성

 - 수퍼클래스에는 어떤 함수의 구체적인 구현이 없고, 단지 모든 서브클래스에 그 '어떤 함수'가 있어야 한다는 점만 명시해

   각 서브클래스가 비어있는 함수의 내용을 필요에 따라 구현하도록 하는 것

abstract class Animal(){
// 추상클래스 앞에 키워드 abstract 붙여주기
	abstract fun eat(){
    }
	// 추상함수 앞에 키워드 abstract 붙여주기
    
	// 추상클래스는 일부 함수가 구현되지 않은 의존성 클래스이므로 단독으로 인스턴스를 생성할 수
    // 없으므로, 서브클래스에서 상속받아 abstract가 표시된 함수를 구현함
    
	fun sniff(){
    	println("킁킁")
    }
}

//서브클래스 Rabbit 생성
class Rabbit: Animal(){
	override fun eat(){
    	println("당근 먹기")
        // 추상함수 eat()의 실제구현부 
    }
}

var r = Rabbit()
r.eat() // "당근 먹기"
r.sniff() // "킁킁"

 

3. 인터페이스: 추상함수로만 이루어진 순수 추상화 기능

 1) 인터페이스의 구성: 속성, 추상함수, 일반함수

 2) 인터페이스의 추상함수와의 차이

  - 추상함수: 생성자를 가질 수 있음

  - 인터페이스: 생성자를 가질 수 없음

 3) 인터페이스에서 함수의 간주

  - 구현부가 존재하는 함수: open 함수로 간주

  - 구현부가 존재하지 않는 함수: abstract 함수로 간주

   ==> open, abstract의 별도 키워드가 없어도 서브클래스에서 구현 및 재정의가 가능.

 4) 한 번에 여러 인터페이스에서 상속받을 수 있어 유연한 설계가 가능함.

 

interface Runner{
	fun run()
}

interface Eater{
	fun eat(){
    	println("음식 먹기")
    }
}

// 두 인터페이스 Runner, Eater를 동시에 상속받는 Dog 클래스를 생성
class Dog : Runner, Eater {
	override fun run(){
    // 여러 인터페이스에서 같은 이름과 형태의 함수를 구현하고 있다면, override를 통해 
    // 재구현함으로써 서브클래스에서의 혼선을 방지함
    	println("뛴다")
    }
    
    override fun eat(){
    	println("먹는다")
    }
}

var d = Dog()

d.run() // "뛴다"
d.eat() // "먹는다"

 

4. 오버라이딩 / 추상화 / 인터페이스의 큰 구분

 1) 오버라이딩: 이미 구현이 완료된 함수의 기능을 서브클래스에서 변경해야 할 때 사용

 2) 추상화: 형식만 선언하고 실제 구현은 서브클래스에 일임할 때 사용

 3) 인터페이스: 서로 다른 기능들을 여러 개 물려줘야 할 때 사용