Урок 23. Наследование. Часть2

19 Января 2023

Задача 23.1 📚

Создайте базовый класс (супер класс) описывающий продукт: Product, в котором есть свойство price – стоимость продукта и метод calculateTax(), который возвращает коэффициент налога 0.1 умноженный на стоимость продукта. Унаследуйте от  него класс Food. Необходимо переопределить метод calculateTax() в классе Food, чтобы он возвращал коэффициент налога 0.05 умноженный на стоимость продукта. Затем создайте экземпляр класса Food и выведите результат работы метода  calculateTax() на консоль.

				
					class Product {
	let price: Double
	
	init(price: Double) {
		self.price = price
	}
	
	func calculateTax() -> Double {
		price * 0.1 // Налог составляет 10% от цены продукта
	}
}

class Food: Product {
	override func calculateTax() -> Double {
		price * 0.05 // На продукты питания налог может быть снижен до 5%
	}
}


// Создание экземпляра класса
let apple = Food(price: 1.99)

print("Налог на продукт питания: $\(apple.calculateTax())")
				
			

Обратите внимание что свойство price должно быть константой, в контексте мы его не меняем, а просто используем в расчетах.

В данном примере класс Product представляет базовый класс продукта с методом calculateTax(), который возвращает налог на продукт, рассчитанный как 10% от его цены.

Класс Food наследуюется от класса Product и получает в свое распоряжение все его свойства и методы. Так как нам нужно изменить логику метода calculateTax(), то мы его переопределяем  в соответствии с налоговыми правилами для продуктов питания.

Далее мы создаем экземпляр класса Food и выводим на консоль результат работы метода calculateTax(). 

Так же прошу заметить что в методе ключевое слово return писать не нужно.

Если вы реализовали метод следующим образом, то это будет считаться не очень красивым решением:

				
					class Food: Product {
	override func calculateTax() -> Double {
		let coefficient = 0.05
		return price * coefficient // На продукты питания налог может быть снижен до 5%
	}
}
				
			

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

Дополнительное свойство можно создать для результата работы функции: 

				
					// Создание экземпляра класса
let apple = Food(price: 1.99)
let result = apple.calculateTax()

print("Налог на продукт питания: $\(result)")
				
			

Это не плохой подход, поскольку результат работы метода хочется сохранить в памяти для дальнейшего использования. 

Задача 23.2 📚

Создайте базовый класс (супер класс) Lable, в котором будут три свойства text, tintColor и font. два последних инициализируйте сразу любыми значениями, тип данных свойства titnColor должно быть перечислением:

				
					enum Color {
	case red
	case blue
	case green
}
				
			

Свойство text должно быть инициализированно в момент создания экземпляра класса. 

Создайте еще один класс CustomLabel и унаследуйте его от класса Label. Задайте для свойств tintColor и font новые значения, использовав переопределение инициализатора.

				
					enum Color {
	case red
	case blue
	case green
}

class Label {
	var text: String
	var tintColor: Color = .blue
	var font = 16
	
	init(text: String) {
		self.text = text
	}
}

class CustomLabel: Label {
	override init(text: String) {
		super.init(text: text)
		tintColor = .green
		font = 20
	}
}
				
			

Свойство text можно было сделать константой, в нашем контексте это будет правильно, но так как мы имитируем реальный элемент интерфейса, то оно должно быть переменной. 

Класс CustomLabel наследует все от класса Label, в том числе и инициализатор, но так как мы хотим при инициализации CustomLabel,  устанавливать для свойств tintColor и font новые значения, то мы переопределяем унаследованный инициализатор, то есть буквально переписываем логику внутри. 

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

Если вы создали отдельный метод для настройки свойств, то это тоже отличное решение:

				
					class CustomLabel: Label {
	override init(text: String) {
		super.init(text: text)
		setupCustomLabel()
	}
	
	func setupCustomLabel() {
		tintColor = .green
		font = 20
	}
}
				
			

Такое решение будет даже предпочтительней. В реальных проектах по код стайлу положено все настройки элемента интерфейса выносить в отдельный метод. 

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

Поддержите наш проект, и помогите изменить подход к обучению!

Развивайся вместе с нами

Поддержите наш проект, и помогите изменить подход к обучению!

Address List

Social Networks

Поддержите наш проект, и помогите изменить подход к обучению!