Форум программистов, компьютерный форум, киберфорум
Наши страницы
Swift
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
Korefey
0 / 0 / 0
Регистрация: 03.03.2012
Сообщений: 11
#1

Swift: Как определить в классе-родителе, какой дочерний класс его вызвал

25.07.2016, 15:24. Просмотров 1107. Ответов 17
Метки нет (Все метки)

Ув. форумчане, нужна помощь.
Не могу найти нормальное решение сложившеся проблеммы.
У меня есть три класса.

class Main: Object {

}

class name1: Main {
}

class name2: Main {
}

Необходимо определить в классе Main, из каким дочерним классом он был вызван.
Как корректно это можно сделать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.07.2016, 15:24
Ответы с готовыми решениями:

Класс наследник в классе родителе
Здравствуйте! Суть проблемы: Есть предположим класс TObj: class TObj...

Как в определить какой объект вызвал исключение?
Как определить на каком объекте сработала ловушка? try { ...

Как определить какой объект вызвал событие
Здравствуйте! Хотел бы узнать, как определить какой объект вызвал событие?...

Как определить какой из CheckBox'ов вызвал событие CheckedChanged?
Чекбоксы созданы программно, список имен чекбоксов берется из Excel файла вот...

Определить, какой элемент управления вызвал событие
Всем здравствуйте! Есть такой момент: Private Sub Button4_Click(sender As...

17
cin_cout
27 / 27 / 7
Регистрация: 06.10.2012
Сообщений: 130
25.07.2016, 17:17 #2
Цитата из книжки "Swift 2.2"

«Checking Type
Use the type check operator (is) to check whether an instance is of a certain subclass type. The type check operator returns true if the instance is of that subclass type and false if it is not.»
1
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
28.07.2016, 01:17 #3
ни в коем случае такой фигней не страдайте!

вопрос: для чего вам это нужно?
0
Korefey
0 / 0 / 0
Регистрация: 03.03.2012
Сообщений: 11
28.07.2016, 01:34  [ТС] #4
Мне нужно заполнить поле родительского класса значением, расчет которого осуществляется с учетом дочернего класса, который его "вызвал".
0
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
28.07.2016, 01:52 #5
т.е. в родительском классе есть некая логика, которая должна сработать плюс логика дочернего класса, так?

тогда создаете метод в родительском классе, в дочернем его переопределяете и вуа-ля

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Parent {
    func someLogic() -> Int {
        return 42 + someDetails()
    }
 
    func someDetails() -> Int {
        return 0
    }
}
 
class Child: Parent {
    override func someDetails() -> Int {
        return 10
    }
}
 
let x: Parent = Parent()
x.someLogic() // 42
 
let y: Parent = Child()
y.someLogic() // 52
1
Korefey
0 / 0 / 0
Регистрация: 03.03.2012
Сообщений: 11
28.07.2016, 12:54  [ТС] #6
Не совсем то что нужно.
У меня порядка 7 дочерних классов, и я не знаю наверняка, какой дочерний класс "вызвал" суперкласс.
0
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
28.07.2016, 12:58 #7
дочерние классы не вызывают суперклассов, они наследуют поведение.
то, что у вас иерархия из 7 вложенностей - запах плохого дизайна, и то, что вам в суперклассе нужно знать о наследниках - результат неправильного понимания наследования и полиморфизма, да и вообще абстрагирования и распределения обязанностей. суперкласс понятия не имеет, будут от него наследоваться или нет.

объясните пожалуйста, для чего вам все это нужно. зачем вам знать какой дочерний класс "вызвал" суперкласс?
0
Korefey
0 / 0 / 0
Регистрация: 03.03.2012
Сообщений: 11
29.07.2016, 00:12  [ТС] #8
С пониманием таких понятий как наследование и полиморфизм у меня все в порядке. Вы не так поняли мой вопрос.
У меня нет иерархии из 7 вложенностей. Есть родительский класс, и есть 7 дочерних классов, которые наследуют этот родительский.
0
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
29.07.2016, 01:37 #9
Хорошо, тогда зачем вам знать в родительском классе о дочерних?
Насчет расчета чего-то в родительском с учетом дочернего, так паттерн template method хорошо вписывается сюда (так как я выше показал), за исключением того, что родительский в этом случае не абстрактный.
0
Korefey
0 / 0 / 0
Регистрация: 03.03.2012
Сообщений: 11
29.07.2016, 01:49  [ТС] #10
Смысл в том, чтобы в случае когда "вызывается" класс родитель из 3 определенных дочерних классов, в классе родителе одно из полей получает значение true.
В дальнейшем это поле берется во внимание в различных расчетах.
0
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
29.07.2016, 10:32 #11
так как-то?
в дочерних переопределяете метод, а в родительском записана основная логика работы алгоритма, т.е. дочерние только конфигурируют родителя.
Child3 не переопределил метод, потому у него будет такая же логика, как по-умолчанию у родителя

Javascript
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
32
33
34
35
36
37
38
class Parent {
    func shouldBeTrue() -> Bool {
        return false
    }
 
    func doSomething() -> Int {
        let someTrickyLogic = 42
        if shouldBeTrue() {
            return someTrickyLogic + 1
        }
        return someTrickyLogic - 1
    }
}
 
class Child1: Parent {
    override func shouldBeTrue() -> Bool {
        return true
    }
}
 
class Child2: Parent {
    override func shouldBeTrue() -> Bool {
        return true
    }
}
 
class Child3: Parent {
    // shouldBeTrue will return false as its Parent
}
 
let c1 = Child1()
c1.doSomething() // 43
 
let c2 = Child2()
c2.doSomething() // 43
 
let c3 = Child3()
c3.doSomething() // 41
0
cin_cout
27 / 27 / 7
Регистрация: 06.10.2012
Сообщений: 130
29.07.2016, 17:47 #12
Не до конца понимаю архитектуру, но я бы упростил подобный вариант dependency injection до использования enumов в Swift'e
без применения наследования. Если надо наклепать однообразных классов, есть протоколы, в конце концов.
0
kabudasay
3 / 3 / 1
Регистрация: 13.04.2015
Сообщений: 51
02.08.2016, 10:57 #13
Objective-C
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
//Наследование
 
 class Person {
  //свойства экземпляров
  let name: String
  var age: Int
  
  //методы экземпляров
  func aboutMe() -> String {
    return "Hello my name is \(name) and I'am \(age) years old"
  }
  
  //стандартный метод init
  init(){
    self.name = "David"
    self.age = 30
  }
  
  //пользовательский init
  init(name: String, age: Int) {
    self.name = name
    self.age = age
  }
  
  deinit {
    //что-то делаем при освобождении объекта
  }
}
 
class Child: Person {
  var sister: String
  
  
  override func aboutMe() -> String {
    let original = super.aboutMe()
    return "\(original) and I have a sister \(sister)"
  }
  
  override init() {
    sister = "Anna"
    super.init()
  }
}
 
let child = Child()
child.sister
child.aboutMe()
 
let person = Person()
person.age
person.aboutMe()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//ДЗ
//№1
//Создайте класс Flat (квартира), у которого есть свойство rooms: Int, отображающее количество комнат, свойство square: Int, отображающее площадь квартиры, свойство name: String, метод description, который описывает квартиру. Создайте инициализатор с аргументами и дефолтный инициализатор (без аргументов)
 
//№2
// Создайте класс House, который является подклассом класса Flat, но который имеет дополнительное свойство stages типа Int, отображающее количество этажей.
 
//№3
//Перепишите метод init для этого класса и функцию descritption, чтобы вы могли уже рассказать о том, сколько у вас этажей (stages).
 
//Создайте экземпляр и измените все свойства, чтобы они имели какие-то реальные значения. Вызовите этим экземпляром функцию description.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//№1
//Создайте класс Flat (квартира), у которого есть свойство rooms: Int, отображающее количество комнат, свойство square: Int, отображающее площадь квартиры, свойство name: String, метод description, который описывает квартиру. Создайте инициализатор с аргументами и дефолтный инициализатор (без аргументов)
 
class Flat {
  var name: String
  var square: Int
  var rooms: Int
  
  init() {
    name = "Unknown"
    square = 0
    rooms = 0
  }
  
  init (name: String, square: Int, rooms: Int) {
    self.name = name
    self.square = square
    self.rooms = rooms
  }
  
  func description() -> String {
    return "We have a \(name), it's square is \(square), and there are \(rooms) rooms there"
  }
}
 
let flat1 = Flat(name: "flat", square: 90, rooms: 4)
 
//№2
// Создайте класс House, который является подклассом класса Flat, но который имеет дополнительное свойство stages типа Int, отображающее количество этажей.
 
//class House: Flat {
//  let stages: Int
//  
//  init (stages: Int) {
//    self.stages = stages
//    super.init ()
//  }
//}
 
 
//№3
//Перепишите метод init для этого класса и функцию descritption, чтобы вы могли уже рассказать о том, сколько у вас этажей (stages).
 
//Создайте экземпляр и измените все свойства, чтобы они имели какие-то реальные значения. Вызовите этим экземпляром функцию description.
 
class House: Flat {
  let stages: Int
  
  init (stages: Int) {
    self.stages = stages
    super.init ()
  }
  
  override func description() -> String {
    let originalDesc = super.description()
    return "\(originalDesc), and we have \(stages) stages!"
  }
}
 
//создайте экземпляр и измените все свойства, чтобы они имели какие-то реальные значения. Вызовите этим экземпляром функцию description
 
var house1 = House(stages: 2)
house1.name = "house"
house1.rooms = 8
house1.square = 96
house1.description()
Вот примеры с классами и их наследованием
0
cin_cout
27 / 27 / 7
Регистрация: 06.10.2012
Сообщений: 130
02.08.2016, 16:34 #14
Задания выглядят страшно по-джавовски.

Свифтово было бы так:

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
protocol Person {
   var name: String { get } { set } 
   var age: Int { get } { set } 
   func aboutMe () -> String
}
 
protocol Dwelling { 
   var name: String { get } 
   var square: Float { get } { set }
   var rooms: Int { get }
   func description (location: String, metroStation: String, cost: Double) -> (String, String, Double) 
}
Дальше реализация разных Person или Flat в любых вариантах. А в логике при вызове того или иного Person/Flat или с помощью оператора is, или с помощью enum'ов (если объекты, например, поддаются типизации) определяться, кто кого вызвал.
0
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
02.08.2016, 18:40 #15
Цитата Сообщение от cin_cout Посмотреть сообщение
Задания выглядят страшно по-джавовски.
варианты решения имеют вид стандартного ООП, чтобы новому человеку было легко ориентироваться в новом языке при помощи общедоступных знаний.

По "свифтовому" я бы вообще избегал наследования и все по максимуму реализовывал при помощи расширений протоколов, но новому человеку сложно сходу все это охватить, потому начинаем с самого простого и доступного

Цитата Сообщение от cin_cout Посмотреть сообщение
А в логике при вызове того или иного Person/Flat или с помощью оператора is, или с помощью enum'ов
А вот это уже страшно и ни по "джавовски" и ни по "свифтовому", а просто страшно, т.к. так жестко привязываться к конкретному типу используя is, это вообще мрак
0
cin_cout
27 / 27 / 7
Регистрация: 06.10.2012
Сообщений: 130
02.08.2016, 23:24 #16
Цитата Сообщение от Vorona Посмотреть сообщение
А вот это уже страшно и ни по "джавовски" и ни по "свифтовому", а просто страшно, т.к. так жестко привязываться к конкретному типу используя is, это вообще мрак
Чем же это страшно?
0
Vorona
Peace 2 all shining faces
672 / 534 / 84
Регистрация: 05.03.2010
Сообщений: 1,283
02.08.2016, 23:29 #17
жесткой привязкой к конкретному типу, потерей всех преимуществ полиморфизма

зачем вам проверять тип, если можно нужным образом реализовать протокол или переопределить метод родителя в наследнике, получая динамическую реализацию в рантайме, а не на этапе компиляции

на этом принципе основаны такие паттерны как декоратор или прокси - подстановка любой имплементации и получение любого поведения используя единый протокол

почитайте gof или head first design patterns, там круто это объясняется
0
kabudasay
3 / 3 / 1
Регистрация: 13.04.2015
Сообщений: 51
03.08.2016, 07:14 #18
раздули демагогию уууууу
0
03.08.2016, 07:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2016, 07:14

Не зарегистрирован класс. Какой класс и как его зарегистрировать?
Решил освоить ASP. Поставил на XP Prof IIS. Запускаю его. В inetpub/wwwroot...

Как узнать какой элемент вызвал ContextMenuStrip
На форме есть 5 текстовых полей и 1 ContextMenuStrip. причем команды для полей...

Как узнать какой Button вызвал метод
На форме несколько кнопок, которые вызывают один и тот же метот, допустим...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru