Animal
과 이를 상속한 Cat
과 Penguin
예제를 살펴보자abstract class Animal(
protected val species: String, // 무슨 종인지
protected open val legCount: Int // 다리 개수, Penguin에서 오버라이드가 필요해 open 추가
) {
abstract fun move()
}
class Cat(
species: String
) : Animal(species, 4) { // 고양이 다리는 4개
override fun move() {
println("고양이가 사뿐 사뿐 걸어가~")
}
}
class Penguin(
species: String
) : Animal(species, 2) { // 펭귄 다리는 2개
private val wingCount: Int = 2 // 펭귄 날개는 2개
override fun move() {
println("팽귄이 움직인다.")
}
override val legCount: Int // legCount 프로퍼티를 오버라이드
get() = super.legCount + this.wingCount
}
extends
키워드 대신 :
키워드를 사용super
를 호출하는 것 대신 :
으로 상속 받는 위치에서 상위 클래스 생성자를 바로 호출한다.override fun
을 사용한다.open
을 꼭 붙여야 한다.super
로, 자신은 this
로 접근한다.Flyable
과 Swimmable
을 구현한 Penguin
예제interface Flyable {
fun act() {
println("파닥 파닥")
}
}
interface Swimmable {
fun act() {
println("어푸 어푸")
}
}
default
키워드 없이 구현부를 작성하면 디폴트 메서드를 만들 수 있다.class Penguin(
species: String
) : Animal(species, 2), Swimable, Flyable {
private val wingCount: Int = 2
override fun move() {
println("팽귄이 움직인다.")
}
override val legCount: Int
get() = super.legCount + this.wingCount
override fun() {
super<Swimable>.act()
super<Flyable>.act()
}
}
:
을 사용super<타입>.함수
를 사용interface Swimmable {
val swimAbility: Int // backing field 없는 프로퍼티
fun act() {
println("어푸 어푸")
}
}
class Penguin(
species: String
) : Animal(species, 2), Swimable, Flyable {
// ...
override val swimAbility: Int // 구현체에서 오버라이드 가능
get() = 3
}
Base
클래스를 Derived
클래스가 상속하는 예제를 살펴보자
open class Base( // 상속이 가능하도록 open
open val number: Int = 100 // 오버라이드 가능하도록 open
) {
init {
println("Base Class")
println(number)
}
}
class Derived(
override val number: Int // number 프로퍼티 오버라이드
) : Base(number) {
init {
println("Derived Class")
}
}
fun main() {
Derived(300)
// 출력 결과
// Base Class
// 0
// Derived Class
}
Base
의 init
블록, Derived
클래스의 init
블록이 차례로 실행 되었고 number
값이 0
으로 출력된다.Accessing non-final property number in constructor
Base
클래스의 init
블록의 number
를 출력하는 코드에 발생하는 경고이다.Derived
)에 number
가 아직 초기화 되지 않은 단계에서 상위 클래스 생성자에서 출력하려고 했기 때문에 기본값인 0이 출력된 것public final class Derived extends Base {
private final int number;
public Derived(int number) {
super(number); // 1. 상위 클래스 생성자 호출, number 초기화 안 됨
this.number = number; // 4. number 초기화
// ...
}
}
public class Base {
private final int number;
public Base(int number) {
this.number = number; // 2. 초기화되지 않은 number 전달 받음
// ...
System.out.println(var3); // 3. 초기화되지 않은 number 출력 -> 0
}
// ...
}
open
을 피해야 한다.final
: override
를 할 수 없게 한다. 기본적으로 보이지 않게 존재open
: override
를 열어 준다.abstract
: 반드시 override
해야 한다.override
: 상위 타입을 오버라이드하고 있다.