Добро пожаловать во вторую главу нашего увлекательного путешествия в мир программирования на Objective-C! В этой главе мы познакомимся с одной из самых важных концепций в современном программировании — объектно-ориентированным программированием или просто ООП. Не пугайтесь сложных терминов — мы объясним все на простых примерах, чтобы вы легко во всем разобрались.
Объектно-ориентированное программирование — это способ думать о программах, как о наборах взаимодействующих объектов. Каждый объект имеет свои свойства (характеристики) и методы (действия).
Пример из жизни:
В ООП мы создаем такие объекты в коде и заставляем их взаимодействовать между собой.
Пример:
Давайте создадим простой класс в Objective-C.
Шаг 1: Объявление класса (интерфейс)
@interface Person : NSObject
// Свойства
@property NSString *name;
@property int age;
// Методы
- (void)sayHello;
@end
@interface
и @end
используются для объявления класса.Person
— имя нашего класса.NSObject
— базовый класс, от которого наследуются все остальные (об этом позже).@property
— объявляем свойства класса.- (возвращаемый_тип)имяМетода;
Шаг 2: Реализация класса
@implementation Person
- (void)sayHello {
NSLog(@"Привет! Меня зовут %@.", self.name);
}
@end
@implementation
и @end
используются для реализации методов класса.self.name
обращается к свойству name
текущего объекта.Теперь создадим объект нашего класса и используем его.
Person *person = [[Person alloc] init];
person.name = @"Иван";
person.age = 30;
[person sayHello]; // Вывод: "Привет! Меня зовут Иван."
[[Person alloc] init]
— выделяем память и инициализируем объект.name
и age
.sayHello
.Свойства позволяют хранить данные внутри объекта. В Objective-C они объявляются с помощью @property
.
Пример:
@property NSString *name;
@property int age;
Методы — это действия, которые может выполнять объект.
Объявление метода:
- (возвращаемый_тип)имяМетода;
-
означает, что это экземплярный метод (применим к объекту).(возвращаемый_тип)
— тип данных, который метод возвращает. void
, если ничего не возвращает.имяМетода
— название метода.Пример:
- (void)sayHello;
Инкапсуляция — это принцип ООП, который подразумевает скрытие внутренней реализации объекта от внешнего мира. Другими словами, мы можем управлять доступом к данным объекта.
В Objective-C, благодаря @property
, сеттеры и геттеры создаются автоматически.
Пример:
person.name = @"Мария"; // Используется сеттер
NSString *personName = person.name; // Используется геттер
Наследование позволяет одному классу наследовать свойства и методы другого класса. Это похоже на то, как дети наследуют черты от родителей.
Создадим класс Student
, который наследует от Person
.
Объявление:
@interface Student : Person
@property NSString *university;
- (void)study;
@end
Реализация:
@implementation Student
- (void)study {
NSLog(@"%@ учится в %@.", self.name, self.university);
}
@end
Student *student = [[Student alloc] init];
student.name = @"Алексей";
student.age = 20;
student.university = @"МГУ";
[student sayHello]; // Метод из класса Person
[student study]; // Метод из класса Student
student
имеет доступ к методам и свойствам класса Person
, поскольку наследует от него.Полиморфизм — это способность объектов принимать разные формы. В программировании это означает, что объект подкласса может использоваться там, где ожидается объект родительского класса.
Представим, что у нас есть массив людей, и мы хотим, чтобы каждый из них представился.
Person *person1 = [[Person alloc] init];
person1.name = @"Иван";
Student *student1 = [[Student alloc] init];
student1.name = @"Мария";
student1.university = @"СПбГУ";
NSArray *people = @[person1, student1];
for (Person *person in people) {
[person sayHello];
}
student1
— объект класса Student
, мы можем поместить его в массив Person
.[person sayHello]
для каждого объекта будет использоваться метод sayHello
из соответствующего класса.Переопределение позволяет подклассу изменить реализацию метода, унаследованного от родительского класса.
Добавим в класс Student
свой вариант метода sayHello
.
@implementation Student
- (void)sayHello {
NSLog(@"Привет! Я студент по имени %@.", self.name);
}
- (void)study {
NSLog(@"%@ учится в %@.", self.name, self.university);
}
@end
Теперь, когда мы вызываем [student sayHello]
, будет использоваться переопределенный метод из класса Student
.
-
).+
).Пример классового метода:
@interface MathUtility : NSObject
+ (int)addNumber:(int)a toNumber:(int)b;
@end
@implementation MathUtility
+ (int)addNumber:(int)a toNumber:(int)b {
return a + b;
}
@end
Использование:
int sum = [MathUtility addNumber:5 toNumber:7]; // sum будет 12
Категории позволяют добавлять новые методы в существующие классы без изменения их исходного кода и без наследования.
Допустим, мы хотим добавить метод к классу NSString
.
Объявление категории:
@interface NSString (MyCategory)
- (void)sayString;
@end
Реализация категории:
@implementation NSString (MyCategory)
- (void)sayString {
NSLog(@"%@", self);
}
@end
Использование:
NSString *myString = @"Привет, категория!";
[myString sayString]; // Вывод: "Привет, категория!"
NSString
есть метод sayString
.Протоколы определяют набор методов, которые класс может (или должен) реализовать. Это похоже на контракт: если класс соглашается следовать протоколу, он обязуется реализовать его методы.
Объявление протокола:
@protocol Drivable <NSObject>
- (void)startEngine;
- (void)stopEngine;
@end
Класс, реализующий протокол:
@interface Car : NSObject <Drivable>
@property NSString *model;
@end
@implementation Car
- (void)startEngine {
NSLog(@"Двигатель запущен.");
}
- (void)stopEngine {
NSLog(@"Двигатель остановлен.");
}
@end
Использование:
Car *myCar = [[Car alloc] init];
myCar.model = @"Tesla Model S";
[myCar startEngine];
[myCar stopEngine];
Car
обязуется реализовать методы startEngine
и stopEngine
.Отлично! Вы познакомились с основами объектно-ориентированного программирования в Objective-C. Теперь вы знаете, что такое классы и объекты, как создавать и использовать их, а также понимаете ключевые концепции ООП: инкапсуляцию, наследование и полиморфизм.
Animal
со свойствами name
(имя) и age
(возраст).makeSound
, который будет выводить в консоль звук животного.Dog
и Cat
, которые наследуют от Animal
.makeSound
, чтобы он выводил "Гав!" для собаки и "Мяу!" для кошки.Пример:
Dog *dog = [[Dog alloc] init];
dog.name = @"Бобик";
[dog makeSound]; // Вывод: "Гав!"
Cat *cat = [[Cat alloc] init];
cat.name = @"Мурка";
[cat makeSound]; // Вывод: "Мяу!"
Calculatable
с методами add:
, subtract:
, multiplyBy:
и divideBy:
.Calculator
, который реализует этот протокол.Calculator
и продемонстрируйте работу методов.Пример:
Calculator *calculator = [[Calculator alloc] init];
int resultAdd = [calculator add:5 to:3]; // resultAdd будет 8
int resultSub = [calculator subtract:2 from:10]; // resultSub будет 8
NSString
, которая добавляет метод reverseString
.Пример:
NSString *originalString = @"Objective-C";
NSString *reversedString = [originalString reverseString]; // reversedString будет @"C-evitcejbO"
Продолжение следует...
В следующей главе мы углубимся в синтаксис Objective-C и узнаем больше о том, как писать эффективный и чистый код. Мы рассмотрим управление памятью, работу с блоками и другие важные аспекты языка.
Не забывайте практиковаться! Создавайте свои классы, экспериментируйте с наследованием и полиморфизмом. Чем больше вы будете писать код, тем лучше будете понимать принципы ООП.
Удачи и до встречи в следующей главе!
Просмотров: 46