class
와 struct
는 언뜻 보면 비슷해 보일 수 있다.
class Vehicle {
var wheel = 4
func move() {
print("move forward")
}
}
struct Vehicle {
var wheel = 4
func move() {
print("move forward")
}
}
다음 예시를 보면 class
와 struct
라는 이름만 달라졌지 그 이외에 달라진 것은 없어보인다.
let vehicle1 = Vehicle()
또한 사용을 할 때도 위와 같이 같은 꼴이다 보니 두 가지를 굳이 왜 구분해놓았지?라고 생각할 수 있다.
왜냐? 내가 처음에 그랬으니까~
하지만 두개는 엄연히 다른 것이다.! 하나하나 어디가 다른지 같이 짚어보자.
1. 상속
class
와 struct
는 상속 가능 여부에 차이가 있다.
결론적으로 말하면 struct
는 상속이 불가능하다!
class
는 아래와 같은 방식으로 상속을 할 수 있다.
class Car: Vehicle{
}
상속을 하게 되면 부모클래스인 Vehicle
내의 프로퍼티나 함수들을 자녀클래스인 Car
에서 사용할 수 있다.
let car = Car()
car.move()
// 출력 : move forward
2. 초기화 (생성자)
class
는 내부의 프로퍼티가 초기화되지 않은 상태라면 꼭 생성자를 써주어야한다.
struct
는 생성자가 필요하지 않기 때문에 아래코드처럼 프로퍼티가 초기화되지 않은 상태로 존재해도 따로 오류가 나지 않는다.
struct Vehicle {
var wheel: Int
func move() {
print("move forward")
}
}
하지만 class
에서는 init
이라는 생성자를 써 주지 않으면 오류가 난다.
class Vehicle {
var wheel: Int
init(wheel: Int){
self.wheel = wheel
}
func move() {
print("move forward")
}
}
하지만 또 두 개가 비슷해 보이는 것은 사용방법 때문인데, class
와 struct
둘 다 아래와 같이 사용해야한다.
let vehicle1 = Vehicle(wheel: 4)
struct
는 생성자는 만들 필요가 없지만, 값이 없는 프로퍼티가 있어서는 안된다. 결국 같은 방식으로 사용해한다.
3. 참조
class
코드에 새로운 함수를 추가해보자.
class Vehicle {
var wheel: Int
init(wheel: Int) {
self.wheel = wheel
}
func move() {
print("move forward")
}
func changeWheelNumber(amount: Int) {
wheel = wheel - amount
}
}
let vehicle1 = Vehicle(wheel: 10)
let vehicle2 = vehicle1
바퀴 수를 10
이라고 두고, vehicle2
라는 객체를 vehicle1
과 같다고 만들어주었다.
이 상태로 changeWheelNumber
이라는 함수를 사용하면 vehicle2
의 wheel
수는 어떻게 될까?
vehicle1.changeWheelNumber(amount: 3)
print(vehicle1.wheel)
print(vehicle2.wheel)
// 출력 : 7
// 출력 : 7
우리는 vehicle2
의 wheel
을 변경한 것이 아닌데도 불구하고 vehicle2
의 wheel
값이 변했다는 것을 알 수 있다.
이것은 vehicle2
가 vehicle1
을 "참조"하고 있기 때문이고 let vehicle2 = vehicle1
만으로는 새로운 객체를 생성한 것이 아닌 것을 알 수 있다.
vehicle2
를 새로운 객체로 만들어주기 위해서는 let vehicle2 = Vehicle(wheel: 10)
으로 생성자부터 써주어야한다.
이것을 struct
로 써보자.
struct Vehicle {
var wheel: Int
func move() {
print("move forward")
}
mutating func changeWheelNumber(amount: Int) {
wheel = wheel - amount
}
}
struct
에서는 내부 프로퍼티의 값을 수정해야할 때, mutating
키워드를 꼭 써주어야한다.
구조체는 값 타입인데 이것은 프로퍼티를 메서드 내에서 수정할 수 없다.
따라서mutating
을 붙여줘서 구조체 전체를 새로 초기화시킴으로써 수정한다.
var vehicle1 = Vehicle(wheel: 10)
var vehicle2 = vehicle1
vehicle1.changeWheelNumber(amount: 3)
print(vehicle1.wheel)
print(vehicle2.wheel)
// 출력 : 7
// 출력 : 10
같은 코드를 써주었을 때, vehicle1
을 상수로 설정해줄 수가 없는데,
mutating
때문에 struct
전체가 변화하는 것이기 때문에 var
로 써야한다.
출력을 보게 되면 vehicle2
의 값은 변하지 않은 것을 알 수 있다. 이것을 통해서 구조체는 참조가 아닌 "복사"를 해서 새로운 객체를 만들어 준다는 것을 알 수 있다.
'iOS > Swift' 카테고리의 다른 글
[Swift] while문의 구문이름표를 알아보자 (0) | 2023.08.04 |
---|---|
[Swift] String 관련 메서드 정리 (2) | 2023.08.03 |
[Swift] 튜플 (Tuple) 알아보기 (0) | 2023.08.02 |
[Swift] Map 알아보기 (1) | 2023.08.01 |