Class vs Struct
Updated:
🔷 Struct
-
Struct 은 값을 복사해서 사용하기 때문에 프로젝트에서 model 에 주로 사용됩니다.
-
model 에서 사용된 struct 객체는 view 단계에서 참조해서 사용할 때, 이것이 복사되어서 자동으로 초기화 되서 각 개별적으로 사용하게 됩니다
// 데이터 model 을 담아 올을때 class 와 struct 2종류를 사용하게 됩니다
// struct: memberWise initializer 때문에 좋다
// 생성자를 만들지 않아도 좋습니다. 자동으로 생성자 생성
struct YoutuberStruct {
var name: String
var subscriberCount: Int
// class 와 다르게 initializer 가 필요없음 (자동생성, object 사용시, 자동으로 메모리에 등록됨 )
}
var devJacob = YoutuberStruct(name: "Jacob", subscriberCount: 9999)
var devJacobCopy = devJacob
// 값을 볻사해서 다른 메모리를 참조하기 때문에 변수 값이 다르게 됨
// struct 은 원래 값에 영향을 미치지 않음
print("devJacobCopy.name: \(devJacobCopy.name)") // Jacob
devJacobCopy.name = "Emma"
print("devJacobClone.name: \(devJacobCopy.name)") // Emma
🔶 struct mutating
// 맴버 변수 name 를 가지는 struct
// struct 는 참조인 class 와 다르기 때문에
// struct 구조의 맴버 변수 값을 변경하려면
// mutating 키워드가 필요
// struct 는 값이고 class 는 주소를 참조하는 형태라서 struct 에서 값을 변경 할때는
// 앞에 mutating 을 붙여 줘야 하는 것임
struct Friend {
var name : String
// mutating 키워드로 맴머 변수의
// 값을 변경하는 메소드
mutating func changeName(newName: String) {
self.name = "hello! " + newName
}
}
// 위의 것을 class 로 표현하면
class Friend2 {
var name : String
func changeName2(newName: String) {
self.name = "hello! " + newName
}
init(_ name: String) {
self.name = name
}
}
var myFriend2 = Friend2("Jacob")
myFriend2.changeName2(newName: "Emma") // 이름을 바꾸기
myFriend2.name
🔶 struct method
- struct 에서도 class 와 마찬가지로 메소드를 가질 수 있고 () 맴버 변수들 활용이 가능합니다 (struct 안에서 함수 사용이 가능하다는 것임)
struct Friend {
var age: Int
var name: String
func sayHello() -> String {
print("sayHello()")
return "저는 \(age) 살 입니다"
}
}
var myFriend = Friend(age: 40, name: "Jacob")
myFriend.sayHello() // "저는 40 살 입니다"
🔶 struct 기본 생성자
// struct 는 클래스와 당리 생성자 메소드가 자동 탑제되어 있습니다
struct Developer {
var name : String
}
let developer = Developer(name: "Jacob")
print(developer) // Developer(name: "Jacob")
// 생성자를 안에서 따르 지정 가능하지만
struct Friend {
var name: String
init () {
name = "Emma"
}
}
let myFriend = Friend()
print(myFriend) // Friend(name: "Emma")
// 아래와 같이 extension 으로 빼서 기본 생성자 지정이 가능합니다
struct Pet {
var name: String
}
extension Pet {
init () {
name = "냥냥이"
}
}
let myPet = Pet()
print(myPet) // Pet(name: "냥냥이")
let myDog = Pet(name: "멍멍이")
print(myDog) // Pet(name: "멍멍이")
🔷 class
-
class 는 struct 와 같이 데이터들의 모음 이지만, 가장큰 차이점은 복사해서 사용하더라도 같은 메모리를 참조합니다
-
즉, 복사한 객체의 값이 변경되면 같은 메모리에 속한 원본 데이터의 값도 같이 변경되게 됩니다
// class : 직접 생성자를 만들어 줘야한다(메모리에 올려줘야 한다)
class YoutuberClass {
var name: String
var subscriberCount: Int
// initializer 생성 - 메모리 올리기
// init 으로 만든 매개변수를 가진 생성자 메소드를 만들어야 매개변수를 넣어서 그 값을 가진 객체(object)를 만들 수 있다
init(name: String, subscriberCount: Int) {
self.name = name
self.subscriberCount = subscriberCount
}
}
var devMike = YoutuberClass(name: "Mike", subscriberCount: 1000)
var devMikeClone = devMike
print("값 넣기 전 devMike.name: \(devMike.name)") // Mike
print("값 넣기 전 devMikeClone.name: \(devMikeClone.name)") // Mike
devMikeClone.name = "Smith" // 이름 값 변경
print("값 넣기 전 devMike.name: \(devMike.name)") // Smith
print("값 넣기 후 devMikeClone.name: \(devMikeClone.name)") // Smith
// Clone 값이 변하면 원본데이터도 같이 변하게 됨
🔶 class func (클래스 메소드)
// 친구 클래스
class Friend {
// 일반적인 메소드
func sayHi() {
print("안녕")
}
// 클래스 메소드로 해당 인스턴스가 생성되지 않아도 호출 가능
class func sayBye() {
print("바이바이~!")
}
}
// 일반적인 형태는 인스턴스 생성해야 해당 메소드 호출이 가능합니다
let myFried = Friend()
myFried.sayHi() // 안녕
// 인스턴스 생성을 하지 않아도
// 클래스에 바로 접근해서 메소드 호출이 가능합니다
Friend.sayBye() // 바이바이~!
🔶 Static, Final Class Method
class MyClass {
// 클래스 메소드 인스턴스를 생성하지 않고 메소드 호출이 가능한데
// final class 메소드와 static class 메소드도 동일합니다
class func sayHi() -> String {
return "안녕?!"
}
static func sayHello() -> String {
return "안녕하세요?!"
}
final class func sayHelloFinal() -> String {
return "호호 안녕하새요?!"
}
}
print(MyClass.sayHi()) // 안녕
print(MyClass.sayHello()) // 안녕하세요?!
print(MyClass.sayHelloFinal()) // 호호 안녕하세요?!
// 클래스 메소드는 오버라이딩이 가능하지만
class HahaClass: MyClass {
override class func sayHi() -> String {
return "sayHi() HahaClass 에서"
}
}
print(HahaClass.sayHi()) // sayHi() HahaClass 에서
// static 과 final method 들의 부모 클래스 메소드를 오버라이딩 할 수 없음
override static func sayHello() -> String {
return "sayHello() HahaClass 에서"
} // override' can only be specified on class members
override class func sayHelloFinal() -> String {
return "sayHelloFinal() HahaClass 에서"
} // override' can only be specified on class members
Reference
The SwiftLanguage Guide: 클래스과 구조체 (Classes and Structures)- https://jusung.gitbook.io/the-swift-language-guide/language-guide/09-classes-and-structures
개발하는 정대리 스위프트 기초 문법 - 6일차 / 클래스 vs 스트럭트 - https://www.youtube.com/watch?v=60VSuIY81iQ
Leave a comment