About swift – “클래스(4), extension, access modifier, protocol”

About swift – “클래스(4), extension, access modifier, protocol”

10월 19, 2021

extension

swift에서 extension은 클래스, 구조체, 열거형, 프로토콜에 새로운 기능을 추가해 주는 역할을 합니다. 그것은 하위 클래스를 생성하거나 참조하지 않고, 기존 클래스에 메서드, 생성자, 계산 프로퍼티 등의 기능을 추가하기 위하여 사용합니다.

extension 기존타입이름 {
    // 새로운 기능 코드 작성
}

아래의 예제를 살펴보겠습니다.

extension Double {
	var cubic : Double { //계산 프로퍼티
	return self * self * self
	}
}

var a : Double = 99.0
print(a.cubic)
print(222.cubic)

1줄에서 5줄의 코드를 보면, Double이라는 표준 자료형 구조체에 세제곱의 값을 반환하는 프로퍼티를 추가했습니다. 그 다음부터는 7~9줄의 코드를 보듯이, myValue라는 인스턴스를 사용할 수 있습니다.

접근 제어 (access modifier)

접근 제어(접근 수정자, 액세스 수정자, 액세스 지정자) 는 클래스나 메서드, 멤버의 접근 가능성을 설정하는 객체지향 언어의 키워드입니다.

  • 모듈은 코드 배포의 단일 유닛입니다.
  • open 접근, public 접근을 통해 모듈의 모든 소스 파일 내에서 사용할 수 있으며, 정의한 모듈을 가져오는 다른 모듈의 소스파일에서도 사용할 수 있습니다. – 보통은, 프레임워크에 공용 인터페이스를 지정할 때는 open 또는 public 접근을 사용합니다.
  • internal 접근은 해당 모듈 외부의 소스파일에서는 사용되지 않도록 하고, 해당 모듈의 모든 소스파일 내에서 사용됩니다. 내부구조를 정의할 때에 internal 접근을 사용합니다.
  • fileprivate 접근은 해당 소스 파일 내에서만 사용이 가능하고,
  • private 접근은 블록과 동일한 파일에 있는 해당 선언의 extension으로 제한합니다.
  • 읽기와 쓰기가 가능한 프로퍼티는 {get set}을,
  • 읽기만 가능한 프로퍼티는 정의 뒤에 {get} 을 붙입니다.

프로토콜과 상속

프로토콜은 특정 클래스와 관련없는 함수들의 선언 집합입니다. 함수나 메서드에 대한 정의는 없습니다.

Swift의 상속에서, 콜론 다음의 갯수가 여러 개이면, 나머지는 프로토콜을 의미한다고 이야기드린 적이 있습니다.

class 클래스명:부모명, 프로토콜명1,프로토콜명2 {}

클래스, 구조체, 열거형, 익스텐션에 프로토콜을 채택할 수 있습니다. 그렇다면 프로토콜은 어떻게 정의하는 것일까요?

protocol 프로토콜명{
	프로퍼티명
	메서드 선언
}

protocol 프로토콜명 : 부모1프로토콜, 부모2프로토콜{
	// 프로토콜은 다중 상속이 가능합니다.
}

아래의 예제를 살펴보겠습니다.

protocol ExProtocol {
	var x: Int { get set }
	var y: Int { get } 
	static var tx: Int { get set }
	static func typeMethod()
	func random() -> Double
}

ExProtocol이라는 프로토콜을 선언했습니다. 프로퍼티 x는 읽기와 쓰기가 모두 가능한 {get set} 을 사용했고, y는 {get} 만 있는 것으로 보아 읽기만 가능한 프로퍼티인 것을 알 수 있습니다. 5줄에서처럼 메소드는 선언만 되는 것을 확인할 수 있겠습니다.

프로토콜을 직접 만들어 봅시다.

protocol Barking { // 프로토콜의 정의
	var x : Int {get set}
	func bark()
}

class Dog : Barking { // 프로토콜의 채택
	var x : Int = 1
	func bark() {print("짖습니다.월월!")}
}

let bbibbi = Dog()
bbibbi.bark()

Barking이라는 프로토콜을 만들고 그것을 함수에서 채택했습니다. class Dog : Barking 이 채택을 의미합니다. 채택하는 순간, 우리는 준수라는 것을 해야 합니다. 위에서 선언되었던 프로퍼티의 값을 지정해 주고, 마찬가지로 선언만 되어 있던 메소드인 bark()의 내용을 적어 주는 것입니다.

다음의 기능을 가지는 소스를 작성해 보겠습니다.

  1. bb()라는 메소드가 하나 있는 프로토콜 B를 만듭니다.
  2. bb() 메서드는 Int형 값을 매개변수로 받아 Int형으로 리턴합니다.
  3. 클래스 A는 클래스 C라는 부모를 갖습니다.
  4. 클래스 A에서 프로토콜 B를 채택해야 합니다.
  5. bb() 메서드는 Int형 값을 매개변수로 받아 두배 한 값을 Int형으로 리턴하는 메서드입니다.
  6. 클래스 A의 인스턴스 a를 만들고, bb()를 호출해 봅니다.
protocol B { // 프로토콜 B를 만듭니다.
	func bb(x:Int)->Int
	//이 프로토콜은 bb라는 메소드를 가지는데, 이는 Int x를 Int로 반환합니다.
}

class C {} // 부모 클래스입니다.
class A : C, B { //클래스 A는 C를 부모로 가지고, B를 채택했습니다.
	func bb(x:Int) ->Int {
		return x*2 // 메소드 bb는 클래스에서 구현합니다.(준수)
	}
}

let a = A()
print((a.bb(x:34)))

설명을 써 놓았습니다^_^

열거형 ( enum )

열거형이란 관련있는 데이터들이 멤버로 구성되어 있는 자료형 객체입니다. 원하지 않는 값이 잘못 입력되는 것을 방지하는 역할을 합니다. 혹은, 입력 받을 값이 한정되어 있거나 특정 값 중 하나만 선택하게 할 때 이것을 사용합니다.

 enum 열거형명{
    case 멤버들
    // case문을 여러 개 써도 됨.
}

열거형을 정의하는 방법입니다.

enum Dinner {
	case chicken
	case pizza
	case meat
	case banana
}

var meal : Dinner
meal = .chicken
switch meal {
	case .chicken:
	print("살찌지만 맛있음.")
	case .pizza:
	print("피자 먹고 싶다.")
	case .meat:
	print("단백질 충전!!!!")
	case .banana:
	print("달달해!")
}

이러한 방식으로, 열거형 멤버별 기능을 정의할 수 있습니다.

실행 결과, meal이 .chicken이므로 “살찌지만 맛있음.”이 출력될 것입니다.

Avada Programmer

Hello! We are a group of skilled developers and programmers.

Hello! We are a group of skilled developers and programmers.

We have experience in working with different platforms, systems, and devices to create products that are compatible and accessible.