Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 752eb2c

Browse files
Docs for 'Classes'
1 parent c4c064c commit 752eb2c

File tree

8 files changed

+338
-0
lines changed

8 files changed

+338
-0
lines changed

‎docs/classes/Abstract class.md‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## Abstract class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
5+
| :warning: | Можно наследоваться от абстрактного класса, IDE подсказывает какие методы надо переопределить | В IDE нет подсказок о необходимости переопределить абстрактный метод |
6+
7+
### Пояснения
8+
9+
Опишем простой абстрактный класс на Kotlin-е:
10+
11+
```kotlin
12+
abstract class AbstractClassExample(
13+
val param1: String
14+
) {
15+
abstract fun forOverride(): String
16+
}
17+
```
18+
19+
В Swift-коде мы можем сделать наследника этого класса, но IDE не подсказывает нам, что метод `forOverride` нужно переопределить.
20+
21+
```swift
22+
class MySwiftChild : AbstractClassExample {
23+
24+
// Можно не переопределять метод forOverride, код успешно скомпилируется.
25+
26+
}
27+
```
28+
29+
При попытке использовать этот метод приложение упадёт с `NSGenericException`.
30+
31+
[В Objective-C, похоже, нет понятия abstract class](https://stackoverflow.com/questions/1034373/creating-an-abstract-class-in-objective-c),
32+
и [в Swift - тоже](https://stackoverflow.com/questions/24110396/abstract-classes-in-swift-language).
33+
34+
В отказе от абстрактных классов есть смысл, что-то вроде "предпочитайте композицию, а не наследование", но после Java
35+
это может оказаться неудобным.
36+
37+
Самое близкое понятие к абстрактному классу в Swift - это `@protocol`. Поверх протокола можно описать extension-ы,
38+
можно описывать дефолтные реализации методов. И будет примерно то же самое, что и абстрактный класс.
39+
40+
---
41+
[Оглавление](/README.md)

‎docs/classes/Annotation class.md‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Annotation class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------------- | ------------------------------------ | ----------------------------- |
5+
| :no_entry_sign: | Аннотации можно использовать в Swift | Аннотации не попали в .h-файл |
6+
7+
### Пояснения
8+
9+
Добавим аннотации в Kotlin-е:
10+
11+
```kotlin
12+
@Target(AnnotationTarget.CLASS)
13+
annotation class AnnotationClassExample
14+
15+
@Retention(AnnotationRetention.BINARY)
16+
@Target(AnnotationTarget.CLASS)
17+
annotation class BinaryClassExample
18+
19+
@Retention(AnnotationRetention.RUNTIME)
20+
@Target(AnnotationTarget.CLASS)
21+
annotation class RuntimeAnnotationClass
22+
23+
@Retention(AnnotationRetention.SOURCE)
24+
@Target(AnnotationTarget.CLASS)
25+
annotation class SourceAnnotationClass
26+
```
27+
28+
Вне зависимости от указанных retention-ов, аннотации не попали в `.h`-файл, и их нельзя использовать в Swift.
29+
30+
В Swift-е нет аннотаций в том смысле, в котором они присутствуют в Kotlin, но
31+
[есть атрибуты](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html), которые используются для
32+
определённых целей.
33+
34+
---
35+
[Оглавление](/README.md)

‎docs/classes/Data class.md‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
## Data class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------- | ----------------------------------------------------------- | ---------------------------------------------------------------------- |
5+
| :warning: | Data class-ы сохраняют свои свойства после перехода в Swift | Не все возможности data class-ов сохраняются / есть особенности с copy |
6+
7+
### Пояснения
8+
9+
Опишем обычный data class в Kotlin-е:
10+
11+
```kotlin
12+
data class DataClassExample(
13+
val param1: String,
14+
val param2: Int,
15+
val param3: Boolean
16+
)
17+
```
18+
19+
#### Метод `copy`
20+
21+
Метод `copy` переносится в Swift с названием `doCopy`, работает аналогично методу в Kotlin, но
22+
есть неудобство [с необходимостью указывать все аргументы функции](/docs/usual-workflow/Function%20with%20default%20arguments.md).
23+
24+
#### Метод `equals`
25+
26+
Сравнение двух экземпляров data class-а работает аналогично Kotlin-у, включая сравнение коллекций.
27+
28+
#### Метод `toString`
29+
30+
При использовании объекта data class-а в строчке вывод такой же, как в Kotlin:
31+
32+
```swift
33+
let dc = DataClassExample(param1: "123", param2: 10, param3: true)
34+
print("dc = \(dc)")
35+
```
36+
37+
#### Destructuring
38+
39+
Эта фича Kotlin-а не работает. Но функции `component1()`, `component2`, ... `componentN()` доступны,
40+
и при желании можно описать свой метод для деструктуризации:
41+
42+
```swift
43+
extension DataClassExample {
44+
func destruct() -> (String, Int32, Bool) {
45+
return (component1(), component2(), component3())
46+
}
47+
}
48+
49+
func example() {
50+
val (param1, param2, param3) = DataClassExample("", 100, true).destruct()
51+
}
52+
```
53+
54+
---
55+
[Оглавление](/README.md)

‎docs/classes/Enum class.md‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Enum class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
5+
| :warning: | Kotlin-овский enum class превратится в enum Swift-а, и можно будет использовать switch | Не работает как ожидается. Но сгенерировался объект со статическими элементами |
6+
7+
### Пояснения
8+
9+
Опишем обычный enum class в Kotlin-е:
10+
11+
```kotlin
12+
enum class MyEnum(val type: String) {
13+
14+
ENTRY_ONE("entry_one"),
15+
ENTRY_TWO("entry_two");
16+
17+
companion object {
18+
fun findByType(type: String) = values().find { it.type == type }
19+
}
20+
21+
}
22+
```
23+
24+
На стороне Swift-а не был сгенерирован enum, и как следствие, класс нельзя удобно использовать в
25+
выражении `switch`. Но доступ к элементам enum-а есть, есть доступ к функции внутри companion object-а,
26+
есть возможность вызвать метод `values()`.
27+
28+
```swift
29+
func enumClassUsage() {
30+
let _ = MyEnum.entryOne
31+
let _ = MyEnum.entryTwo
32+
33+
let _ = MyEnum.entryOne.name
34+
let _ = MyEnum.entryOne.type
35+
36+
let _ = MyEnum.companion.findByType(type: "entry_two")
37+
let optionalResult = MyEnum.companion.findByType(type: "entry_two_trheee")
38+
}
39+
40+
private func enumEntryUsage(enumClassExample: MyEnum) {
41+
switch enumClassExample {
42+
default:
43+
print("Sad")
44+
}
45+
}
46+
```
47+
48+
[Kotlin/Native пока что не поддерживает генерацию enum-а](https://youtrack.jetbrains.com/issue/KT-48068).
49+
50+
См. [moko-kswift overview](/docs/moko-kswift/Overview.md)
51+
52+
---
53+
[Оглавление](/README.md)

‎docs/classes/Inner class.md‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## Inner class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------- | -------------------------------------------------------------------------------------------- | --------------------------------------- |
5+
| :warning: | Можно создать инстанс inner-класса / прямого доступа к родительским свойствам и функциям нет | Небольшие отличия в синтаксисе создания |
6+
7+
### Пояснения
8+
9+
Создадим небольшой inner-класс на Kotlin-е:
10+
11+
```kotlin
12+
class InnerClassExample(
13+
val param: String
14+
) {
15+
16+
fun parentFunc() {}
17+
18+
inner class MyInnerClass {
19+
fun useSomeFunction() {
20+
println("this@InnerClassExample.param == ${this@InnerClassExample.param}")
21+
}
22+
}
23+
}
24+
25+
private fun example() {
26+
val inner = InnerClassExample("12").MyInnerClass()
27+
}
28+
```
29+
30+
В Swift-е немного меняется синтаксис создания экземпляра inner-класса, нужно явно передавать родительский класс в конструктор:
31+
32+
```swift
33+
let _ = InnerClassExample.MyInnerClass(InnerClassExample(param: "1323"))
34+
```
35+
36+
---
37+
[Оглавление](/README.md)

‎docs/classes/Open class.md‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## Open class
2+
3+
| Статус | Ожидание | Реальность |
4+
| ------------------ | ----------------------------------------------------------------------------------------------------- | ----------------------------------- |
5+
| :white_check_mark: | Можно наследоваться от open-класса / есть доступ к protected-полям / можно переопределять open-методы | Можно переопределять и final-методы |
6+
7+
### Пояснения
8+
9+
Опишем open class на Kotlin:
10+
11+
```kotlin
12+
open class OpenClassWithConstructorParams(
13+
val param1: String,
14+
val param2: Boolean
15+
) {
16+
17+
protected val someField: String get() = "14"
18+
19+
fun finalMethodInClass() {
20+
println("Final method in open class")
21+
}
22+
23+
open fun methodCanBeOverride() {
24+
println("OpenClassWithConstructorParams | methodCanBeOverride")
25+
}
26+
27+
}
28+
```
29+
30+
На стороне Swift-а мы можем наследоваться от этого класса, использовать его protected-свойства,
31+
переопределять open и даже переопределять **final**-методы:
32+
33+
```swift
34+
class OpenSwiftClass : OpenClassWithConstructorParams {
35+
override func methodCanBeOverride() {
36+
print("methodCanBeOverride in SwiftOpen2")
37+
}
38+
39+
override func finalMethodInClass() {
40+
print("I can override final method")
41+
}
42+
}
43+
44+
func example() {
45+
let osc = OpenSwiftClass(param1: "123", param2: true)
46+
let _ = osc.someField
47+
}
48+
```
49+
50+
---
51+
[Оглавление](/README.md)

‎docs/classes/Sealed class.md‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## Sealed class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
5+
| :no_entry_sign: | Корректно конвертируется в структуру, которую можно передать в switch-конструкцию и сделать exhaustive | Генерируется класс с наследниками. Передав в switch нет подсказок об exhaustive |
6+
7+
### Пояснения
8+
9+
В Kotlin-е sealed-классы могут использоваться в `when`-выражениях, которые могут подсказывать программисту
10+
о забытых ветках:
11+
12+
```kotlin
13+
sealed class MySealed {
14+
object Object : MySealed()
15+
16+
class Simple(val param1: String) : MySealed()
17+
18+
data class Data(val param1: String, val param2: Boolean) : MySealed()
19+
}
20+
21+
private fun example(s: MySealed) {
22+
when (s) {
23+
MySealed.Object -> TODO()
24+
is MySealed.Simple -> TODO()
25+
is MySealed.Data -> TODO()
26+
}
27+
}
28+
```
29+
30+
Но в Swift такой класс сконвертируется как обычный класс с наследниками, который бесполезен при подстановке в `switch`:
31+
32+
```switch
33+
func example(s: MySealed) {
34+
switch s {
35+
default:
36+
print("Sad")
37+
}
38+
}
39+
```
40+
41+
В Swift-е роль sealed-классов выполняют enum-ы, и можно было бы написать специальный bridge-код для конвертации
42+
sealed-классов в Swift-овый enum.
43+
44+
См. [moko-kswift overview](/docs/moko-kswift/Overview.md)
45+
46+
---
47+
[Оглавление](/README.md)

‎docs/classes/Value class.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## Value class
2+
3+
| Статус | Ожидание | Реальность |
4+
| --------------- | ------------------------------------------------------------ | --------------------------------------------- |
5+
| :no_entry_sign: | Класс попадёт в .h-файл, им можно будет пользоваться в Swift | Класс не попал в .h-файл, пользоваться нельзя |
6+
7+
### Пояснения
8+
9+
Опишем value-класс на стороне Kotlin-а:
10+
11+
```kotlin
12+
value class ValueClassExample(val t: Int)
13+
```
14+
15+
В Swift-е этот класс [недоступен](https://kotlinlang.org/docs/native-objc-interop.html#unsupported),
16+
класс не попал в `.h`-файл.
17+
18+
---
19+
[Оглавление](/README.md)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /