[Swift Programming] 프로퍼티와 메서드Swift 프로그래밍2022. 7. 12. 06:16
Table of Contents
프로퍼티
1. 정의
Property : 속성이라는 뜻으로 클래스 구조체 또는 열거형 등에 관련된 값을 뜻함
2. 프로퍼티 종류
- 저장 프로퍼티 (Stored Properties)
- 클래스 또는 구조체의 인스턴스와 연관된 값을 저장하는 가장 단순한 개념의 프로퍼티
class ClassName { // 클래스 이름 var propertyName : String = "" // 저장 프로퍼티 } struct Info{ var name : String // 저장 프로퍼티 }
- 연산 프로퍼티 (Computed Properties)
- 값을 연산하는 프로퍼티
- 접근자의 역할이나, 설정자의 역할을 할 수 있다.
- 접근자와 설정자란?설정자 : 은닉화된 내분의 프로퍼티 값을 간접적으로 설정함
- 이렇게 텍스트로 읽으면 이해가 잘 안되지만, 아래의 예시를 참고하면 조금 이해가 갈 것이다. !
- 접근자 : 인스턴스 내/외부의 값을 연산하여 적절한 값을 돌려줌
- 예시 코드
- struct CoordinatePoint{ var x : Int var y : Int var oppsitePoint : CoordinatePoint{ //연산프로퍼티 //접근자 get{ return CoordinatePoint(x: -x, y: -y) // 인스턴스 내/외부의 값을 연산하여 적절한 값을 반환 } //설정자 (읽기전용 연산 프로퍼티 사용시, 설정자 안해도 됨) set(opposite){ // 내부의 프로퍼티 값을 간접적으로 설정 x = -opposite.x y = -opposite.y } } } var Position : CoordinatePoint = CoordinatePoint(x:10,y:20) print(Position) // CoordinatePoint(x: 10, y: 20) print(Position.oppsitePoint) //CoordinatePoint(x: -10, y: -20) Position.oppsitePoint = CoordinatePoint(x:15,y:10) print(Position) //CoordinatePoint(x: -15, y: -10)
- 메소드를 사용하지 않고, 연산 프로퍼티를 사용하는 이유?
- 인스턴스 외부에서 메서드를 통해 인스턴스 내부 값에 접근하려면 메서드를 두개(접근자, 설정자) 구현해야 함
- 가독성이 나쁘며, 연산 프로퍼티가 훨씬 더 간편하고 직관적
struct CoordinatePoint{ var x : Int var y : Int //접근자 func oppositePoint()-> Self{ return CoordinatePoint(x:-x,y:-y) } //설정자 mutating func setOppositePoint(_opposite : CoordinatePoint){ x = -_opposite.x y = -_opposite.y } } var Position : CoordinatePoint = CoordinatePoint(x:10,y:20) print(Position) //CoordinatePoint(x: 10, y: 20) print(Position.oppositePoint()) //CoordinatePoint(x: -10, y: -20) Position.setOppositePoint(_opposite: CoordinatePoint(x:15,y:10)) print(Position) //CoordinatePoint(x: -15, y: -10)
- 프로퍼티 감시자
- 프로퍼티 감시자를 사용하면 프로퍼티의 값이 변경됨에 따라 적절한 작업을 취할 수 있다
- 프로퍼티 감시자는 프로퍼티의 값이 새로 할당될 때마다 호출
- 프로퍼티 감시자는 저장 프로퍼티뿐만 아니라 프로퍼티를 재정의해 상속받은 저장 프로퍼티 또는 연산 프로퍼티에도 적용 가능
- 프로퍼티 메서드
- willSet 메서드
- 프로퍼티의 값이 변경되기 직전에 호출하는 메서드
- 전달인자 : 프로퍼티가 변경될 값 (newValue)
- didSet 메서드
- 프로퍼티의 값이 변경된 직후에 호출하는 메서드
- 전달인자 : 프로퍼티가 변경되기 전 값 (oldValue)
class Account{ var credit:Int = 0{ willSet{ print("잔액이 \\(credit)원에서 \\(newValue)원으로 변경될 예정입니다.") } didSet{ print("잔액이 \\(oldValue)원에서 \\(credit)원으로 변경되었습니다.") } } } let myAccount : Account = Account() myAccount.credit = 1000 //출력 : // 잔액이 0원에서 1000원으로 변경될 예정입니다. // 잔액이 0원에서 1000원으로 변경되었습니다.
- willSet 메서드
- 타입 프로퍼티 (Type Properties)
- 각각의 인스턴스가 아닌 타입 자체에 속하는 프로퍼티
- 타입프로퍼티의 값은 하나이다.
- 그 타입의 모든 인스턴스가 공통으로 사용하는 값(static constant와 유사), 모든 인스턴스에 공용으로 접근하고 값을 변경할 수 있는 변수(static과 유사) 등을 정의할때 유용
- 타입 프로퍼티의 두가지 종류
- 저장 타입 프로퍼티
- 변수 또는 상수로 선언 가능
- 초깃값 설정해야 하며 지연 연산됨
- 연산 타입 프로퍼티
- 변수로만 선언 가능
class AClass{ //저장 타입 프로퍼티 static var typeProperty : Int = 0 //저장 인스턴스 프로퍼티 var instanceProperty : Int = 0{ didSet{ AClass.typeProperty = instanceProperty + 100 } } // 연산 타입 프로퍼티 static var typeComputedProperty : Int{ get{ return typeProperty } set{ typeProperty = newValue } } } AClass.typeProperty = 123 let classINstance : AClass = AClass() classINstance.instanceProperty = 100 print(AClass.typeProperty) //200 print(AClass.typeComputedProperty) //200
- 저장 타입 프로퍼티
3. 키 경로
- 키 경로를 사용하여 간접적으로 특정 타입의 어떤 프로퍼티 값을 가리켜야 할지 미리 지정해두고 사용할 수 있다.
- 키 경로는 AnyKeyPath라는 클래스로 파생됨
- \타입이름.경로.경로.경로
struct Stuff{
var name : String
}
print(type(of: \\Stuff.name))
//출력 : WritableKeyPath<Stuff, String>
메서드
: 특정 타입에 관련된 함수
- 인스턴스 메서드
- 클래스,구조체,열거형 등은 실행하는 기능을 캡슐화한 인스턴스 메서드
- 타입 메서드
- 타입 자체와 관련된 기능을 실행하는 타입 메서드
- 기존의 프로그래밍 언어에서의 클래스 메서드와 유사한 기능
- 스위프트에서는 프로그래머가 정의하는 타입(클랫, 구조체, 열거형 등)에 자유롭게 메서드를 정의할 수 있다.
1. 인스턴스 메서드
- 특정 타입의 인스턴스에 속한 함수를 뜻함
- 함수와 유일한 차이점으로는, 인스턴스가 존재할 때만 사용이 가능하다는 점이다.
- 구조체나 열거형등의 값 타입은 메서드 앞에 mutating 키워드 사용해야 한다. → 사용 안하면 에러 발생 !
- self 프로퍼티를 이용하여 인스턴스를 더 명확히 지칭할 수 있다.
//클래스 인스턴스
class Info {
var name : String = "None"{
didSet{
print("이름이 \\(name)으로 변경되었습니다.")
}
}
func changeName(name: String){
self.name = name
}
}
var Student1 : Info = Info()
Student1.changeName(name: "Gani")
//구조체나 열거형등의 값 타입은 메서드 앞에 mutating 키워드 사용
struct Info {
var name : String = "None"{
didSet{
print("이름이 \\(name)으로 변경되었습니다.")
}
}
mutating func changeName(Newname: String){
self.name = Newname
}
}
var Student02 : Info = Info()
print(Student02.name)
Student02.changeName(Newname: "ganii")
*클래스의 인스턴스는 참조타입이라서 self 프로퍼티에 다른 참조를 할당할 수 없는데, 구조체나 열거형 등은 self 프로퍼티를 사용하여 자신 자체를 치환할 수 있다.
//클래스 인스턴스
class InfoClass {
var name : String = "None"{
didSet{
print("이름이 \\(name)으로 변경되었습니다.")
}
}
func reset(){
self = InfoClass() // 에러발생 : Cannot assign to value: 'self' is immutable
}
}
//구조체 인스턴스
struct InfoStruct {
var name : String = "None"{
didSet{
print("이름이 \\(name)으로 변경되었습니다.")
}
}
mutating func reset(){
self = InfoStruct()
}
}
var Student02 : InfoStruct = InfoStruct()
Student02.name = "Gani"
Student02.reset()
print(Student02.name) //출력 : None
2. 타입 메서드
- 타입 자체에 호출이 가능한 메서드
- 메서드 앞에 static 키워드를 사용하여 타입 메서드임을 표시
- 클래스의 타입 메서드는 static 키워드와 class 키워드를 사용할 수 있는데, static으로 사용시 재정의가 불가능하고, class 미워드로 정의하면 상속 후 메서드 재정의가 가능하다.
//클래스 인스턴스
class AClass {
static func staticTypeMethod(){
print("Aclass staticTypeMethod")
}
class func classTypeMethod(){
print("Aclass classTypeMethod")
}
}
class BClass : AClass {
// 오류 발생 : Cannot override static method
// override static func staticTypeMethod(){
//
// }
override class func classTypeMethod(){
print("Bclass classTypeMethod")
}
}
AClass.staticTypeMethod()
AClass.classTypeMethod()
BClass.classTypeMethod()
- 인스턴스 메서드와 달리 self 프로퍼티가 타입 그 자체를 가리킨다.
- 인스턴스 메서드 self → 인스턴스
- 타입 메서드 self → 타입
struct SystemVolume{ static var volume : Int = 5 static func mute(){ self.volume = 0 } } //클래스 인스턴스 class Navigation { var volume : Int = 5 func guideWay(){ SystemVolume.mute() } func finishGuideWay(){ SystemVolume.volume = self.volume } } SystemVolume.volume = 10 let myNavi : Navigation = Navigation() myNavi.guideWay() print(SystemVolume.volume) myNavi.finishGuideWay() print(SystemVolume.volume)
* 야곰님의 스위프트 프로그래밍 3판 책으로 공부하며 정리해 본 글입니다.
'Swift 프로그래밍' 카테고리의 다른 글
[Swift Programming] 인스턴스 생성 및 소멸 (0) | 2022.07.26 |
---|---|
[Swift Programming]구조체와 클래스 (0) | 2022.07.08 |
completion handler VS async/await (0) | 2022.07.07 |
[Swift Programming] 옵셔널 (0) | 2022.07.07 |
@gani+ :: Gani_Dev :)
꾸준히 기록할 수 있는 사람이 되자 !