티스토리 뷰

Programming/Swift

Swift Beginner | 인터페이스

글그리 2020. 11. 18. 21:26

swift의 함수형 언어 특성인 closure를 공부했으니 이번에는 객체지향적 특성에 대해 공부해보자. swift는 객체지향 코딩을 위해서 여러가지 인터페이스를 제공한다.

사실 인터페이스라는 단어와 가장 어울리는 개념은 protocol이다.하지만 프로그래머로 하여금 코드의 각 조각들을 서로 연결시켜주는 역할을 한다는 뜻으로 사용했다.
  • protocol : 가장 추상적인 인터페이스로 선언만 허용되는 인터페이스다. 실제 사용하기 위해서는 상속을 받아서 구체화시켜서 사용한다.
  • class : 아마 가장 많이 사용할 인터페이스일 것이다. 함수(=method)와 변수(=property)를 모두 가질 수 있고, 인스턴스를 생성해서 프로그램 여기저기에서 사용된다.
  • struct : 데이터를 구조화시킬 때 많이 사용한다. class와 거의 비슷한 기능을 가지고 있다.
  • enum : 반복되는 값의 모음을 묶어서 하나의 자료형으로 만들어준다. swift는 이것에 더해서 더 강력한 기능을 제공한다.

이 포스팅에서는 이 인터페이스들의 공통점과 상대적으로 다른점에 대해 알아보고 각 인터페이스의 고유 특징 및 기법은 각 포스팅에 나눠서 정리한다.

 

 

 

기본 문법

작성하는 문법은 매우 비슷하다 앞에 붙이는 키워드만 차이가 있어서 class를 붙이면 클래스가 되고, struct를 붙이면 구조체가 된다.

protocol foo { 
	// ...
}

class foo {
	// ...
}

struct foo {
	// ...
}

 

 

 

value type reference type

프로토콜은 추상 인터페이스라서 인스턴스를 생성할 수 없다. 나머지 셋을 보자.

이 셋은 비슷해 보이지만 메모리 면에서 차이가 있다. struct와 enum은 value type, class는 reference type이다. 그래서 생성된 각 인스턴스들이 다른 인스턴스로 전달될 때 structure는 값의 복사가 발생하고, class는 포인터가 넘어가게 된다.어떤 차이가 있는지 코드를 통해 바로 알아보자.

class PersonClass {
	var index = 0
}

struct PersonStruct {
	var index = 0
}

var pc = PersonClass()
var ps = PersonStruct()

var alsoPc = pc
var alsoPs = ps

alsoPc.index = 5
alsoPs.index = 5

print(pc.index)		// > 5
print(ps.index)		// > 0

위 코드를 보면 구조체로 만든 ps의 경우 alsoPs로 전달되면서 값의 복사가 일어나서 alsoPs에서 내용을 바꿔도 원본에 영향이 없지만, pc의 경우 alsoPc로 전달될 때 포인터가 전달되기 때문에 alsoPc에서 값을 변경하면 원본인 pc의 값도 변경된다.

 

 

 

initializer

enum은 열거형이라서 초기화할 것이 딱히 없다.나머지 둘을 보자.

두 인터페이스는 값을 초기화 하는 역할을 하는 initializer를 가지고 있다. 이름은 init으로 동일하지만 기본적으로 제공하는지 사용자가 작성해야 하는지 차이가 있다. structure의 경우 자신의 property를 파라미터로 가지는 default initializer가 있어서 웬만하면 그냥 써도 무관하다. class의 경우 default initialier가 없기 때문에 사용자가 작성해 주거나 property를 선언과 동시에 초기화해줘야 한다.

class circleClass {
	var radius: Double
}

struct circleStruct {
	var radius: Double
}


var cball = circleClass(radius: 1.0)	// error! no initializer!

var sball = circleStruct()		// error!
var sball = circleStruct(radius: 1.0)	// fine :)

class는 기본 initializer는 있지만 property에 대응해서 initializer가 자동으로 생성되지는 않기 때문에 radius를 초기화할 수 있는 initializer가 없다. 그래서 사용자가 만들어줘야 한다.

 

 

 

extension

protocol, class, struct 는 모두 외부에서 기능을 확장할 수 있다. 상속과는 조금 다른 개념으로 새로운 함수를 추가하고 싶을 때 사용할 수 있다. 단 새로운 인터페이스를 만드는게 아니기 때문에 변수 확장할 수 없다.

class foo {
	let name = "James"
	var age = 10

	func printName() {
		print(name)
	}
}

// now foo has printAge method
extension foo {
	func printAge() {
		print(age)
	}
}

 

 

 

상속

클래스나 구조체를 선언할 때 이름 뒤에 : 연산자를 붙여서 다른 인터페이스를 상속받을 수 있다. 단 인터페이스 별로 상속받을 수 있는 인터페이스가 다르다.

  • class : protocol, other class
  • struct : protocol

상속 구조에 따라 상위에 있는 인터페이스를 super라고 하고, 하위에 있는 인터페이스를 sub라고 한다.sub 인터페이스는 함수나 변수 등을 가져다가 사용하거나 필요하면 추가해서 사용할 수 있다.override 키워드를 사용해서 super 인터페이스에 있는 함수를 재활용할 수도 있다. 상속은 클래스에서 주로 사용하는 기능이므로 구체적인 기능과 예제는 따로 알아보자.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함