Do it! 코틀린 프로그래밍 [둘째마당, 객체 지향 프로그래밍] 학습
abstract
라는 키워드와 함께 선언📌 추상클래스의 정의와 구현
abstract class Vehicle
abstract
로 선언될 수 있음// 추상 클래스 -> 주 생성자에는 비추상 프로퍼티 매개변수가 3개 있음
abstract class Vehicle(val name: String, val color: String, val weight: Double) {
// 추상 프로퍼티 -> 반드시 하위(자식) 클래스에서 재정의 초기화 필요
abstract var maxSpeed: Double
// 일반 프로퍼티 -> 초깃값인 상태를 저장 가능
var year = "2018"
// 추상 메서드 -> 반드시 하위(자식) 클래스에서 구현 필요
abstract fun start()
abstract fun stop()
// 일반 메서드 -> 재정의할 필요 X
fun displaySpecs() {
println("$name, $color, $weight")
}
}
-> Vehicle 클래스는 객체를 생성할 수 없음 (기본 설계 역할만)
-> 추상 클래스에서는 abstract
키워드 자체가 상속과 오버라이딩을 허용하고 있기 때문에 open
키워드가 필요없음
-> 일반 프로퍼티나 메서드를 오버라이딩 하기 위해선 open 키워드 필요
⬇️ 위에서 작성한 인터페이스 구현
// maxSpeed는 오버라이딩
class Car(name: String, color: String, weight: Double, override var maxSpeed: Double) : Vehicle(name, color, weight {
// 추상 메서드 start()와 stop()을 오버라이딩
override fun start() { /* 재정의 */ }
override fun stop() { "Car Stop" }
}
class MotorCycle(name: String, color: String, weight: Double, override var maxSpeed: Double) : Vehicle(name, color, weight) {
override fun start() {
// 추상 메서드 start()와 stop()을 오버라이딩
override fun start() { /* 재정의 */ }
override fun stop() { "MotorCycle Stop" }
}
fun main() {
val car Car("SuperMatiz", "yellow", 1110.0, 270.0)
val motor = MotorCycle("DreamBike", "red", 173.0, 100.0)
car.displaySpecs()
car.stop()
motor.displaySpecs()
motor.stop()
}
-> 각 개체의 start()와 stop()은 추상 메서드로부터 오버라이딩되어 하위 클래스에서 구현
📌 추상 클래스로부터 단일 인스턴스로 객체 생성하기
object
키워드를 사용해서 지정할 수 있음// 추상 클래스
abstract class Printer {
abstract fun print() // 추상 메서드
}
val myPrinter = object: Printer() { // 객체 인스턴스
override fun print() { /* 추상 메서드 구현 */ }
}
fun main() {
myPrint.print()
}
abstract
로 정의된 추상 메서드나 일반 메서드가 포함📌 인터페이스를 쓰는 이유
📌 인터페이스의 선언과 구현
⬇️ 인터페이스의 구조
interface 인터페이스 이름 [: 인터페이스 이름...] {
추상 프로퍼티 선언
추상 메서드 선언
[일반 메서드 선언 {...}]
}
⬇️ 인터페이스 선언
interface Pet {
// abstract키워드가 없어도 기본은 추상 프로퍼티/메서드
var category: String
fun feeding()
// 일반 메서드 : 구현부를 포함하면 일반적인 메서드로 기본이 됨
fun patting() { } // 구현부
}
-> 프로퍼티는 상태를 저장할 수 없기에 기본값을 가질 수 없음
⬇️ 인터페이스로부터 구현 클래스 정의
class Cat(override var category: String) : Pet {
override fun feeding() { /* 구현부 */ }
}
fun main() {
val obj = Cat("small")
obj.feeding() // 구현(오버라이딩)된 메서드
obj.patting() // 기본 메서드
}
-> Cat 클래스는 Pet인터페이스를 구현한 클래스
📌 게터를 구현한 프로퍼티
interface Pet{
val msgTags: String
get() = "I'm your lovely pet!"
}
...
println("$obj.msgTags")
...
📌 인터페이스 구현의 필요성
interface Bird {
val wing: Int
fun jump() { println("Bird Jump") }
}
interface Horse {
var maxSpeed: Int
fun jump() { println("Horse Jump") }
}
class pegasus: Bird, Horse { // 인터페이스 다중 상속
override val wings = 2
override val maxSpeed = 100
override fun jump() { // 오버라이딩 하지 않아도 상관X
super<Horse>.jump() // Horse인터페이스의 jump() 실행
println("Pegasus Jump!")
}
}
fun main() {
val pegasus = Pegasus()
pegasus.jump
// Horse Jump 출력 후 Pegasus Jump! 출력
}
-> 인터페이스와 구현 클래스에서 함수명이 동일한 경우 super<인터페이스 이름>.메서드 이름()
형태로 구분할 수 있음