본문 바로가기
코틀린 문법

10. 클래스의 다형성

by 농농씨 2023. 5. 4.

코드테스트 사이트: play.kotlinlang.org

참조:유튜브 디모의 코틀린

*맥북에서 스크린샷을 클립보드에 바로 복사하는 법

:컨트롤을 누른 상태로 스크린샷 단축키를 누른다

 

//복습:클래스의 상속을 통해 클래스를 '확장'할 수 있다.
//예를 들어, 콜라를 콜라 뿐만 아니라 '음료'라는 특성으로도 볼 수 있게 하는 게
//'다형성'의 개념이다.(?)
//'음료'클래스와, 음료클래스를 상속받은 '콜라'클래스가 있을 때
//콜라클래스의 인스턴스를 만들면
//상속관계에 있는 수퍼클래스인 '음료'의 내용을 담는 공간에
//'콜라'의 내용을 담는 '추가공간'이 생성된다
//(흠... 그럼 콜라 클래스가 음료클래스에 포함관계인건가?아닌것같은데..)
//이렇게 만들어진 콜라의 인스턴스는 음료를 담는 변수에 저장하면
//ex.var a:Drink=Cola()->음료의 기능만 사용하게 되고
//                          콜라를 담는 변수에 저장하면
//ex.var a:Cola=Cola()->콜라의 기능까지 모두 사용할 수 있게 된다.
//이때, 콜라의 인스턴스를 음료 변수에 담는 행위를
//상위 자료형인 수퍼클래스로 변환한다고 하여 'Up-Casting' 이라 함.
//Up-Casting된 인스턴스를 다시 하위 자료형으로 변환하면'Down-Casting'이라 함
//사실, upcasting은 그냥 상위자료형에 담는 것으로 동작하지만 
//downcasting은 '별도의 연산자'가 필요함 !-->'as','is'연산자
//as:변수를 호환되는 자료형으로 변환해주는 캐스팅 연산자
//   코드 내에서 사용할 시 즉시 자료형을 변환해줌
//   변환된 자료형을 반환도 해줌
//  ex)var a:Drink=Cola(
//     a as Cola -->이후로는 a는 cola로 동작함 
//     var b = a as Cola-->cola로 변환한 결과를 반환받아 변수에
//      넣을 수도 있음!
//is:변수가 자료형에 호환되는지를 먼저 '체크한 후 변환'해주는 캐스팅연산자
//   조건문 내에서만 사용됨
//  ex) var a:Drink=Cola()
//   if(a is Cola)
//   {
//      (이 안에서만 a가 cola가 됨)
//   }

fun main(){
    var a=Drink()//drink의 인스턴스 만들어 변수 a에 담음
    a.drink()//drink의 함수 호출
    
    var b: Drink=Cola()//콜라의 인스턴스 만들어서 
     //drink타입의 변수 b에 할당
    b.drink()
    
    if (b is Cola){ //if문과 is캐스팅연산자를 활용한 구문으로
         //b가 Cola와 호환되는지 여부를 확인하고
        b.washDishes()//콜라의 함수 호출해보기
        //*is는 '조건문 안에서만' 잠시 다운캐스팅 된다는 점 유의!
    }
    
    var c=b as Cola //b를 콜라로 다운캐스팅 한 것을 변수 c에 할당!
    c.washDishes()//그리고 함수 호출
    b.washDishes()//에러 안남. as를 사용하면 반환값뿐만 아니라
     //변수(b) 자체도 downcastig되기 때문!
     //(근데 그럼 c는 변수공간 낭비 아닌가? )
}

open class Drink {
    //먼저 drink클래스를 상속이 가능한 open class로 만들어줌
    var name="음료"
    //속성으로 name이라는 변수에 '음료'라는 문자열 할당
    open fun drink(){//함수 만들고 override 가능하도록 open해줌
        println("${name}를 마십니다")
    }
    
}

class Cola: Drink(){//음료 클래스 상속받는 콜라 클래스 만듦
    var type = "콜라" //변수 만들어서 문자열 할당

    override fun drink(){//함수 오버라이딩 해서
        println("${name}중에 ${type}를 마십니다")//문자열 출력
    }
    fun washDishes(){//새로운 함수 추가
        println("${type}으로 설거지를 합니다")
    }
}
//실행결과 a는 drink의 인스턴스에 있는 drink 함수를 호출해서
//'음료'를 마십니다 라고 출력됨
//b는 drink타입의 변수이지만 cola에 인스턴스를 담았으므로 
//콜라에서 override했던 함수가 실행됨
//하지만 b는 drink변수이므로 이대로는 washDishes함수를 호출못해!
//참조할수 없다는 오류 뜰것임.-->as나 is로 downcasting필요!
//
//다운캐스팅은 클래스의 상속관계에서 오는 인스턴스의 호환성을 적극 활용할 수 있는 기능
//수퍼클래스가 같은 인스턴스를 한번에 관리하거나
//인터페이스를 구현하여 사용하는 코드에서도 이용되므로 이해가 꼭 필요함

'코틀린 문법' 카테고리의 다른 글

12. 리스트  (0) 2023.05.11
11. 제너릭  (0) 2023.05.11
9. 상속, 오버라이딩과 추상화  (0) 2023.04.30
8. 클래스, 생성자, 보조생성자  (0) 2023.04.30
7. 조건문과 비교연산자, 흐름제어와 논리연산자  (0) 2023.04.30