관리 메뉴

hyeals study

[코틀린] 클래스 계층 정의 본문

코틀린

[코틀린] 클래스 계층 정의

hyeals 2020. 2. 18. 18:38

[코틀린 인터페이스] : 자바의 인터페이스와 비슷함. 

☞ 코틀린 인터페이스 안에 추상메소드구현이 되어있는 메소드(자바에서 default메소드와 비슷)를 정의할 수 있음.

 

다만, 인터페이스안에 어떠한 필드도 들어갈 수 없음.

 

* 클래스는 class로 정의, 인터페이스는 interface로 정의

 

 

간단한 인터페이스 선언 예시

위의 코드는 click이라는 추상메소드가 있는 인터페이스를 정의한 예시임.

* 이 인터페이스를 구현하는 모든 클래스는 click에 대한 구현을 제공해야 함.

 

아래와 같은 방법으로 이 인터페이스를 구현하면 됨.

인터페이스 구현 예시

  • 자바에서는 extends나 implements 키워드를 사용하지만, 코틀린에서는 클래스명 뒤에 콜론(:)을 붙여서 상속과 인터페이스를 처리함. 
  • 자바와 마찬가지로 코틀린에서도 상속은 하나만 할 수 있고, 인터페이스는 개수 제한 없이 구현할 수 있음.
  • override: 자바의 @Override 애노테이션과 같은 기능을 함(상위 클래스나 상위 인터페이스에 있는 프로퍼티나 메소드를 오버라이드한다는 표시), 자바와 달리 코틀린에서는 override 변경자를 반드시 사용해야함.(상위 클래스에 있는 메소와 같은 메소드를 하위 클래스에서 선언하면 컴파일이 안되기 때문)

출력 결과

* 인터페이스 메소드로 디폴트 구현을 할 수 있음.

☞ 이 경우 자바에서는 메소드 앞에 default를 붙여야 하지만 코틀린에서는 그냥 메소드 본문을 쓰면 됨.

 

인터페이스 안에 디폴트 메소드 구현 예시

  • click(): 일반 메소드 선언
  • showOff(): 디폴트 구현을 한 메소드
  • 따라서 이 인터페이스를 구현하는 클래스는 click에 대한 구현을 반드시 제공해야 하며, showOff 메소드는 새로 정의할 수도 있고 생략할 수도 있음.

Clickable 인터페이스와 동일한 메소드를 구현한 다른 인터페이스 예시

위의 인터페이스는 Clickable 인터페이스와 동일한 메소드인 showOff() 메소드를 정의하고 있음.

한 클래스에서 Clickable과 Focusable 인터페이스를 모두 구현하면 어느 인터페이스의 showOff 메소드가 선택될까?

 

이를 확인하기 위한 코드를 작성해보면,

showOff 메소드 확인 예시

위와 같이 작성할 수 있는데, 이를 실행해보면

출력 결과

위와 같은 컴파일 오류가 발생함. 

이는 두 상위 인터페이스에 정의된 showOff 메소드의 구현을 대체할 오버라이딩 메소드를 직접 제공하지 않았기 때문에 발생한 것임.

 

따라서 이런 경우에는 아래와 같이 하위 클래스에 강제적으로 직접 구현을 해야함.

상속한 인터페이스의 메소드 구현 예시

  • 만약 두 인터페이스 중 하나만 호출해도 된다면 override fun showOff() = super<Clickable>.showOff() 이런식으로 작성하면 됨. 

출력 결과


[open, final, abstract 변경자]

 

* 코틀린에서는 기본적으로 클래스와 메소드가 final임.

☞ 따라서 어떤 클래스의 상속을 허용하려면 클래스 앞에 open 변경자를 붙여야 함.

☞ 이와 마찬가지로 오버라이드를 허용하고 싶은 메소드나 프로퍼티 앞에서 open 변경자를 붙여야 함.

 

open 메소드를 포함하는 open 클래스 정의 예시

  • RichButton 클래스: open 클래스임. 따라서 다른 클래스가 이 클래스를 상속할 수 있음
  • disable 메소드: final 메소드임. 따라서 하위 클래스가 이 메소드를 오버라이드할 수 없음
  • animate 메소드: final 메소드임. 따라서 하위 클래스가 이 메소드를 오버라이드할 수 없음
  • click 메소드: 이 메소드는 상위 클래스의 open 메소드를 오버라이드함. 따라서 오버라이드한 메소드는 기본적으로 open메소드라는 것을 알 수 있음

* 자바와 마찬가지로 코틀린에서도 클래스를 abstract 선언할 수 있음

  • abstract 클래스는 인스턴스화 할 수 없음
  • 추상 클래스에는 구현이 없는 추상 멤버가 있어서 하위 클래스에서 추상 멤버들을 반드시 오버라이드해야함
  • 따라서 추상 멤버는 항상 열려있음
  • 그래서 추상 멤버 앞에 open 변경자를 명시할 필요가 없음

추상 클래스 예시

  • Animated 클래스: 추상클래스. 이 클래스의 인스턴스는 만들 수 없음
  • animate 메소드: 추상 함수. 구현이 없기 때문에 하위 클래스에서 반드시 오버라이드 해줘야 함
  • stopAnimating 메소드, animateTwice 메소드: 추상클래스에 있더라도 추상 함수가 아니기 때문에 기본적으로 final 이지만 원한다면 open 변경자로 오버라이드를 허용할 수 있음.

※ 상속 변경자 정리

변경자 이 변경자가 붙은 멤버는 설명
final 오버라이드 할 수 없음 클래스 멤버의 기본 변경자
open 오버라이드 할 수 있음 반드시 open을 명시해야 오버라이드 가능
abstract 반드시 오버라이드 해야 함 추상 클래스의 멤버에만 이 변경자를 붙일 수 있으며 추상 멤버에는 구현이 있으면 안됨.
override 상위 클래스나 상위 인스턴스의 멤버를 오버라이드 하는 중  오버라이드 하는 멤버는 기본적으로 열려있으며, 하위 클래스의 오버라이드를 금지하려면 final로 명시해주면 됨.

[가시성 변경자(visibility modifier)]: 클래스 외부 접근을 제어함.

 

* 기본적으로 코틀린과 자바의 가시성 변경자는 비슷함.

 

※ 가시성 변경자 정리

변경자 클래스 멤버 최상위 선언
public(기본 가시성) 모든 곳에서 볼 수 있음 모든 곳에서 볼 수 있음
internal 같은 모듈 안에서만 볼 수 있음 같은 모듈 안에서만 볼 수 있음
protected 하위 클래스 안에서만 볼 수 있음 (최상위 선언에 적용할 수 없음)
private 같은 클래스 안에서만 볼 수 있음 같은 파일 안에서만 볼 수 있음

* 모듈(modual): 한꺼번에 컴파일되는 코틀린 파일들. ex) 인텔리J, 이클립스, 메이븐, 그레이들 등의 프로젝트 


[내부 클래스 & 중첩 클래스]: 클래스를 캡슐화하거나 코드 정의를 그 코드를 사용하는 곳 가까이에 두고 싶을 때 유용.

☞ 자바와 차이: 코틀린의 중첩클래스는 명시적으로 요청하지 않으면 외부 클래스 인스턴스에 대한 접근권한이 없음.

 

  • 코틀린의 중첩 클래스는 아무런 변경자가 붙지 않으면 자바에서 static 중첩 클래스와 같음
  • inner 변경자를 붙이면 중첩 클래스를 내부 클래스로 변경해서 외부 클래스에 대한 참조를 포함할 수 있음.

※ 내부클래스 & 중첩 클래스 정리

클래스 B안에 정의된 클래스 A 자바 코틀린
중첩 클래스(외부 클래스에 대한 참조를 저장하지 않음) static class A class A
내부 클래스(외부 클래스에 대한 참조를 저장함) class A inner class A
  • 내부 클래스(inner)에서 외부 클래스(outer)의 참조에 접근하기 위해서는 this@Outer이라고 써야 함.

[봉인된 클래스]

 

sealed 변경자: 상위 클래스에 이 변경자를 붙이면 그 상위 클래스를 상속한 하위 클래스의 정의를 제한할 수 있음

☞ 따라서 sealed 클래스의 하위 클래스를 정의할 때는 반드시 상위 클래스 안에 중첩 시켜야 함.

  • when 식에서 sealed 클래스의 모든 하위 클래스를 처리해야한다면 디폴트 분기(else 분기)가 필요 없음(when 식이 모든 하위 클래스를 검사하므로)
  • sealed로 표시된 클래스는 자동으로 open 임
  • sealed 인터페이스는 정의할 수 없음 → 봉인된 인터페이스를 만든다면 이 인터페이스를 자바에서 구현하지 못하게 막을 수 있는 수단이 코틀린에는 없기 때문

 

 

 

본 게시물은 "Kotlin IN ACTION"을 참고함.

Comments