상속
추상 클래스 상속
- 상속을 받을 때는 extends가 아닌 :을 사용
- 부모 클래스의 생성자를 바로 호출
- kotlin의 클래스는 기본적으로 final: 상속 허용을 위해서는 open 키워드를 사용
- 추상 멤버가 아니면 오버라이드 불가능
- 생성자 또는 초기화 블럭에서 사용되는 프로퍼티는 open 사용을 피하기
- 자식 클래스에서 메서드나 프로퍼티를 재정의하려면 override를 명시
- 부모 클래스의 기능을 사용할 때는 super 사용
- 정적 메소드가 없음
- package-level 함수를 대신 사용
- object, compoanion object 사용
open class Animal (
protected val species: String,
protected val legCount: Int,
){
open fun sound() {
println("동물이 소리를 냅니다.")
}
}
class Dog(
species: String: Animal(species, 4) {
override fun sound() {
println("멍멍!")
}
}
인터페이스 상속
- extdes가 아닌 :을 사용
- default 키워드를 붙일 필요는 없음
- 중복되는 인터페이스를 특정 시, super<타입>.함수
interface Flyable {
fun act() { // default 메서드
println("파닥 파닥")
}
fun fly() // 추상 메서드
}
class Penguin(
species: String
) : Animal(species, 2), Swimable, Flyable {
private val wingcount: Int = 2
...
override fun act() {
super<Swimable>.act() // Swimable.super.act()
super<Flyable>.act()
}
}
인터페이스
- interface 키워드 사용
- 접근 제어자는 public, open이며 접근 제어자 변경은 불가능
- 구현(implementation)이 없는 함수만 가지거나, 기본 구현을 가짐
- 클래스가 인터페이스를 상속받아 구현 → 클래스에서 인터페이스의 메서드들의 구현 부분을 채운 후 사용
- 프로퍼티 선언이 가능
- 인터페이스에서 초기화 불가능
- 클래스에서 게터/세터 디폴트 구현을 가질 수 있으며 구현하지 않을 경우 디폴트 구현이 사용
- filed 키워드 사용은 불가능
- :을 사용하여 인터페이스 구현
- 추상 메소드 뿐만 아니라 구현이 있는 메소드도 정의 가능
- 다중 구현이 가능
- 코틀린은 클래스의 다중 상속은 불가능하지만 인터페이스는 다중 상속이 가능
interface Movable {
fun move()
}
interface Eatable {
fun eat() {
println("먹는다.")
}
}
interface Playable {
fun play()
val playtype: String
var playtime: Int
}
class Person : Movable, Eatable, Playable {
override fun move() {
println("사람이 움직인다.")
}
override val palytype: String = ""
override val playtime: Int = 0
}
추상클래스
- abstract 키워드를 사용하여 정의
- 접근 제어자는 public, open이며 반드시 override
- 추상메소드/프로퍼티가 아닌 일반 메서드/프로퍼티의 기본 접근 제어지는 public, final
- 인스턴스화 불가능: 그 자체의 객체 생성 불가능
- 추상 메서드와 일반 메서드 사용 가능
- 추상 메서드가 하나라도 있다면 그 클래스는 추상 클래스
- abstract 키워드로 추상 메서드 정의
- 구현부(블럭)를 가질 수 없음
- 추상 메서드는 자식 클래스에서 override하여 사용
- 공통된 구현을 가질 수 있음: 일반 메서드도 포함 가능
- 인터페이스와 달리 생성자나 상태(filed)를 가질 수 있음
- 생성자를 가질 수 있음
- concreate(비추상, 구상) 프로퍼티를 초기화
- 클래스는 하나의 추상 클래스만 상속 가능
- 추상 클래스도 추상 클래스 상속 가능
abstract class Animal {
abstract fun makeSound()
fun sleep() {
println("잠을 잡니다")
}
}
class Cat : Animal() {
override fun makeSound() {
println("야옹~")
}
}
클래스, 추상 클래스, 인터페이스 비교
클래스 | 추상클래스 | 인터페이스 | ||
키워드 | class | abastract class | interface | |
상속(구현)해주는 일반적인 방법 | class 하위 클래스 이름 : 상위 클래스 이름() |
class 하위 클래스 이름 : 상위 추상 클래스 이름() |
class 하위 클래스 이름 : 상위 인터페이스 이름 |
|
객체 생성 | 가능 | 불가능 | 불가능 | |
기본 접근 제어자 | public, final | abastract | poublic, open (have to override) |
public, open (have orride) (변경 불가) |
concrete | public, final | |||
특정 클래스가 상속 받을 수 있는 최대 개수 | 1개 | 1개 | 1개 이상 | |
디폴트 메서드 / 프로퍼티 | - | absract | 구현 불가 | 구현부가 디폴트 / 게터 세터 구현이 디폴트 |
concrete | - |
퀴즈
객관식
1. 상속과 다형성
다음 코드의 출력 결과는?
open class Parent {
open fun hello() = println("Hello from Parent")
}
class Child : Parent() {
override fun hello() = println("Hello from Child")
}
fun greet(p: Parent) {
p.hello()
}
fun main() {
val c = Child()
greet(c)
}
- Hello from Parent
- Hello from Child
- 컴파일 오류
- 아무것도 출력되지 않음
답: 2
2. 인터페이스 구현
interface A {
fun show() = println("A")
}
interface B {
fun show() = println("B")
}
class C : A, B {
override fun show() {
super<A>.show()
super<B>.show()
}
}
fun main() {
C().show()
}
- A
- B
- A B
- 컴파일 오류
답: 3
3. 추상 클래스와 구현
abstract class Animal {
abstract fun sound(): String
}
class Cat : Animal() {
override fun sound() = "Meow"
}
fun main() {
val animal: Animal = Cat()
println(animal.sound())
}
- 컴파일 오류
- Meow
- Cat
- 아무것도 출력되지 않음
답: 2
서술형
1. 상속과 override
다음 코드를 실행했을 때 출력 결과는?
open class Animal {
open fun speak() {
println("동물이 소리를 낸다")
}
}
class Dog : Animal() {
override fun speak() {
println("멍멍")
}
}
fun main() {
val myDog: Animal = Dog()
myDog.speak()
}
답: 멍멍
2. 인터페이스
interface Clickable {
fun click()
}
interface Focusable {
fun setFocus(b: Boolean)
}
class Button : Clickable, Focusable {
override fun click() {
println("클릭됨")
}
override fun setFocus(b: Boolean) {
println("포커스 상태: $b")
}
}
위 클래스 Button을 main 함수에서 사용하려면 어떻게 호출할까?
답: val btn = Button()
3. 추상 클래스
abstract class Shape {
abstract fun area(): Double
}
class Circle(val radius: Double) : Shape() {
override fun area(): Double {
return 3.14 * radius * radius
}
}
Circle(3.0).area()의 결과는?
답: 28.26
'개발새발 > 코틀린' 카테고리의 다른 글
[코틀린/Kotlin] 람다와 고차함수 (3) | 2025.08.18 |
---|---|
[코틀린/Kotlin] 컬렉션 (3) | 2025.08.16 |
[코틀린/Kotlin] 함수 및 클래스 구조 (1) | 2025.08.12 |
[코틀린/Kotlin] 조건문과 반복문 (2) | 2025.08.11 |
[코틀린/Kotlin] 자료형과 변수 (5) | 2025.08.09 |