Week 4 of Object oriented programming - Polymorphism

Week 4 of Object oriented programming - Polymorphism

이번엔 다형성에 관한 내용을 본다.




다형성의 목적에 대해 설명할 수 있을 정도의 수준을 목표로 한다.


다형성은 위와 같이 상위클래스를 참조하여 하위클래스 객체를 생성하는 것을 말한다.


위와 같은 구조를 통해 상속도를 알 수 있었고


이전 강좌에서 간략히 리스트 내에 각 객체정보를 담는 것을 보여줬었다.


간단한 퀴즈를 통해 개념을 확인하는데 위의 코드에서 과정을 예측하는데 p[1]은 Student 객체이므로 Student 내에 있는 toString 메쏘드가 호출된다.


그러므로 각 객체에 맞는 toString 메쏘드를 호출하기에 위와 같이 출력이 나온다.


이제 다형성을 해석할 때 두가지 측면에서 보아야 한다. 1번째는 컴파일러가 코드를 번역할때,


2번째는 런타임 환경이 번역된 코드를 실행할 때이다.


이제 컴파일, 런타임 시의 단계에 대해 알아본다.


컴파일러는 오직 레퍼런스 타입만 알 수 있으며 메쏘드를 위한 레퍼런스 타입클래스만 확인 가능하다.


예시를 보면 Person 타입으로 s를 정의하고 객체 생성을 Student 타입으로 진행 할 때 Student가 Person을 extends하므로 Student 내에 toString 메쏘드가 아닌 Person 내의 toString 메쏘드를 메쏘드 시그니쳐로 인식한다.


이번엔 런타임 시의 상황을 보면 컴파일 할 때의 메쏘드 시그니쳐와 실제 객체의 클래스의 메쏘드가 일치해야 한다. 따라서 Student 내의 toString 메쏘드를 실행하게 된다.


간단한 퀴즈가 등장하고 위의 코드를 실행 시 Person 객체에는 컴파일 시 GetSID를 찾을 수 없으므로 컴파일 에러가 발생한다.


따라서 캐스팅에 간한 내용을 다루게 된다.


아까 본 퀴즈의 내용으로 컴파일 에러가 발생하는 것을 알았다.


캐스팅은 자동적으로 타입을 승격시켜주는 역할을 한다. 이를 Widening이라고 한다.


그리고 명시적 캐스팅으로 활용될 때에는 Narrowing이라고 칭한다.


아까의 코드를 다시 보면 캐스팅을 통해 작동가능해지게 할 수 있다.


하지만 Person그 자체로만 객체를 생성하고 캐스팅을 이용하게 되었을 때에는 문제가 발생한다.


이때는 런타임 에러가 발생한다.


이는 is-a 관계 처럼 instanceof를 통해 확인이 가능하다.


이제 복습차원에서 이해한 내용에 대해 간단한 토의를 진행해본다. 위의 코드를 실행하였을 때 예측되는 결과를 의논한다.


동일한내용의 코드이며


위의 코드를 실행했을 시 status 메쏘드는 Person 클래스 내에 존재하므로 상위클래스로 넘어간다. if문에서 this.isAsleep 메쏘드를 동일 클래스 내에서 호출하며 조건을 비교할 때 False이므로 Now online: Sally가 출력된다.


다음 주제또한 생각해보는 시간을 가지며


구조는 위와 같이 조성되어 있다.


이제 우측상단의 코드를 실행할 때의 결과를 예측해본다.



결과적으로는 위와 같이 나오며 이유는 다음과 같다.


u의 타입은 Person이나 Undergrad를 통해 객체를 생성하므로 method1을 호출하면 Undergrad 클래스 내에는 없어 상위 Student 클래스의 method1을 호출한다. 그럼 Student 1 이 출력되고 이후 super.method1에 의해 더 상위 클래스인 Person 내의 method1이 실행되고 이 때 Person 1이 출력 된다.


이후 method2를 실행하는데 이는 런타임 시 편입되므로 Undergrad 내의 method2가 실행된다고 한다. 따라서 마지막은 Undergrad 2가 출력된다.


최종 출력 결과는 위와 같다.


마지막으로 abstract 키워드를 사용해보고 implementation과 interface를 통한 상속을 비교해본다.


먼저 monthlyStatement 메쏘드를 추가하는데 위의 순서를 따른다.


이 때 Abstract 클래스를 사용하게 된다.


위와 같은 형식으로 사용할 수는 없고


위와 같이 사용된다고 한다.


그래서 abstract 클래스는 implementation과 interface를 모두 제공하나


만약 interface만 원하는 상황에서는 어떻게 할지 고민한다.


그럼 위의 단계에서 4번 대신 interface를 활용한다고 한다.


인터페이스는 요구된 메쏘드로 정의되며 클래스는 다양한 인터페이스로부터 상속받을수 있다고 한다.


그래서 위와 같은 형식으로 사용되며


Impelementation을 진행하게 될 때에는 이런 식으로 활용된다.




댓글