seong_hye, the developer

Swift) 문법 정리 - 상속 본문

IOS

Swift) 문법 정리 - 상속

seong_hye 2022. 7. 12.

 

흔히 아는 상속의 뜻은 부모가 자식에게 물려주는 것을 의미하듯이

프로그래밍에서도 상속은 부모가 자식에게 물려주는 것을 의미한다.


상속

클래스만 가지는 성격으로

본직적으로 성격이 비슷한 타입을 새로 만들어

데이터(저장속성)를 추가하거나 기능(메서드)을 변형시켜서 사용하려는 것

class 클래스 이름: 부모클래스 이름 {
	프로퍼티와 메서드들
}

 

상속의 특징

- 상속 하는 클래스는 상위, 메인, 부모 클래스라고 함

- 상속받은 클래스를 하위, 서브, 자식 클래스라고 함

- 상속된 클래스는 부모 클래스의 모든 기능을 상속받으며 자신만의 기능을 추가하게 함

- 하나의 클래스는 하위 클래스를 얼마든지 가질 수 있음

- 하위 클래스는 다중 상속 불가능함

 

class Person {
	var id = 0
    var name = "이름"
    var email = "abc@gmail.com"
}

class Student: Person {
	// id, name, email을 가짐
    var studentId = 0
}

class Undergraduatel: Student {
	//id, name, email, studentId를 가짐
    var major = "전공"
}

 

오버로딩 vs 오버라이딩

오버로딩(overloading) - 함수에서 함수의 하나의 이름에 여러 함수를 대응시켜서 사용

오버라이딩(overriding) - 클래스의 상속에서 상위클래스의 속성/메서드를 재정의하는 것


UIKit 상속 구조

developer.apple.com/documentation/uikit

 

세밀하고 복잡한 클래스 구조도를 가지고 있음

UIKit는 애플의 프레임워크(라이브러리의 집합체)로

iOS 앱을 만들기 위해 세밀하고 복잡한 클래스 구조로 이루어져 있다.

버튼, 이미지, 라벨과 같이 UI를 이루는데 기본적인 요소들이 상속하는 구조도를 확인할 수 있다.


재정의(Overrideing)

자식클래스가 부모클래스로부터 상속받은 메서드나 프로퍼티 등을 변경하여 사용할 수 있는 것

앞에 override 키워드를 붙여 사용

스위프트 컴파일러가 부모클래스에 해당하는 프로펀티나 메서드 등이 있는지 확인 후 재정의 함

이때 만약 부모 클래스에 해당 특성이 없으면 컴파일 에러 발생

class Vehicle {  
	var name = "name"
	 var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    
    func makeNosie() {
    	print("noise")	
    }
}

class Train: Vehicle {
    override func makeNoise() {
        print("choo choo")
    }
}

let train = Train()
train.makeNoise()

 

Train 클래스가 상속 받은 Vehicle 클래스의 makeNoise() 메서드를 override함

 

재정의 가능한 대상(멤버)

속성( 하지만 저장 속성에 대한 재정의는 어떠한 경우에도 불가능)

메서드 (메서드, 서브스크립트, 생성자)

 

 프로퍼티 재정의 규칙

저장 속성의 경우

원칙적으로는 재정의불가

메서드 형태로 추가하는 재정의는 가능

(계산 속성, 속성감시자 형태로 재정의 가능)

class Vehicle {  
	 var currentSpeed = 0.0
   	 var halfSpeed: Double {
     	get {
        	return currentSpeed / 2
        }
        set {
        	currentSpeed = newValue * 2
        }
     }
}

class Biycle: Vehicle {
   var hasBasket = false
   
   override var currentSpeed: Double {
       get {
        	return super.currentSpeed
       }
       set {
        	super.currentSpeed = newValue
       }
}

 

계산 속성의 경우

계산속성의 재정의는 실질적 메서드 대체

확장 방식의 재정의 가능 ex) 읽기 -> 읽기/쓰기

속성 감시자를 추가하는 재정의 가능(실질적 단순 메서드 추가)

class Vehicle {  
	 var currentSpeed = 0.0
   	 var halfSpeed: Double {
     	get {
        	return currentSpeed / 2
        }
        set {
        	currentSpeed = newValue * 2
        }
     }
}

class Biycle: Vehicle {
   var hasBasket = false
   
   override var halfSpeed: Double {
       willSet {
        	print("값이 \(halfSpeed)에서 \(newValue)로 변경 예정")
       }
       didSet {
        	print("값이 \(oldValue)에서 \(halfSpeed)로 변경 예정")
       }
}

메서드 재정의 규칙

일반적으로 상위 구현의 메서드를 대체 및 변형 할 수도 있으므로,

자유롭게 재정의 가능

 

class Vehicle {  
	 var currentSpeed = 0.0
   	 var datas = ["1","2","3","4","5"]
     func makeNoise() {
     	print("noise")
    }
    
    subscript(index: Int) -> String {
    	get {
        	if index > 4 {
            	return "0"
            }
            return datas[index]
        }
        set {
        	datas[index] = newValue
        }
    }
}

class Biycle: Vehicle {
   override func makeNoise() {
   		print("자전거가 지나가고 소리친다")
   }
}

super 키워드

부모 클래스의 프로퍼티나 메서드를 사용하고 싶을 때 사용하는 키워드

class Train: Vehicle {
    override func makeNoise() {
    	super.makeNoise()
        print("choo choo")
    }
}

let train = Train()
train.makeNoise()	//"noise" "choo choo"

final 키워드

클래스 앞에 붙여 클래스의 상속을 금지시키는 키워드

각 멤버 앞에 붙인 경우, 해당 멤버 재정의 불가라는 뜻

final class Person() {
	var id = 0
    var name = "이름"
    var email = "abc@gmail.com"
}

class Studnet: Person {		//에러 발생!!!!
	var studentId = 0
}

왜 사용해?

상속을 하지않는 클래스의 상속을 막음으로써 유일해지고

컴파일 시기에 이미 어떠한 메소드와 프로퍼티를 호출할지 결정(Static Dispatch)됨으로 성능적으로 유리해짐


참고자료)

https://zrr.kr/qNHN

 

앨런 Swift문법 마스터 스쿨 (온라인 BootCamp - 2개월과정) 강의 - 인프런

Swift문법을 제대로 이해, 활용해보고자 하는 철학을 바탕으로 과정이 설계되었습니다. 코딩에 대해 1도 모르는 비전공자를 시작으로 네카라쿠배에 입사할 수 있는 초고급 수준까지 올리는 것을

www.inflearn.com

 

Comments