본문 바로가기

Swift_Grammar

[Swift_Grammar] 구조체와 클래스

 

 

 

구조체와 클래스는
프로퍼티와 메서드를 사용하여 
하나의 새로운 사용자 정의 데이터 타입을 만들어 줄수 있다.

구조체를 먼저 보자면
struct 키워드를 사용하고
새로운 타입을 생성해주는것과 같으므로
대문자 카멜케이스로 이름을 지어준다.

struct Person {
    let name: String
    var age: Int
}

 

구조체를 정의하고 초기화 할때 

아래와 같이 타입과 프로퍼티 이름을 그대로 받는

기본적으로 생성되는 init이 있다. ( 멤버 와이즈 이니셜라이저 )

 

 

 

또한 점문법을 사용하여 프로퍼티에 접근할 수 있다.

하지만 구조체를 let 으로 생성한 후

프로퍼티에 값을 변경하려고 하면

상수이기 때문에 컴파일 에러가 난다.

let kim = Person(name: "kim", age: 2)

print(kim.name) // "kim"
print(kim.age) // 2

kim.name = "park" // 컴파일 에러

 

 

 

그렇다면 var로 생생해보겠다.

다시 프로퍼티에 접근해서 

값을 변경해보면

var로 선언이 되었던 age의 변경은 가능하지만

let으로 선언이 되었던 name의 변경에서 

컴파일 에러가 발생한다.

구조체 내에서 name을 정의 할때 let으로 

선언했기 때문이다.

 var kim = Person(name: "kim", age: 2)
 
kim.age = 3

kim.name = "park" // 컴파일 에러

 

 

 

여기서 사람의 이름 처럼 바뀌지 않는 속성은 let 으로 ( 물론 이름도 바꾸는 사람이 있지만.. )

사람의 나이처럼 매년 1씩 증가하는 속성은 var 로 선언 하는게 팁이다.

 

 

 

그다음 클래스에 대해 알아 보겠다.

 

class 키워드를 사용하고
구조체와 마찬가지로 새로운 타입을 생성해주는것과 같으므로
대문자 카멜케이스로 이름을 지어준다.

class Earphone {
    var currentVolume: Int = 0
}

 

클래스는 구조체와 달리

상속이라는걸 받을 수 있다.

상속받을때는 클래스 이름 뒤에 

:을 써주고 부모클래스의 이름을 써준다.

아래와 같이 상속을 하게 되면 

OpenTypeEarphone이라는 서브클래스와

KernelTypeEarphone이라는 서브클래스는 

Earphone 클래스를 상속받았기 때문에 

Earphone 클래스의 프로퍼티인  currentVolume을 

물려 받게 된다.

또한 서브클래스는 hasNoiseCanceling과 같이

새로운 속성을 추가 할 수 있다.

class OpenTypeEarphone: Earphone {
    ...
}

class KernelTypeEarphone: Earphone {
    var hasNoiseCanceling = true
}

 

 

클래스를 정의하고 초기화 할때

위 Earphone 클래스 같은 경우

currentVolume 프로퍼티에 0 이라는 기본값을 줬으니

따로 init에 받을 초깃값은 필요가 없다.

(기본값을 설정해주지 않아도 정의가 가능했던 구조체의 멤버 와이즈 이니셜라이저와 차이점 - 물론 클래스도 커스텀 init이 가능하여 init을 수정할 수 있다.)

let earphone = Earphone()

 

 

여기서 클래스는 참조 타입이라서

earphone 이라는 객체를 let으로 선언을 해줘도

earphone의 currentVolume 값을 변경 해줄 수 있다.

 

이게 무슨말이냐면 

 

구조체 같은경우 값타입 이므로 

값을 그대로 복사해와서

그 복사해온 값을 변경하는데 

 

클래스 같은 경우 참조 타입라서

복사가 아닌

주소값을 참조해서 해당 주소에 값을 변경하는 프로세스라서

가능한 것이다.

earphone.currentVolume = 10

 

이렇게 생긴것은 비슷해도
각자의 인스턴스가 띄우고 있는 성격(값타입, 참조타입)을 가지고
용도에 따라서 적절히 사용해야한다.

어떻게 적절한 선택을 하냐가 관건인데
애플 가이드라인에서는 다음 조건중 하나 이상에 해당한다면
구조체를 사용하는것을 권장한다고 한다.

- 연관된 간단한 값의 집합을 캡슐화 하는것만이 목적일때
- 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
- 구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
- 다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을때

 

 

'Swift_Grammar' 카테고리의 다른 글

[Swift_Grammar] Method  (0) 2021.01.06
[Swift_Grammar] Property  (0) 2020.12.31
[Swift_Grammar] Optional  (0) 2020.12.28
[Swift_Grammar] 함수  (0) 2020.12.27
[Swift_Grammar] 흐름 제어 (2)  (0) 2020.12.25