이미지 순서대로 시작해보자!
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
func sum(_ a: Double, _ b: Double) -> Double {
return a + b
}
func sum(_ a: String, _ b: String) -> String {
return a + b
}
sum(1,3) // 4
sum(1.0,3.0) // 4.0
sum("a","b") // ab
class Animal {
func description() {
print("동물입니다")
}
}
class Cat: Animal {
override func description() {
super.description() // "동물입니다"
print("고양이입니다") // "고양이입니다"
}
func description() { // !CompileError: 메소드명 중복
print("고양이입니다")
}
override func printHello() { // !CompileError: 상위클래스에 해당 메소드가 없음
print("고양이입니다")
}
}
let cat = Cat.init()
cat.description()
상속받은 프로퍼티를 오버라이딩하여 해당 속성에 대한 getter/setter를 제공하거나 상속받은 프로퍼티 값의 변경을 추적할 수 있도록 프로퍼티 옵저버 추가할 수 있다.
서브 클래스에서는 상속된 프로퍼티의 특성이 저장 프로퍼티인지, 연산 프로퍼티인지 알 수 없고, 상속받은 프로퍼티의 이름과 타입 정도만 알고 있다.
따라서, 오버라이딩을 할 경우 프로퍼티의 이름과 타입을 반드시 명시해줘야 한다.
class Product {
var name = "Pencil"
}
class Pencil: Product {
// !Compile Error
override var name: String = "Pencil2" // Cannot override with a stored property 'name'
// !Compile Error
var subName = "Pencil2"
override var name: String {
return self.subName // Cannot override mutable property with read-only property 'name'
}
// getter/setter로 오버라이딩 가능
override var name: String {
get {
return self.subName
}
set {
self.subName = newValue
}
}
}
let product: Product = .init()
product.name // Pencil
let pencil: Pencil = .init()
pencil.name // Pencil2
// 상위 클래스가 getter로만 구현된 경우
class Human {
var name = "Jaekyung"
var alias: String {
return self.name + " 개발자"
}
}
// 하위 클래스에서 getter만 구현
class Developer: Human {
override var alias: String {
return self.name + " iOS 개발자"
}
}
// 하위 클래스에서 setter 추가 구현하여 getter/setter가진 경우
class Developer: Human {
override var alias: String {
get {
return self.name + " iOS 개발자"
} set {
self.name = newValue
}
}
}
let human: Human = .init()
human.alias // "Jaekyung 개발자"
let developer: Developer = .init()
developer.alias // "Jaekyung iOS 개발자"
class Human {
var name = "Jaekyung"
}
class Developer: Human {
override var name: String {
willSet {
print("변경예정 \(newValue)") // "변경예정 iOS 개발자\n"
}
didSet {
print("변경됨 \(oldValue)") //"변경됨 Jaekyung\n"
}
}
}
let developer: Developer = .init()
developer.name = "iOS 개발자"
class Human {
var name = "Jaekyung"
var alias: String {
get {
return name + "사람"
}
set {
self.name = newValue
}
}
}
class Developer: Human {
override var name: String {
willSet {
print("상속받은 name을 \(newValue)로 변경 예정") // "상속받은 name을 iOS 개발자로 변경 예정\n"
}
didSet {
print("상속받은 name은 원래 \(oldValue)였음") // "상속받은 name은 원래 Jaekyung였음\n"
}
}
}
let developer: Developer = .init()
developer.name = "iOS 개발자"
class Human {
final var name = "Jaekyung"
final func description() {
print("안녕하세요!")
}
}
class Developer: Human {
// !Compile Error
override func description() {
// Instance method overrides a 'final' instance method
}
}
무언가를 구분하고 익힐 때에는 이미지와 코드 예제가 참 기억에 많이 남게 되는것 같다!
참고:
오버로딩 https://babbab2.tistory.com/129
오버라이딩 https://babbab2.tistory.com/126
https://programmingnote.tistory.com/29