오브젝트 타입(class, struct, enum)의 가장 중요한 특징은 인스턴스화 될 수 있다는 것이다. 오브젝트 타입을 선언하면 단지 타입을 정의하는 것일 뿐이다. 타입을 인스턴스화 하기 위해서는 타입의 인스턴스를 만들어야 한다.
스위프트에서는 오브젝트 타입의 이름 옆에 괄호를 붙여서 인스턴스를 생성한다. 이는 오브젝트 타입에게 자기 자신을 인스턴스화 하라는 특별한 메시지를 보내는 것과 같다.
// Dog 클래스의 인스턴스 생성
let fido = Dog()
위 코드에는 두 가지 일이 수행된다.
Dog
의 인스턴스를 생성한다.Dog
인스턴스를 fido
라는 변수 안에 넣는다.이제 fido
는 Dog
인스턴스이다. 또한 let
을 사용했기 때문에 fido
는 항상 같은 Dog
인스턴스일 것이다. 만약 var
키워드를 사용했다면 이후에 다른 Dog
인스턴스가 될 수 있다.
인스턴스가 생성된 후에는 인스턴스 메시지를 보낼 수 있다. 이 인스턴스 메시지는 오브젝트의 프로퍼티와 메소드를 의미한다.
fido.bark()
기본적으로 프로퍼티와 메소드는 인스턴스 프로퍼티와 메소드이다. 메시지를 보내기 위해서는 반드시 인스턴스가 있어야 한다.
Dog.bark() // compile error
위와 같이 메소드를 호출하기 위해서는 class
함수나 static
함수를 선언해야 한다.
프로퍼티 역시 class
프로퍼티나 static
프로퍼티를 선언해야 한다.
오브젝트 타입에게도 메시지를 보낼 수 있음에도 불구하고 인스턴스를 사용하는 이유는 객체 지향 프로그래밍의 강점을 생각해보면 금방 이해할 수 있다. 같은 오브젝트 타입을 가진 여러 인스턴스가 다르게 행동할 수 있기 때문이다.
인스턴스는 코드이자 데이터이다. 오브젝트 타입에서 정의된 코드들이 그 타입을 가지는 다른 인스턴스들에 공유될 뿐만 아니라 인스턴스 하나에 특정 데이터가 속하게 된다. 인스턴스는 상태(state)를 갖는다. 인스턴스는 상태를 유지하는 기기와 같다. 즉, 데이터를 저장하는 상자 역할을 한다.
인스턴스는 오브젝트고 오브젝트는 메시지의 수신자이다. 그러므로 인스턴스가 자기 자신에게 메시지를 보내는 방법이 있어야 한다. 이를 위해 self
키워드가 필요하다.
self
는 인스턴스 메소드에서만 사용된다. 인스턴스의 코드에 self
가 포함되면 이는 이 인스턴스를 참조한다는 의미이다.
self
키워드는 생략이 가능하지만 저자는 가독성을 위해 생략하지 않는 것을 추천한다고 한다.
클래스를 선언하면 네임스페이스가 정의된다. 다른 오브젝트가 네임스페이스 안에 있는 것을 참조하려면 dot-notation을 사용해야 한다. 하지만 여전히 다른 오브젝트들은 네임스페이스 안에 있는 것들을 참조할 수 있다. 이를 막으려면 private
키워드를 사용한다.
객체 지향 프로그래밍의 핵심은 인스턴스에게 충분한 수명을 주고 그들을 다른 오브젝트들에게 보이게 한다는 것이다. 실제 앱 개발을 할 때는 프레임워크가 앱의 생애 동안 지속되는 인스턴스들(기본적인 인터페이스들)을 제공해준다.
프레임워크가 우리에게 알려주지 않는 것은 비즈니스 로직을 설계하는 방법이다. 이는 가장 자유로운 부분이면서 가장 어려운 부분이다.