<commit_before>
## Протоколи

### Какво са протоколите?

Протокола е "договор", който всеки тип данни (клас, структура или изброим тип) се съгласява да удовлетвори. "Договор", е списък от изисквания, който определят начина по който ще изгледжа даденият тип.

### Синтаксис
```swift
protocol Sellable {
	var pricePerUnit: Double { get }
	
	var isAvailable: Bool { set get }
}
```

### Пропъртита - properties
Протокола може да задължава всички имплементиращи го да добавят пропъртита. Има два варианта:

#### Гетъри - get
--
Когато имаме гетър, тогава наложените ограничения са най-малки. Те не ни задължават да имаме сетър. Можем да имаме изчислимо пропърти или стандартно (set и get). Дори можем да имаме и `read–only` пропърти.

#### Сетъри и гетъри -  Set & Get
--
В този случай трябва да имаме и двата метода - `get` и `set`. Т.е. ограниченията са такива, че можем да имаме или стандартно пропърти `var` (то има гет и сет) или да имплементираме изчислимо, но и с двата му варианта, за да има `set` и `get`.

Като от всеки от горе изброените два варианта, може да се прилага към типа (`static`) или към инстанцията - тук говорим за член пропъртита.

Трябва да знаем, че не можем да дадем имплементация по-подразбиране на статичните функции.

Пример:

```swift
protocol Printable {
	var description: String { get }
	
	static var version: String { get }
}
```

### Методи:
В протокола може да изискваме различни методи, като фиксираме името на метода, имената и типовете на параметрите (дали имат име или не) и типа на връщания резултат.

#### 1. към инстанцията (методи към обект)
Това са методи, които ще са характерни за инстанция (обект) от типа, който имплемнтира протокола. 

#### 2. към типа (статични методи)
Това са методи, които са характерни за типа, който имплементира протокола. Тези функции (можем спокойно да си мислим и за пропъртита)

Пример:
	
```swift
protocol PersonalComputer {
	func getRamSize() -> Int
	
	// Convert X bytes to "KB" or "MB" or "GB" or "TB"
	static convert(bytes: Int, to:String) -> Double
}
```

### Инициализираши методи

Пишем ги по стандартния начин, без самата имплементация.

Когато ги имплементираме добавяме ключовата дума `required`

Пример:

```swift
protocol Printable {
	var description: String { get }
	static var version: String { get set}    
	
	init()
	
	init(a:Int, b:Int)
}
	
class Machine: Printable {
	var powerConsumption = 0
	var name = "Missing name"
	static var version: String = "v. 2.0"

	//без този конструктор не се компилира
	required init() { }

	required init(a:Int, b:Int) {
		print("Machine")
	} 
}
```

###  Протоколи, които могат да се имплементират само от класове

Понякога имаме нуджа даден протокол, да се използва само от типове данни, които са класове. Това можем да се направи, като изпозлваме ключовата дума `class`.
Ето и един пример:

```swift
protocol PersonalComputer: class {
	func getRamSize() -> Int
	static func convert(bytes: Int, to:String) -> Double<commit_msg>Fix typos in lecture 7.<commit_after>
## Протоколи

### Какво са протоколите?

Протоколът е "договор", който всеки тип данни (клас, структура или изброим тип) се съгласява да удовлетвори. "Договор", е списък от изисквания, които определят начина по който ще изглежда даденият тип.

### Синтаксис
```swift
protocol Sellable {
	var pricePerUnit: Double { get }
	
	var isAvailable: Bool { set get }
}
```

### Пропъртита - properties
Протоколът може да задължава всички имплементиращи го да добавят пропъртита. Има два варианта:

#### Гетъри - get
--
Когато имаме гетър, тогава наложените ограничения са най-малки. Те не ни задължават да имаме сетър. Можем да имаме изчислимо пропърти или стандартно (set и get). Дори можем да имаме и `read–only` пропърти.

#### Сетъри и гетъри -  Set & Get
--
В този случай трябва да имаме и двата метода - `get` и `set`. Т.е. ограниченията са такива, че можем да имаме или стандартно пропърти `var` (то има гет и сет) или да имплементираме изчислимо, но и с двата му варианта, за да има `set` и `get`.

Като от всеки от горе изброените два варианта, може да се прилага към типа (`static`) или към инстанцията - тук говорим за член пропъртита.

Трябва да знаем, че не можем да дадем имплементация по-подразбиране на статичните функции.

Пример:

```swift
protocol Printable {
	var description: String { get }
	
	static var version: String { get }
}
```

### Методи:
В протокола може да изискваме различни методи, като фиксираме името на метода, имената и типовете на параметрите (дали имат име или не) и типа на връщания резултат.

#### 1. към инстанцията (методи към обект)
Това са методи, които ще са характерни за инстанция (обект) от типа, който имплементира протокола. 

#### 2. към типа (статични методи)
Това са методи, които са характерни за типа, който имплементира протокола. Тези функции (можем спокойно да си мислим и за пропъртита)

Пример:
	
```swift
protocol PersonalComputer {
	func getRamSize() -> Int
	
	// Convert X bytes to "KB" or "MB" or "GB" or "TB"
	static convert(bytes: Int, to:String) -> Double
}
```

### Инициализиращи методи

Пишем ги по стандартния начин, без самата имплементация.

Когато ги имплементираме, добавяме ключовата дума `required`

Пример:

```swift
protocol Printable {
	var description: String { get }
	static var version: String { get set}    
	
	init()
	
	init(a:Int, b:Int)
}
	
class Machine: Printable {
	var powerConsumption = 0
	var name = "Missing name"
	static var version: String = "v. 2.0"

	//без този конструктор не се компилира
	required init() { }

	required init(a:Int, b:Int) {
		print("Machine")
	} 
}
```

###  Протоколи, които могат да се имплементират само от класове

Понякога имаме нужда даден протокол да се използва само от типове данни, които са класове. Това можем да се направи, като използваме ключовата дума `class`.
Ето и един пример:

```swift
protocol PersonalComputer: class {
	func getRamSize() -> Int
	static func convert(bytes: Int, to:String) -> Double
{'fraction_non_alphanumeric': 0.08968079716264145, 'fraction_numerical': 0.0018577942915048134, 'mean_word_length': 4.140625, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '813490', 'n_tokens_mistral': 2444, 'n_tokens_neox': 2758, 'n_words': 817}