구조체와 클래스는 OOP(Object-Oriented Programming)를 위한 필수 요소로 프로그램의 코드를 추상화하기 위해 사용합니다.
POP(Procedural Oriented Programming)는 절차 중심 프로그래밍으로. 이 패러다임은 계산을 수행하는 데 필요한 절차 나 기능에 중점을 둡니다. 그것은 데이터보다는 프로세스에 초점을 맞추고 있습니다.
구조체와 클래스는 프로그램 코드의 구성 요소를 유연한 구조로 묶어 표현하고자 할때 사용합니다. 상수(constants), 변수(variables) 및 함수(functions)를 정의하는 데 사용하는 것과 동일한 구문을 사용하여 구조체와 클래스에 기능을 추가하는 프로퍼티와 메서드를 정의합니다.
다른 프로그래밍 언어와 달리 Swift는 사용자 정의 구조체 및 클래스에 대해 별도의 인터페이스 및 구현 파일을 만들 필요가 없습니다. Swift에서 구조체 또는 클래스를 단일 파일로 정의하면 해당 클래스 또는 구조체에 대한 외부 인터페이스를 자동으로 다른 코드에서 사용할 수 있습니다.
NOTE
클래스의 인스턴스는 전통적으로 객체(object)로 알려져 있습니다. 그러나 Swift에서 구조체와 클래스는 다른 언어보다 기능면에서 훨씬 더 가깝습니다. 이 글의 대부분은 클래스 또는 구조체 타입의 인스턴스에 적용되는 기능을 설명합니다. 이 때문에 좀 더 일반적인 용어인 인스턴스(instance)가 사용됩니다.
구조체와 클래스의 비교 (Comparing Structures and Classes)
구조체와 클래스는 공통점이 많습니다. 둘다 다음을 수행할 수 있습니다.
- 프로퍼티를 정의 할 수있다.
- 메소드를 정의 할 수 있다.
- 점(.) 구문을 사용하여 값에 대한 접근을 제공 한다.
- 이니셜 라이저 정의가 가능하다.
- 기능을 확장할 수 있도록하는 extention 정의가 가능하다
- 프로토콜을 준수할 수 있다.
클래스에는 구조체에는 없는 추가 기능이 있습니다.
- 상속을 통해 한 클래스가 다른 클래스의 특성을 상속 할 수 있다.
- 런타임에 타입 캐스팅을 통해 클래스 인스턴스의 타입을 확인하고 해석가능하다. (구조체에서는 클래스 타입케스팅이 불가능하다)
- Deinitializer가 존재 한다.
- 레퍼런스*참조 카운팅이 된다.
● Any
Any는 함수타입을 포함하여 모든 타입의 인스턴스를 나타낼 수 있습니다.
● AnyObject
AnyObject는 모든 클래스 타입의 인스턴스를 나타낼 수 있습니다.
클래스가 지원하는 추가 기능에는 복잡성이 증가합니다. 구조체는 일반적인 지침으로 추론하기 쉽기 때문에 더 선호하고 클래스는 적절히 필요할 때에 사용합니다. 실제로 이것은 대부분의 개발자가 구현하는 데이터 타입이 구조체 및 열거형이라는 것을 의미합니다.
자세한 비교는 [구조체와 클래스 중 선택]을 참조하십시오.
구문정의 (Definition Syntax)
구조체와 클래스는 비슷한 정의 구문을 가지고 있습니다. struct 키워드로 구조체를 구현하고 class 키워드로 클래스를 구합니다. 둘 다 전체 정의를 한 쌍의 중괄호 안에 넣습니다.
struct SomeStructure {
// 구조체 정의는 여기
}
class SomeClass {
// 클래스 정의는 여기
}
새로운 구조체나 클래스를 정의 할 때 UpperCamelCase (예 : SomeStructure 및 SomeClass)로 지정합니다.
프로퍼티 및 메서드는 lowerCamelCase (예 : frameRate 및 incrementCount)로 지정하여 타입이름을 구분합니다.
다음은 구조체 정의 및 클래스 정의의 예입니다.
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name: String?
}
위의 예는 픽셀 기반 디스플레이 해상도를 설명하기 위해 Resolution이라는 새로운 구조체를 정의합니다. 이 구조체에는 너비와 높이라는 두 개의 저장 프로퍼티가 있습니다. 프로퍼티는 구조체 또는 클래스의 일부로 묶여 저장되는 상수 또는 변수입니다. 이 두 프로퍼티는 초기값을 정수 값 0으로 설정하여 Int 타입으로 추론됩니다.
위의 예제는 비디오 표시를 위한 특정 비디오 모드를 설명하기 위해 VideoMode라는 새 클래스도 정의합니다. 이 클래스에는 4 개의 저장 프로퍼티 변수가 있습니다. 첫 번째 resolution는 Resolution의 프로퍼티 타입을 유추하는 Resolution 구조체 인스턴스로 초기화됩니다. VideoMode 인스턴스의 다른 세 가지 프로퍼티의 경우 인터레이스 설정 false , 재생 프레임 속도 0.0 및 이름이라는 옵셔널 문자열 값으로 초기화됩니다. name 프로퍼티는 옵셔널 타입으로 기본값 nil 또는 “이름 값 없음”이 됩니다.
구조체 및 클래스 인스턴스 (Structure and Class Instances)
Resolution은 구조체 정의로 VideoMode는 클래스 정의로는, Resolution 또는 VideoMode의 모양 만 묘사하는 것입니다.
실제 사용 하려면 구조체 또는 클래스의 인스턴스를 만들어야합니다.
let someResolution = Resolution()
let someVideoMode = VideoMode()
구조체와 클래스는 모두 새 인스턴스에 대해 초기화 구문을 사용합니다. 가장 간단한 형식의 이니셜 라이저 구문은 Resolution() 또는 VideoMode()와 같은 빈 괄호 뒤에 클래스 또는 구조체의 이름을 사용합니다. 이렇게하면 모든 프로퍼티가 기본값으로 초기화 된 클래스 또는 구조체의 새 인스턴스가 생성됩니다. 클래스 및 구조체 초기화는 [초기화]에 자세히 설명되어 있습니다.
프로퍼티 접근 (Accessing Properties)
점 구문을 사용하여 인스턴스의 속성을 액세스 할 수 있습니다. 점 구문에서는 공백없이 마침표 (.)로 구분하여 인스턴스 이름 바로 뒤에 프로퍼티 이름을 작성합니다.
print("The width of someResolution is \(someResolution.width)")
// Prints "The width of someResolution is 0"
이 예제에서 someResolution.width는 someResolution의 width 프로퍼티를 참조하고 기본값 인 0을 반환합니다.
VideoMode의 해상도 프로퍼티에있는 너비 속성과 같은 하위 프로퍼티로 드릴 다운*(더 많은 정보를 찾기 위해 깊이 들어가는 행위) 할 수 있습니다.
print("The width of someVideoMode is \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is 0"
점 구문을 사용하여 변수 프로퍼티에 새 값을 할당 할 수도 있습니다.
someVideoMode.resolution.width = 1280
print("The width of someVideoMode is now \(someVideoMode.resolution.width)")
// Prints "The width of someVideoMode is now 1280"
구조체의 멤버 별 초기화 (Memberwise Initializers for Structure Types)
모든 구조체에는 새 구조체 인스턴스의 멤버 프로퍼티를 초기화하는 데 사용할 수있는 자동 생성 된 멤버 별 이니셜 라이저가 있습니다. 새 인스턴스의 프로퍼티에 대한 초기 값은 이름으로 멤버 단위 이니셜 라이저에 전달할 수 있습니다.
let vga = Resolution(width: 640, height: 480)
구조체와 달리 클래스 인스턴스는 기본 멤버 별 이니셜 라이저를 받지 않습니다. 이니셜 라이저는 [초기화]에 자세히 설명되어 있습니다.