티스토리 뷰
상속(Inheritance)
• 상속이 필요한 경우
- 바탕이 되는 클래스에 확장이 되는 클래스를 만들고 싶은 경우
- 이미 존재하는 클래스를 합칠 때
• open 키워드로 설정된 클래스만 상속할 수 있다.
ex) open class 클래스명() {}
• final 키워드로 설정된 클래스는 상속할 수 없다.
- 명시하지 않는다면 기본적으로 final로 선언.
ex) final class 클래스명() {}
• 상속해준 클래스를 슈퍼 클래스(또는 부모 클래스), 상속받은 클래스를 서브 클래스(또는 자식 클래스)라고 한다.
• 서브 클래스는 슈퍼 클래스가 가지고 있는 모든 것을 물려 받는다.
// 상속을 사용하지 않을 때 - 같은 코드 반복 및 클래스끼리의 연관성 확인 어려움.
class Warrior() {
fun attack() {
println("복잡한 코드 + 공격")
}
}
class DefenseWarrior() {
fun attack() {
println("복잡한 코드 + 공격")
}
fun defense() {
println("방어")
}
}
class HardAttackWarrior() {
fun attack() {
println("복잡한 코드 + 공격")
}
fun hardAttack() {
println("강하게 공격")
}
}
// 상속을 사용할 경우 - 공통된 코드 공유, 클래스끼리 연관성 명시
open class Warrior2(var name: String, var power: Int, var type: String) { // 슈퍼 클래스(부모 클래스)
fun attack() {
println("복잡한 코드 + 공격")
}
}
class DefenseWarrior2(name: String, power: Int) : Warrior2(name, power, "골렘") { // 서브 클래스(자식 클래스)
fun defense() {
println("방어")
}
}
val defenseWarrior2: DefenseWarrior2 = DefenseWarrior2("단단한 골렘", 100)
defenseWarrior2.attack() // defenseWarrior2는 DefenseWarrior2의 인스턴스지만 Warrior2의 메소드 attack()을 상속받았기 때문에 사용할 수 있다.
defenseWarrior2.defense() // defenseWarrior2의 메소드 defense() 사용 가능
• 서브 클래스는 슈퍼 클래스의 생성을 책임져야 한다.
open class Warrior2(var name: String, var power: Int, var type: String) {
fun attack() {
println("복잡한 코드 + 공격")
}
}
// 서브 클래스의 주 생성자가 슈퍼 클래스의 생성을 책임지는 경우
class DefenseWarrior2(name: String, power: Int) : Warrior2(name, power, "골렘") { 주 생성자가 슈퍼 클래스 생성
fun defense() {
println("방어")
}
}
// 서브 클래스의 부 생성자가 슈퍼 클래스의 생성을 책임지는 경우
class HardAttackWarrior2 : Warrior2 {
var bonusPower: Int = 0
// 부 생성자가 슈퍼 클래스 생성
constructor(name: String, power: Int, bonusPower: Int) : super(name, power, "오크") { // super는 슈퍼 클래스(부모 클래스)를 의미한다.
this.bonusPower = bonusPower
}
fun hardAttack() {
println("강하게 공격")
}
}
• 서브 클래스는 슈퍼 클래스가 사용하고 있는 멤버와 동일한 이름의 멤버를 만들 수 없다.
class WizardWarrior(var name: String, var power: Int) : Warrior2(name, power, "고블린"), Warrior() { // 오류 발생 : 슈퍼 클래스에서 사용하고 있는 name, power를 다시 var로 선언할 수 없다.
fun attack() { // 오류 발생 : 슈퍼 클래스에서 사용하고 있는 attack()을 다시 선언할 수 없다.
println("복잡한 코드 + 공격")
}
fun magicAttack() {
println("마법 공격")
}
}
• 상속은 여러 번 할 수 있다. (A --상속--> B, B --상속--> C)
• 다중 상속은 불가능하다. (A, B를 상속하는 클래스 C)
class WizardWarrior2(name: String, power: Int) : Warrior2(name, power, "고블린"), Warrior() { // 오류 발생 : Warrior2와 Warrior 다중 상속 불가능
fun magicAttack() {
println("마법 공격")
}
}
오버라이딩(Overriding)
• 기본적으로는 슈퍼 클래스가 사용하고 있는 멤버와 동일한 이름의 멤버를 만들 수 없다.
• 오버라이딩을 통해 슈퍼 클래스가 가지고 있는 함수를 재정의할 수 있다.
* 재정의
- 재선언
- 이전에 정의한 것을 덮어쓴다. (이전에 정의한 것은 작동하지 않는다.)
• 함수 선언 맨 앞에 override 키워드를 적어준다.
open class Warrior3(var name: String, var power: Int, var type: String) {
open fun attack() {
println("복잡한 코드 + 공격")
}
}
class WizardWarrior3(name: String, power: Int) : Warrior3(name, power, "고블린") {
override fun attack() {
super.attack() // 슈퍼 클래스의 attack 함수
println("마법사라 지팡이로 때리는건 약하다")
}
fun magicAttack() {
println("마법 공격")
}
}
val wizardWarrior3 : WizardWarrior3 = WizardWarrior3("똑똑한 고블린", 50)
wizardWarrior3.attack() // 서브 클래스인 WizardWarrior3에서 정의한 attack() 메소드가 실행된다.
이 글은
패스트 캠퍼스 Android 앱 개발의 정석 with Kotlin 올인원 패키지 Online
강의를 듣고 공부한 내용을 바탕으로 작성되었습니다.
'📱 Android > 💻 Kotlin' 카테고리의 다른 글
[Android/Kotlin] 19. Null Safety (0) | 2022.10.13 |
---|---|
[Android/Kotlin] 18. 형변환 (0) | 2022.10.13 |
[Android/Kotlin] 16. 접근 제한자 (0) | 2022.10.12 |
[Android/Kotlin] 15. 클래스 2편 (2) | 2022.10.12 |
[Android/Kotlin] 14. 클래스(Class) (1) | 2022.10.11 |