abstract class Shape(val name: String) {
// 추상 메서드
abstract fun getArea(): Double
// 일반 메서드
fun printName() {
println("도형 이름: $name")
}
}
class Square(name: String, val side: Double) : Shape(name) {
// 추상 메서드 구현
override fun getArea(): Double {
return side * side
}
}
class Circle(name: String, val radius: Double) : Shape(name) {
// 추상 메서드 구현
override fun getArea(): Double {
return Math.PI * radius * radius
}
}
fun main() {
val square = Square("정사각형", 5.0)
square.printName()
println("넓이: ${square.getArea()}")
val circle = Circle("원", 2.0)
circle.printName()
println("넓이: ${circle.getArea()}")
}
[출력 결과]
도형 이름: 정사각형
넓이: 25.0
도형 이름: 원
넓이: 12.566370614359172
interface Vehicle {
fun start()
fun stop()
// 인터페이스 내부에서 메서드 구현(default 메서드)
fun horn() {
println("Beep beep!")
}
}
class Car : Vehicle {
override fun start() {
println("Car started.")
}
override fun stop() {
println("Car stopped.")
}
}
fun main() {
val car = Car()
car.start()
car.horn() // 인터페이스에서 구현한 디폴트 메서드 호출
car.stop()
}
[출력 결과]
Car started.
Beep beep!
Car stopped.
만약, 클래스가 여러 개의 부모 클래스를 가지고 있고, 부모 클래스들 중에서 같은 이름의 메서드가 있는 경우, super 키워드로 부모 클래스의 메서드를 호출하면 어떤 클래스의 메서드를 호출해야 할 지 모호해집니다.
이런 경우에는 super<클래스명>.메서드명() 형태로 호출하면 특정 부모 클래스의 메서드를 호출할 수 있습니다.
다음은 "super<클래스명>.메서드명()"를 사용하는 예제 코드입니다
open class A {
open fun foo() {
println("A's foo")
}
}
interface B {
fun foo() {
println("B's foo")
}
}
class C : A(), B {
override fun foo() {
super<A>.foo() // A 클래스의 foo() 호출
super<B>.foo() // B 인터페이스의 foo() 호출
}
}
fun main() {
val obj = C()
obj.foo()
}
[출력 결과]
A's foo
B's foo