메서드(Method)
인스턴스 메서드(Instance Methods)
가장 기본적인 메서드
구조체의 인스턴스 메서드
값 타입(구조체, 열거형)에서 기본적으로 인스턴스 메서드 내에서 속성을 수정할 수 없음
수정하려면, mutating(변형되는)키워드를 붙이면 속성 수정 가능해짐(클래스와 구조체의 차이)
struct Dog2 {
var name: String
var weight: Double
init(name: String, weight: Double) {
self.name = name
self.weight = weight
}
func sit() {
print("\(name)가 앉았습니다.")
}
mutating func changeName(newName name: String) { // mutating 생략 불가
self.name = name
}
}
mutate: 변형되다 (mutating - 변형되는)
컴파일러가 알아서 수정해줌 (실수에 대한 자동 방지가 되지만, 문법적으로 인지하고 있어야함)
스택에 영역에 저장하는 것은 메서드로 바꿀 수 없다 라고 간단히 생각해도 됨
오버로딩(Overloading)
함수에서의 오버로딩과 동일하게 클래스, 구조체, 열거형의 메서드에서도 오버로딩 지원
타입 메서드 (Type Methods)
메서드이지만, 인스턴스의 성격이 아닌 타입 자체의 성격에 가까운 메서드일 때, 타입메서드로 구현 가능
class Dog {
static var species = "Dog"
var name: String
var weight: Double
init(name: String, weight: Double) {
self.name = name
self.weight = weight
}
func sit() {
print("\(name)가 앉았습니다.")
}
func trainning() {
print("월월 저는 \(Dog.species)입니다.")
sit()
sit()
self.sit()
}
func changeName(newName name: String) {
self.name = name
}
static func letmeKnow() { // 타입 메서드에서, 타입속성에 접근시에는 타입으로 접근하지 않아도 됨
print("종은 항상 \(species)입니다.") // Dog.species라고 써도됨. -> 얘 자체가 타입 메서드이기 때문
}
}
일반메서드 호출
let bori = Dog(name: "보리", weight: 20.0)
bori.sit()
bori.changeName(newName: "말썽쟁이보리")
bori.sit()
타입 메서드의 호출
Dog.letmeKnow() // "종은 항상 Dog입니다."
타입이름명시.
인스턴스 기능이 아닌, 타입 자체에 필요한 기능을 구현할 때 주로 사용
타입 자체가. 가져야 하는 공통된 기능(동작) 구현시
타입 메서드 사용 예시
Int.random(in: 1...100)
Double.random(in: 1.2...3.7)
클래스 - 타입 메서드의 상속
상속부분 공부 후 다시 볼 것임
타입 메서드를 상속시 재정의 가능 하도록 하려면 -> static 키워드를 상속가능한 class 키워드로 바뀌어야 함
// 상위클래스
class SomeClass {
class func someTypeMethod() { // 타입 메서드 / static일때는 재정의 불가
print("타입과 관련된 공통된 기능의 구현")
}
}
SomeClass.someTypeMethod()
// 상속한 서브클래스
class SomeThingClass: SomeClass {
override class func someTypeMethod() {
//super.someTypeMethod()
print("타입과 관련된 공통된 기능의 구현(업그레이드)")
}
}
SomeThingClass.someTypeMethod()
class - 상속시 재정의 가능 키워드
static 키워드로 선언하면 (상속시)재정의 불가 (상속이 불가한 것 아님)
서브스크립트(Subscripts)
대괄호를 이용해서 접근가능하도록 만든 문법을 가르킨다.
- 배열
array[인덱스]
- 딕셔너리
dictionary[키]
대괄호는 사실 특별한 형태의 메서드(기능) 호출 역할 -> 메서드를 직접 구현도 가능
var array = ["Apple", "Swift", "iOS", "Hello"]
array[0] // "Apple"
array[1] // "Swift"
내부적으로 대괄호를 사용하면 어떤 값을 리턴하도록 구현이 되어 있어서 가능한 일
인스턴스.0
인스턴스.method() -> 이런 형태가 아닌
인스턴스[파라미터] -> 이런 형태로 동작을 가능하게 한 문법(대괄호로 메서드의 기능을 대신)
(인스턴스) 서브스크립트(Subscriptes)의 직접 구현 - 클래스, 구조체, (열거형)
인스턴스 메서드로써의 서브스크립트 구현
class SomeData {
var datas = ["Apple", "Swift", "iOS", "Hello"]
subscript(index: Int) -> String { // 1) 함수와 동일한 형태이지만, 이름은 subscript
get { // 2) get/set은 계산속성에서의 형태와 비슷
return datas[index]
}
set(parameterName) {
datas[index] = parameterName // 또는 파라미터 생략하고 newValue로 대체 가능(계산 속성의 setter와 동일)
}
}
}
var data = SomeData()
data[0] // get블럭 실행
//data[0] = "AAA" // set블럭 실행
파라미터 생략 불가(값이 반드시 필요)
리턴형도 생략 불가능(저장할 값의 타입 명시 필요)
읽기 전용(read-only)으로 선언 가능 (set블록은 선택적으로 구현이 가능하고, 쓰기 전용으로의 선언은 불가)
서브스크립트 사용 예시 - 대괄호 형태로 사용하는 메서드
struct TimesTable {
let multiplier: Int = 3
subscript(index: Int) -> Int { // get만 가능 set구현 X
return multiplier * index
}
}
let threeTimesTable = TimesTable()
print("6에 3배를 하면 숫자 \(threeTimesTable[6]) 이(가) 나옵니다.")
threeTimesTable[2] // 6
struct Matrix {
// 2차원 배열
var data = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
// 2개의 파라미터를 받는 읽기전용 서브스크립트의 구현
subscript(row: Int, column: Int) -> String? {
if row >= 3 || column >= 3 {
return nil
}
return data[row][column]
}
}
// 2개의 파라미터를 받는 서브스크립트 구현도 가능
var mat = Matrix()
mat[0, 1]! // 대괄호 안에 파라미터 2개 필요
타입 서브스크립트(Type Subscriptes) - 클래스, 구조체, (열거형)
enum Planet: Int { // 열거형의 원시값
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Planet { // Self
return Planet(rawValue: n)!
}
}
let mars = Planet[4] // Planet.venus
print(mars)
static 또는 class 키워드로 타입 자체의 서브스크립트 구현 가능
class는 상속시 재정의 가능
'iOS 관련 공부' 카테고리의 다른 글
접근제어(Access Control), 싱클톤(Signleton) 패턴 (0) | 2025.02.25 |
---|---|
타입 캐스팅 (Type Casting) (0) | 2025.02.21 |
속성(Property)과 메서드(Method) - 1 (0) | 2025.02.16 |
초기화 (initialization) - 1 (0) | 2025.02.13 |
클래스와 구조체 (0) | 2025.02.06 |