Форум программистов, компьютерный форум, киберфорум
Наши страницы

Swift

Войти
Регистрация
Восстановить пароль
 
 
Korefey
0 / 0 / 0
Регистрация: 03.03.2012
Сообщений: 11
#1

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

25.07.2016, 15:24. Просмотров 938. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Swift: Как определить в классе-родителе, какой дочерний класс его вызвал (Swift):

Класс наследник в классе родителе - C++ Builder
Здравствуйте! Суть проблемы: Есть предположим класс TObj: class TObj { public: int X,Y;

Как в определить какой объект вызвал исключение? - C#
Как определить на каком объекте сработала ловушка? try { this.BindingSource1.EndEdit(); ...

Как определить какой объект вызвал событие - C# WPF
Здравствуйте! Хотел бы узнать, как определить какой объект вызвал событие? Например у нас есть 10 картинок (Image1, Image2.......

Как определить какой из CheckBox'ов вызвал событие CheckedChanged? - Visual Basic .NET
Чекбоксы созданы программно, список имен чекбоксов берется из Excel файла вот код: Dim ChkBox As CheckBox Dim point As...

.NET 4.x Определить, какой элемент управления вызвал событие - Visual Basic .NET
Всем здравствуйте! Есть такой момент: Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click,...

Не зарегистрирован класс. Какой класс и как его зарегистрировать? - C# ASP.NET
Решил освоить ASP. Поставил на XP Prof IIS. Запускаю его. В inetpub/wwwroot кладу скриптец test.asp: <HTML> <HEAD> ...

17
cin_cout
26 / 26 / 7
Регистрация: 06.10.2012
Сообщений: 119
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
669 / 531 / 45
Регистрация: 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
669 / 531 / 45
Регистрация: 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
669 / 531 / 45
Регистрация: 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
669 / 531 / 45
Регистрация: 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
669 / 531 / 45
Регистрация: 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
26 / 26 / 7
Регистрация: 06.10.2012
Сообщений: 119
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
26 / 26 / 7
Регистрация: 06.10.2012
Сообщений: 119
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
669 / 531 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
02.08.2016, 18:40 #15
Цитата Сообщение от cin_cout Посмотреть сообщение
Задания выглядят страшно по-джавовски.
варианты решения имеют вид стандартного ООП, чтобы новому человеку было легко ориентироваться в новом языке при помощи общедоступных знаний.

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

Цитата Сообщение от cin_cout Посмотреть сообщение
А в логике при вызове того или иного Person/Flat или с помощью оператора is, или с помощью enum'ов
А вот это уже страшно и ни по "джавовски" и ни по "свифтовому", а просто страшно, т.к. так жестко привязываться к конкретному типу используя is, это вообще мрак
0
02.08.2016, 18:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2016, 18:40
Привет! Вот еще темы с ответами:

.NET 4.x Как узнать какой элемент вызвал ContextMenuStrip - C#
На форме есть 5 текстовых полей и 1 ContextMenuStrip. причем команды для полей у всех ContextMenuStrip одинаковые. Решил оставить только...

Как узнать, какой компонент вызвал форму? - Lazarus
Программа будет использоваться на компьютере с сенсорным монитором (мышки и клавиатуры не будет). Пользователю в процессе работы на 1-й и...

.NET 4.x Как узнать какой Button вызвал метод - C#
На форме несколько кнопок, которые вызывают один и тот же метот, допустим такой: void METOD() { MessageBox.Show(" Здесь должно...

Как узнать, какой контролл вызвал событие - C#
У меня есть 12 panel'ей. Они объединены в массив. Как бы мне сделать так, чтобы при нажатии на i-ую панель вылезало, ну, к примеру, "Hello,...


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

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

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