우리가 목이 말라 음료를 마시겠지만 음료에는 콜라, 생수, 커피 등 식품 종류들에 맞춰 뭘 마시는지도 추가할 수 있다. 이때 콜라를 콜라 자체로도 볼 수 있지만 음료의 특성 중 하나로도 볼 수 있도록 만드는 것을 코드에서는 다형성 이라고 한다.

먼저 생성한 Drink 클래스를 상속받아 생성한 Cola 클래스는 인스턴스 생성 시 Drink의 객체 공간과 Cola의 추가 공간을 받게 된다.
여기서
var a: Drink = Cola()
콜라 인스턴스는 Drink 자료형의 변수에 초기화를 한다면 Cola의 기능을 사용 못하지만
var a: Cola = Cola()
콜라를 담는 변수에 초기화를 한다면 Drink와 Cola 둘다 기능을 사용 가능하다.
여기서 Cola 인스턴스를 Drink 변수에 담는 행위 즉, 상위 자료형인 수퍼 클래스로 변환하는 행위를 Up-Casting이라고 한다.
반대로 Up-Casting된 인스턴스를 다시 하위 자료형으로 변환하면 Down-Casting이라고 한다.
Up-Casting의 경우 상위 자료형에 담는 것으로 동작하지만
Down-Casting은 별도의 연산자가 필요하다.
: 변수를 호환되는 자료형으로 변환해주는 캐스팅 연산자
var a: Drink = Cola()
var b a as Cola
Up-Casting한 상황에서 다시 Down-Casting을 할 때 as로 하위 자료형을 넣어주면 된다.
또한 변환한 결과를 반환받아 변수에도 넣을 수도 있다.
: 변수가 자료형에 호환되는지를 먼저 체크 후 변환해주는 캐스팅 연산자
var a: Drink = Cola()
if (a is Cola) {
...
}
보통 조건문에 쓰는 경우가 많다. 조건문 true 시 a 는 Cola로 변환된다.

a는 Cola 인스턴스 객체를 상위 자료형인 Drink에 담는 변수이다.
그래서 원래는 Cola에 대해 재정의한 drink 함수는 정상적으로 출력이 되지만 별도로 washDishes 함수는 접근하지 못한다.
하지만 Down-Casting을 함으로써 washDishes() 함수도 호출 가능해짐을 알 수 있다.

as 말고도 is를 통한 조건문으로 호출 가능하다. 호환성 검사 말고도 추가적으로 조건 검사를 해야하거나 조건을 통한 해야하는 일들이 많을 때 보통 is를 쓴다고 한다.

또한 이것을 보면 반환값 뿐 아니라 변수 자체에서도 다운캐스팅을 하기 때문에
a와 b 둘다 washDishes() 함수를 호출 가능하다.