Урок 22. Наследование. Часть 1
Главная / Уроки / Страница блока Основы / Урок 22. Наследование. / Задача 22. Наследование. Часть 1.
12 Мая 2023
Задача 22.1
В методе можно просто вывести действие на консоль “издать звук” или “передвигаться”.
Создайте базовый класс “Animal” и дочерний класс “Cat”. У класса “Animal” должны быть свойства “имя” и “возраст”, а также методы “издать звук” и “передвигаться”. Класс “Cat” должен наследовать эти свойства и методы, а также иметь свойство “тип шерсти”.
class Animal {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func makeSound() {
print("The animal makes a sound")
}
func move() {
print("The animal moves")
}
}
class Cat: Animal {
let furType: String
init(name: String, age: Int, furType: String) {
self.furType = furType
super.init(name: name, age: age)
}
}
Обратите внимание на то как располагаются элементы в классе:
1. Аутлеты
2. Публичные свойства
3. Геттеры
4. Инициализаторы
5. Публичные методы класса
Этому расположению следует придерживаться. Подобная расстановка помогает искать нужный элемент, и легко ориентироваться в чужом коде. В дальнейшем этот список расширится.
Публичные свойства и методы, это обычные свойства и методы, и в дальнейшем мы изучим еще несколько их разновидностей.
Все свойства в классах должны быть константами.
Задача 22.2
Для решения этой задачи вам потребуются: умение приводить к типу, обращаться к значению словаря по ключу, и извлекать опциональное значение.
У вас есть словарь с данными:
let data = ["name": "Бульбазавр",
"image": "bulbasaur.jpg",
"health": "8",
"experience": "11"]
Создайте базовый класс “Character” и дочерний класс “Pokemon”. У класса “Character” должны быть свойства “health” и “experience” с типом Int. Класс “Pokemon” должен наследовать эти свойства, а также иметь свойства “name” и “image” с типом String. Инициализировать класс Pokemon необходимо данными из представленного словаря.
let data = ["name": "Бульбазавр",
"image": "bulbasaur.jpg",
"health": "8",
"experience": "11"]
class Character {
let health: Int
let experience: Int
init(health: Int, experience: Int) {
self.health = health
self.experience = experience
}
}
class Pokemon: Character {
let name: String
let image: String
init(value: [String: String]) {
name = value["name"] ?? ""
image = value["image"] ?? ""
let health = Int(value["health"] ?? "") ?? 0
let experience = Int(value["experience"] ?? "") ?? 0
super.init(health: health, experience: experience)
}
}
Все свойства обоих классов должны быть константами.
Класс Pokemon принимает в инициализаторе словарь, и достает значения по нужному ключу.
Давайте разберем следующую конструкцию:
let health = Int(value["health"] ?? "") ?? 0
Вы наверняка знаете, что когда мы обращаемся по ключу к значению словаря value["health"]
, то нам возвращается опциональное значение, которое мы извлекаем при помощи значения по умолчанию.
Приведение строки к типу Int точно так же приведет к опциональному значению, потому что компилятор не уверен в том что у нас получится извлечь число, поэтому мы снова используем значение по умолчанию для извлечения.
Если вы не определяли дополнительных свойств для опциональных значений, то необходимо сносить длинные строки:
init(value: [String: String]) {
name = value["name"] ?? ""
image = value["image"] ?? ""
super.init(health: Int(value["health"] ?? "") ?? 0,
experience: Int(value["experience"] ?? "") ?? 0)
}
В решении вы можете использовать опциональные значения, в таком случае нет необходимости извлекать опционалы:
class Character {
let health: Int?
let experience: Int?
init(health: Int?, experience: Int?) {
self.health = health
self.experience = experience
}
}
class Pokemon: Character {
let name: String?
let image: String?
init(value: [String: String]) {
name = value["name"]
image = value["image"]
super.init(health: Int(value["health"] ?? ""),
experience: Int(value["experience"] ?? ""))
}
}
Обратите внимание, что внутри приведения к типу Int все равно необходимо извлечь опциональное значение из значения словаря, иначе у вас будет двойной опционал.
При этом у вас не получится использовать здесь опциональную привязку:
init(value: [String: String]) {
if let name = value["name"] {
self.name = name
}
if let image = value["image"] {
self.image = image
}
super.init(health: Int(value["health"] ?? "") ?? 0, // Ошибка
experience: Int(value["experience"] ?? "") ?? 0)
}
Компилятор выдаст вам ошибку, потому что появляется вероятность оставить свойства name и image не инициализированными, в том случае если по ключу мы не обнаружим значения, компилятор такого не может допустить, поэтому выдает ошибку.
Если ваше решение отличается от представленных, отправьте его в телеграмм чат, получите личный фидбек.
Поддержите наш проект, и помогите изменить подход к обучению!
Развивайся вместе с нами
Поддержите наш проект, и помогите изменить подход к обучению!
Address List
Social Networks
Поддержите наш проект, и помогите изменить подход к обучению!
Social Networks