[swift] 구조체와 클래스

이은수, Lee EunSoo·2024년 9월 10일
0

Swift Basic

목록 보기
9/24
post-thumbnail
post-custom-banner

개요

swift는 다른 언어들 처럼 프로퍼티와 메서드를 갖는 구조체와 클래스를 갖는다, 객체지향 언어이기 때문

다른 객체지향 언어들의 경우(java, C++, C#, Python 등) 클래스를 많이 사용한다

하지만 swift의 경우 iOS에서 사용하는 경우 구조체 사용을 많이한다, 실제로 swiftUI에서 View는 구조체로 되어있다.

이번 페이지에서는 이 클래스와 구조체에 대해서 알아보고자 한다.

값타입과 참조타입에 대해..

구조체와 클래스에 대해 알아보기 전에 인스턴스와 값타입/참조타입에 대해 어느정도 알아야 한다.

구조체와 클래스는 형태를 정의하고 인스턴스를 생성한다.
이 구조를 붕어빵을 예를 들어 설명을 많이 하는데 다음과 같다.

붕어빵의 경우 붕어빵틀 반죽과 팥을 넣고 결과물인 붕어빵을 만든다.

붕어빵틀이 클래스/구조체 라고 할 수 있다.
그리고 붕어빵이 인스턴스이다.

인스턴스를 하나 만들게 되면 붕어빵이 하나 생겨나는데 여기서 이 붕어빵을 사용하는 방법에서 값타입과 참조타입의 차이점이 나타나는데

값타입과 참조타입의 차이점

참조타입의 경우 하나의 붕어빵을 만들면 여러곳에서 접근해서 사용이 가능하다.

예시 코드를 보며 살펴보자

class Bread(){
	var taste: String = "RedBean"
}

var fishBread1 = Bread()
var fishBread2 = fishBread1

이 경우 fishBread1이라는 인스턴스가 생겨나고 fishBread2에 fishBread1을 복사하면 fishBread1 과 fishBread2는 서로 동일한 붕어빵을 바라본다.

fishBread1.taste = "cream"
print(fishBread1.taste)
print(fishBread2.taste)

//결과: cream
//결과: cream

하나의 인스턴스를 여러곳에서 같이 사용하는것이다.


값타입의 경우 생성된 인스턴스는 유일하다. 공유되지 않는다.

struct Bread(){
	var taste: String
    var size: String
}

var fishBread1 = Bread()
var fishBread2 = fishBread1 //fishBread1과 동일한 내부 데이터를 갖는 인스턴스

이 경우 fishBread1과 fishBread2는 서로 다른 붕어빵(인스턴스)이다.

클래스 였다면 지금까지 1개의 붕어빵(인스턴스)였겠지만
지금은 2개의 붕어빵(인스턴스)이 메모리에 올라가 있다.

이전처럼 해보면

fishBread1.taste = "cream"
print(fishBread1.taste)
print(fishBread2.taste)

//결과: cream
//결과: RedBean

서로 장단점이 있다.

참조타입의 경우 메모리 공간을 적게 사용하는 장점이 있지만 여러곳에서 사용이 가능한 만큼 코드가 복잡해질 경우 내부 프로퍼티가 보장이 안된다.

값타입의 경우 인스턴스가 생성/복사할 때마다 생겨나기에 메모리 관리 측면에서는 불리 할 수 있으나 내부 데이터는 생성했던 인스턴스만 접근이 가능하기에 코드 관리에 용이 하다는 장점이 있다.

정의

struct SomeStructure {
    
}

class SomeClass {
    
}

코드의 형태는 다음과 같다.

swift에서 클래스와 구조체는 타입이 된다. SomeStructure, SomeClass타입이 만들어 졌다고 볼 수 있다.

예시

struct PrivateInfo {
    var address = "부산시"
    var phoneNumber = "010-1234-5678"
    var identificationNumber = "012345-678910"
}

class Human {
    var name = "Gil Dong"
    var age = "32"
    var privateInfo = PrivateInfo()
}

개인정보를 저장하는 구조체와 사람을 정의하는 클래스를 만들었다.

각각 struct와 class 키워드를 사용하여 만든다

인스턴스 생성

구조체와 클래스의 인스턴스 생성 방법을 살펴보자

//별도의 생성자가 없다면 ()빈 괄호만 사용해도 된다
let gildong = Human()

다음과 같이 인스턴스를 생성하면 되고, 위 코드는 타입이 생략되어 있는 코드이다.
(원래 형태는 var gildong:Human = Human())

왠만하면 변수나 상수를 생성할때 타입은 명시하는것을 추천한다.
코드 가독성에 도움이 되는것도 있고, 타입을 명시하지 않으면 컴파일러가 타입을 추론하는데 타입추론하는 코드가 많아지면 컴파일 시간 초과 오류가 발생하는 경우가 생긴다.

프로퍼티의 접근

프로퍼티란 구조체/클래스 내부의 변수/상수를 말한다.

이들에 접근방법은 다음과 같다.

print("my name is \(gildong.name)")
print("my home address is \(gildong.privateInfo.address)")
//result: my name is 


gildong.privateInfo.address = "Seoul"
print("my home address is \(gildong.privateInfo.address)")

이런식으로 인스턴스이름.프로퍼티이름 의 형태로 사용한다.

인스턴스의 프로퍼티에서 데이터를 가져오는것, 수정하는것 둘다 가능하다.
(이를 get/set이라고 하는데 추후 따로 다룬다.)

인스턴스 초기화

struct PrivateInfo {
    var address
    var phoneNumber
    let identificationNumber = "012345-678910"
}

class Human {
    var name
    var age
    var privateInfo = PrivateInfo()
}

클래스와 구조체의 경우 이전처럼 프로퍼티에 미리 값이 있을 수도 없을수도 있다.
그런경우 우리가 사용하기 위해선 생성자라는 것을 사용해 주어야 한다.

struct PrivateInfo {
    var address
    var phoneNumber
    let identificationNumber = "012345-678910"
}

class Human {
    var name
    var age
    var privateInfo = PrivateInfo()
}

클래스는 init()이라는 키워드를 직접 사용해서 동작을 처리하는 코드를 넣어야 하고 구조체의 경우 생성자를 만들지 않아도 프로퍼티에 값을 넣어주는 생성자를 자동으로 만들어 준다.

var gildong:Human = Human(name: "길동", age: 32) //오류: 클래스는 생성자가 반드시 필요함

var privateGildong:PrivateInfo = PrivateInfo(address: "부산시", phoneNumber: "010-1234-5678", identificationNumber: "00000-123456")

gildong 인스턴스는 생성되지 못하고 컴파일 단계에서 오류가 발생한다. 클래스 내부에 생성자가 없기 때문이다

반면에 구조체인 privateGildong의 경우 프로퍼티의 이름에 맞는 생성자를 자동으로 생성해서 생성자 없이도 인스턴스의 초기화가 가능하다.

//수정된 클래스 Human

class Human {
    var name
    var age
    var privateInfo = PrivateInfo()
    
    
    init(){
    	self.name = "gindong"
        self.age = 35
    }
    
    init(name: String, age: Int){
    	self.name = name
        self.age = age
    }
}

init() 생성자는 함수이다 init()의 경우 생성자라고 예약되어 있기 떄문에 func를 생략 할 수 있다.(물론 생성자는 반환도 하지 않는다.)

생성자는 여러개 일 수 있다, 함수처럼 이름이 동일하다 하더라도 매개변수만 다르다면 중복으로 생성이 가능하다,

(하지만 생성자는 인스턴스 생성하는 그 순간에만 1회 사용할 수 있으므르 여러개 있다고 해서 여러번 사용이 가능한 것은 아니다.)

profile
iOS 개발자 취준생, 천 리 길도 한 걸음부터
post-custom-banner

0개의 댓글