코틀린 언어 정리 2-3
class
상속
class 상속
단일 상속
코틀린에서 class는 단일 상속만 지원합니다.
interface 상속
다중 상속
interface를 사용 또는 구현하려고 하는 class에서 상속과 같은 방법(문법)으로 적용할 수 있으며 여러 개의 interface를 동시에 적용(다중상속 문법)할 수 있습니다.
override
상위 클래스에서 open으로 선언된 프로퍼티나 멤버함수를 하위 클래스에서 재정의하여 사용 합니다.
override된 멤버는 최종적으로 override한 하위 클래스의 멤버로 통합되는 것이 아니라 상위, 하위 클래스 또는 인터페이스에 각각의 멤버가 별도로 존재하며 "super<...>.멤버" 와 같은 방식으로 각 타입의 멤버에 접근할 수 있습니다.
override로 선언된 property, member function은 open으로 선언된 것으로 간주됩니다.
property override 규칙
property를 override할 때 val/var, nullable type 등을 변경할 수 있는 경우가 있습니다.
예제
변경 가능한 경우
1. 상위에서 val로 선언한 프로퍼티를 하위에서 var로 변경 가능 ( val->var: ok )
2. 상위에서 val로 선언한 nullable type을 하위에서 non-nullable type으로 변경 가능 ( val nullable -> non-nullable: ok )
3. 1, 2 동시에 변경 가능
하위로 가면서 기능 확장은 가능하지만 예외 허용 범위는 좁아져야 합니다. 상위에서 원래 처리하던 예외의 범위를 넘어가서는 안됩니다.
규칙 이해를 위한 여러 상황들 고려
1. 상위에서 프로퍼티를 사용하는 로직이 읽기/쓰기 가능한데 하위에서 읽기 전용으로 변경하면 하위 프로퍼티 사용 로직에 오류(읽기 전용 변수에 쓰기 시도)가 생길 수 있습니다. ( var -> val: not ok )
2. 상위에서 프로퍼티에 null값이 없는 것을 가정하고 로직을 만들었는데 하위에서 nullable로 변경되어 null값을 추가하면 상위 로직에서 오류(상위에 null값에 대한 예외 처리가 없음)가 생길 수 있습니다. 즉 non-nullable 프로퍼티를 사용하는 로직에 null값이 입력 되는 경우 오류가 발생합니다.( non-nullable -> nullable: not ok )
3. nullable 프로퍼티를 사용하던 기존 코드에서 null값을 입력하는 경우 하위에서 이를 non-nullable 프로퍼티로 참조하면 문제가 발생합니다.( var nullable -> non-nullable: not ok )
overriding conflict
상위에서 final로 선언한 멤버와 충돌하는 경우
C++에서는 가상함수(가상 함수로 선언 시 변수를 참조하는 타입이 아닌 실제 생성된 객체 인스턴스의 타입에 선언된 함수를 실행 합니다. 즉 override한 함수와 비슷하게 동작합니다.)가 아니더라도 상위와 하위에 동일한 이름의 멤버(virtual이 아닌 멤버 함수 및 멤버 변수)가 허용되며 이를 각각 접근할 수 있는 방법을 제공합니다. 하지만 코틀린에서는 상위에서 final로 선언된( 코틀린 class의 멤버는 기본으로 final입니다. ) 멤버가 있는 경우 하위에서 이 멤버와 동일한 멤버( 이름이 동일한 프로퍼티, 이름과 형식이 동일한 멤버 함수 등 )를 선언할 수 없습니다. 즉 상위의 final 멤버를 open/abstract 등으로 수정 불가한 경우 하위에서는 상위에서 final로 선언된 멤버와 동일한 이름의 멤버 프로퍼티, 동일한 이름 및 형식의 멤버 함수 정의를 피해야 합니다.
상위에 정의된 동일한 이름의 함수(override한 함수) 접근
하위 클래스 내부 구현에서 다중 상속 받은 각 상위 클래스의 동일한 이름의 멤버에 접근하려면 "super<interface name>.멤버" 와 같은 방법으로 접근하면 됩니다.
abstract
특징
추상 클래스, 추상 멤버 프로퍼티, 추상 멤버 함수 등을 선언할 때 사용합니다.
abstract는 open의 개념을 포함합니다. 즉 상속 가능하다는 것을 표현하기 위해 open을 별도로 명시하지 않아도 됩니다.
abstract로 선언된 클래스로 객체를 직접 생성하지 못합니다.
클래스의 멤버 중 하나라도 abstract로 선언했다면 클래스도 abstract로 선언해야 합니다.
abstract 클래스의 멤버를 abstract로 선언하려면 각각의 멤버 선언에 abstract를 추가해야 합니다.
abstract가 아닌 클래스가 abstract 클래스를 상속받은 경우 abstract 멤버(프로퍼티, 함수)를 반드시 구현해야 합니다.
예제
open
class나 property, member function 앞에 상속 가능하다는 것을 명시할 때 사용합니다.
final
class나 property, member function 앞에 상속 불가능하다는 것을 명시할 때 사용합니다. 코틀린 클래스 멤버는 open을 명시하지 않는 경우 기본적으로 final로 처리됩니다.
예제
기타
코틀린의 모든 class는 Any class를 상속 받는다.
class의 상속은 "is a" 관계이고 interface의 상속은 "has a" 의 관계입니다.
상위 클래스 접근
상위 클래스를 상속 받은 하위 클래스에서는 하위 클래스에서 상위 클래스에 접근하는 키워드로 super를 사용합니다.
super
기본 상위 클래스/인터페이스 접근 방법입니다.
super<interface/class 이름>
class, interface 들을 다중 상속받은 경우 각각의 상위 접근을 구분하는 방법
상위 생성자 접근
하위 클래스에 주생성자가 있는 경우 하위클래스의 주생성자에서만 상위클래스의 생성자에 접근할 수 있습니다.(클래스 이름으로 접근) 주생성자가 없는 경우 보조생성자 선언에서 super 키워드로 접근할 수 있습니다. 여기서 접근한다는 의미는 선언을 통해 호출한다는 의미입니다.
예제
상위 클래스 생성자 호출
하위 클래스의 생성자 선언에 상위 클래스의 생성자 호출을 추가하는 방법을 사용합니다.
하위 클래스에서 상위 클래스의 생성자를 호출하는 방법
[하위 클래스에 주생성자가 있는 경우]
주생성자 선언 부분에서 상위 클래스 이름(이후 나올 예제에서 "SuperA")으로 생성자를 호출합니다. 하위 클래스의 보조생성자에서는 상위클래스의 생성자를 바로 호출할 수 없습니다.
[하위 클래스에 주생성자가 없는 경우]
보조생성자 선언 부분에서 super 키워드로 상위 클래스의 생성자를 호출합니다. 상위 클래스의 생성자가 여러 개인 경우 원하는 생성자를 호출하면 됩니다.
예제
상속 관계 캐스팅
as를 이용하여 상속 관계를 고려한 캐스팅을 할 수 있습니다.
as?를 이용하면 null 허용 객체로 예외가 발생하는 것을 방어하면서 as의 기능을 수행할 수 있습니다.
상속 전반적인 내용에 대한 전체 예제
예제
'코틀린( Kotlin )' 카테고리의 다른 글
코틀린 2-5 interface (0) | 2020.04.05 |
---|---|
코틀린 2-4 class - 생성자 호출 순서, Any (0) | 2020.04.05 |
코틀린 2-2 class - 프로퍼티, 접근 권한 (0) | 2020.04.04 |
코틀린 2-1 class - 주생성자, 보조생성자 (0) | 2020.04.04 |
코틀린 1-9 기본 - operator(연산자) - 연산자 오버로딩 (0) | 2020.04.03 |