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: 상위 타입을 오버라이드하고 있다.