Содержание
Главная
Главная
|
|
Добавление нового функционала к классам с помощью методов.
iOS. Приемы программирования
Добавление нового функционала к классам с помощью методов
Методы — это строительные блоки, из которых состоят классы. Например, класс Person может иметь логические возможности — обозначим их как «ходить», «дышать», «есть» и «пить». Обычно такие функции инкапсулируются в методах.
Метод может принимать параметры. Параметры — это переменные, передаваемые вызывающей стороной при вызове метода и видимые только этому методу. Например, в упрощенном мире у нашего класса Person был бы метод walk. Но вы могли бы добавить к этому методу параметр или аргумент и назвать его walkingSpeed. Этому параметру вы бы присвоили тип CGFloat. Теперь, если другой программист вызовет этот метод в вашем классе, он может указать, с какой скоростью будет идти Person. Вы как автор класса напишете соответствующий код, который будет обрабатывать различные скорости ходьбы Person. Не переживайте, если у вас возникает ощущение «как-то много работы получается». Рассмотрим следующий пример. В нем я добавил метод в файл реализации того класса Person, который мы создали в подразделе «Как создавать классы и правильно пользоваться ими» данного раздела.
#import «Person.h»
@implementation Person
— (void) walkAtKilometersPerHour:(CGFloat)paramSpeedKilometersPerHour{
/* здесь пишем код для этого метода */
}
— (void) runAt10KilometersPerHour{
/* Вызываем метод walk в нашем собственном классе и передаем значение 10 */
[self walkAtKilometersPerHour:10.0f];
}
@end
Типичный метод в языке Objective-C имеет следующие качества.
1. Префикс указывает компилятору, является ли данный код методом экземпляра (—) или методом класса (+). К методу экземпляра можно обратиться лишь после того, как программист выделит и инициализирует экземпляр вашего класса. Получить доступ к методу класса можно, вызвав его непосредственно из этого класса. Не волнуйтесь, если на первый взгляд это кажется сложным. В этой книге мы рассмотрим многочисленные примеры методов, пока просто следите за ходом рассказа.
2. Тип данных для метода, если метод возвращает какое-либо значение. В примере мы указали тип данных void. Так мы сообщаем компилятору, что не собираемся возвращать от метода какое-либо значение.
3. Первая часть имени метода, за которой идет первый параметр. Метод может и не иметь параметров. Методы, не принимающие параметров, довольно широко распространены.
4. Список последующих параметров, идущих за первым.
Рассмотрим пример метода с двумя параметрами:
— (void) singSong:(NSData *)paramSongData loudly:(BOOL)paramLoudly{
/* Параметры, к которым мы можем обратиться здесь, в этом методе, таковы:
paramSongData (для доступа к информации о песне)
paramLoudly сообщает нам, должны мы петь песню громко или нет
*/
}
Важно учитывать, что каждый параметр каждого метода обладает внешним и внутренним именем. Внешнее имя входит в состав метода, а внутреннее имя — это фактическое название (или псевдоним) параметра, которое может использоваться в пределах реализации метода. В предыдущем примере внешнее имя первого параметра — singSong, а внутреннее — paramSongData. Внешнее имя второго параметра — loudly, а внутреннее — paramLoudly. Имя метода и внешние имена его параметров вместе образуют сущность, которая называется селектором метода. В данном случае селектор упомянутого метода будет иметь вид singSong: loudly:. Как будет объяснено далее в этой книге, селектор является идентификатором каждого метода в среде времени исполнения. Никакие два метода в рамках одного и того же класса не могут иметь одинаковые селекторы.
В нашем примере мы определили в файле реализации класса Person (Person.m) три метода:
walkAtKilometersPerHour:;
• runAt10KilometersPerHour;
• singSong: loudly:.
Если бы мы хотели использовать любой из этих методов из какой-нибудь сущности, находящейся вне класса, например из делегата приложения, то должны были бы предоставить эти методы в нашем файле интерфейса (Person.h):
#import <Foundation/Foundation. h>
@interface Person: NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
— (void) walkAtKilometersPerHour:(CGFloat)paramSpeedKilometersPerHour;
— (void) runAt10KilometersPerHour;
/* Не предоставляем метод singSong: loudly: для доступа извне.
Этот метод является внутренним для нашего класса. Зачем же нам открывать к нему доступ? */
@end
Имея такой файл интерфейса, программист может вызывать методы walkAtKilometersPerHour: и runAt10KilometersPerHour извне класса Person. А метод singSong: loudly: так вызывать нельзя, поскольку он не предоставлен в файле интерфейса. Итак, продолжим: попробуем вызвать все три этих метода из делегата нашего приложения и посмотрим, что получится:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
Person *person = [[Person alloc] init];
[person walkAtKilometersPerHour:3. 0f];
[person runAt10KilometersPerHour];
/* Если раскомментировать следующую строку кода, то компилятор выдаст
вам ошибку и сообщит, что такого метода в классе Person не существует */
//[person singSong: nil loudly: YES];
self.window = [[UIWindow alloc]
initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Итак, теперь мы умеем определять и вызывать методы экземпляров. А что насчет методов классов? Сначала разберемся, что такое методы классов и чем они отличаются от методов экземпляров.
Метод экземпляра — это метод, относящийся к экземпляру класса. Например, в нашем случае вы можете создать экземпляр класса Person дважды и получить в гипотетической игре, которую разрабатываете, двух разных персонажей. Один персонаж будет ходить со скоростью 3 км/ч, другой — 2 км/ч.
Пусть вы и написали код для метода экземпляра walk всего один раз, но когда во время исполнения создаются два экземпляра класса Person, поступающие от них вызовы методов экземпляра маршрутизируются к соответствующему экземпляру класса (тому, который выполнил вызов).
Напротив, методы класса работают только с самим классом. Например, в вашей игре есть экземпляры класса Light, отвечающего за подсвечивание сцен в вашей игре. У этого класса может быть метод dimAllLights. Вызвав этот метод, программист погасит в игре все источники света независимо от того, где они находятся. Рассмотрим пример метода класса, применяемого с нашим классом Person:
#import «Person.h»
@implementation Person
+ (CGFloat) maximumHeightInCentimeters{
return 250.0f;
}
+ (CGFloat) minimumHeightInCentimeters{
return 40.0f;
}
@end
Метод maximumHeightInCentimeters — это метод класса, возвращающий гипотетический максимальный рост любого персонажа в сантиметрах. Метод класса minimumHeightInCentimeters возвращает минимальный рост любого персонажа. Вот как мы предоставим оба этих метода в файле интерфейса нашего класса:
#import <Foundation/Foundation.h>
@interface Person: NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, assign) CGFloat currentHeight;
+ (CGFloat) maximumHeightInCentimeters;
+ (CGFloat) minimumHeightInCentimeters;
@end
Мы добавили к нашему классу Person еще одно свойство, принимающее значения с плавающей точкой. Оно называется currentHeight. С его помощью экземпляры этого класса могут хранить информацию о своей высоте в памяти (для справки) — точно так же, как имя и фамилию.
А в делегате нашего приложения мы продолжим работать с методами вот так:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
Person *steveJobs = [[Person alloc] init];
steveJobs.firstName = @»Steve»;
steveJobs.lastName = @»Jobs»;
steveJobs.currentHeight = 175.0f; /* Сантиметры */
if (steveJobs.currentHeight >= [Person minimumHeightInCentimeters] &&
steveJobs.currentHeight <= [Person maximumHeightInCentimeters]){
/* Высота этого персонажа находится в пределах допустимого */
} else {
/* Высота этого персонажа находится вне пределов допустимого */
}
self.window = [[UIWindow alloc]
initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self. window makeKeyAndVisible];
return YES;
}
Данный текст является ознакомительным фрагментом.
в предложении | Примеры предложений из Кембриджского словаря
Эти примеры взяты из корпусов и источников в Интернете. Любые мнения в примерах не отражают мнение редакторов Кембриджского словаря, издательства Кембриджского университета или его лицензиаров.
Специализированные агенты находятся в пространстве и предлагают добавленную функциональность пользователю путем абстрагирования типичных потребностей пользователя в функциональности и, следовательно, упрощения взаимодействия с клиентом.
Из Кембриджского корпуса английского языка
Обеспечивает добавленную функциональность для анализа и картирования преступлений.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Эти добавили функциональность , оптимизацию и повышение скорости компиляции.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
В добавлена функциональность дает пользователям возможность выбирать лучший контент на сайте.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Они могут иметь добавленную функциональность записи изменений на загрузочный носитель.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Для достижения этой цели, команда разработчиков включила добавила функциональность с ракурсами и крупными планами во время выступлений.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Некоторые инструменты могут быть удалены, чтобы освободить место для других инструментов, которые могут делать то же самое, но с добавленной функциональностью и большей эффективностью.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Многие авторы программных плагинов добавили функциональность для эмуляции звуков более ранних аналоговых устройств.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Большинство компьютерных языков и платформ обычно имеют добавленную функциональность , что не может быть выражено в модели вызова/возврата функции.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Некоторые инструменты добавили функциональность из предыдущей игры.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Каждый слой добавлял функциональность к ранее составленным слоям, а разные композиции слоев создавали разные программы.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован под лицензией CC BY-SA.
Эти примеры взяты из корпусов и из источников в Интернете. Любые мнения в примерах не отражают мнение редакторов Кембриджского словаря, издательства Кембриджского университета или его лицензиаров.
Проверьте свой словарный запас с помощью наших веселых викторин по картинкам
- {{randomImageQuizHook.copyright1}}
- {{randomImageQuizHook.copyright2}}
Авторы изображений
Пройди тест сейчас
Слово дня
индейка
Великобритания
Ваш браузер не поддерживает аудио HTML5
/ˈtɜː. ki/
НАС
Ваш браузер не поддерживает аудио HTML5
/ˈtɝː.ki/
крупная птица, выращиваемая на мясо на фермах
Об этом
Блог
Он мог уговорить ослика на задние лапы (Как мы разговариваем, часть 1)
Подробнее
Новые слова
коричневый шум
Другие новые слова
17.6 — Добавление новых функций в производный класс — Learn C++
Алекс
Во введении к уроку наследования мы упомянули, что одним из самых больших преимуществ использования производных классов является возможность повторного использования уже написанного кода. Вы можете наследовать функции базового класса, а затем добавлять новые функции, изменять существующие функции или скрывать функции, которые вам не нужны. В этом и нескольких следующих уроках мы более подробно рассмотрим, как выполняется каждая из этих вещей.
Во-первых, давайте начнем с простого базового класса:
#includeБазовый класс { защищено: интервал m_value {}; публичный: База (целое значение) : m_value { значение } { } void identity() const { std::cout << "Я База\n"; } };
Теперь давайте создадим производный класс, который наследуется от Base. Поскольку мы хотим, чтобы производный класс мог устанавливать значение m_value при создании экземпляров производных объектов, мы сделаем так, чтобы конструктор Derived вызывал конструктор Base в списке инициализации.
класс Производный: общедоступный Базовый { публичный: Производное (целое значение) : База {значение} { } };
Добавление новых функций в производный класс
В приведенном выше примере, поскольку у нас есть доступ к исходному коду базового класса, мы можем добавить функциональность непосредственно в базовый класс, если захотим.
Бывают случаи, когда у нас есть доступ к базовому классу, но мы не хотим его изменять. Рассмотрим случай, когда вы только что приобрели библиотеку кода у стороннего поставщика, но вам нужны дополнительные функции. Можно добавить к исходному коду, но это не лучшее решение. Что, если поставщик пришлет вам обновление? Либо ваши дополнения будут перезаписаны, либо вам придется вручную перенести их в обновление, что отнимает много времени и сопряжено с риском.
В качестве альтернативы могут быть случаи, когда невозможно даже изменить базовый класс. Рассмотрим код в стандартной библиотеке. Мы не можем изменить код, являющийся частью стандартной библиотеки. Но мы можем наследовать эти классы, а затем добавлять собственные функции в производные классы. То же самое касается сторонних библиотек, где вам предоставляются заголовки, но код поставляется предварительно скомпилированным.
В любом случае лучшим ответом будет создание собственного класса и добавление необходимых функций в производный класс.
Одно очевидное упущение в классе Base — это способ публичного доступа к m_value. Мы могли бы исправить это, добавив функцию доступа в базовый класс, но для примера мы добавим ее в производный класс. Поскольку m_value было объявлено защищенным в базовом классе, Derived имеет к нему прямой доступ.
Чтобы добавить новую функциональность в производный класс, просто объявите эту функциональность в производном классе, как обычно:
класс Производный: общедоступный Базовый { публичный: Производное (целое значение) : База {значение} { } int getValue() const { return m_value; } };
Теперь публика сможет вызывать getValue() для объекта типа Derived, чтобы получить доступ к значению m_value.