Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Программирование. Введение в разработку на C#. Учебное пособие
.pdf
вают влияния на исходную копию в вызывающем методе. Тип значения
по ссылке можно передать с помощью ключевого слова ref.
Ссылочные типы передаются по ссылке. При передаче методу объекта, имеющего ссылочный тип, ссылка указывает на исходный объект,
а не на копию. Изменения объекта, осуществляемые с помощью этой
ссылки, будут доступны и в вызывающем методе.
Методы могут возвращать значения вызывающим их объектам. Если тип возвращаемого значения, указываемый перед именем метода, не
равен void, для возвращения значения используется ключевое слово
return. В результате выполнения инструкции с ключевым словом return,
после которого указано значение нужного типа, вызвавшему метод
объекту будет возвращено это значение. Кроме того, ключевое слово
return останавливает выполнение метода. Если тип возвращаемого значения void, инструкцию return без значения все равно можно использовать для завершения выполнения метода. Если ключевое слово return
отсутствует, выполнение метода завершится, когда будет достигнут конец его блока кода.
Когда программа создает экземпляр класса, она активизирует конструктор класса для инициализации переменных экземпляра класса
(объектов данных). Конструктор класса – это метод, у которого имя
совпадает с названием класса. Переменные экземпляра могут быть
инициализированы либо конструктором, либо при их объявлении в теле
класса. Независимо от того, получают переменные экземпляра явные
значения инициализации или нет, эти переменные всегда инициализируются. В случаях отсутствия явных значений инициализации переменные экземпляра получают значения по умолчанию (0 – для числовых переменных встроенных типов данных, false – для переменных
bool, и null – для ссылок).
Если класс не определяет конструкторы, тогда программакомпилятор обеспечивает конструктор по умолчанию (без аргументов).
Такой конструктор не содержит кода (т. е. имеет пустое тело), и не имеет никаких параметров. Конструкторы не задают возвращающих типов,
иначе результатом будут синтаксические ошибки. Также обратите вни-
71

мание, что, как правило, конструктор имеет модификатор public, иначе
невозможно было бы создать экземпляр класса.
Чтобы использовать возвращаемое методом значение в вызываемом методе, вызов метода можно поместить в любое место кода, где
требуется значение соответствующего типа. Кроме того, возвращаемое
значение можно присвоить переменной.
Использовать локальную переменную для хранения значения не
обязательно. Эта переменная может упростить читаемость кода либо
быть необходимой, если необходимо сохранить исходное значение аргумента для целой области метода.
8.2. Примеры реализации методов
Вернемся к примеру из раздела 7.2 и посмотрим на созданные нами
методы:
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
Метод Point представляет собой конструктор класса, так как имя
метода полностью совпадает с именем класса. У него два входных параметра, которые присваиваются одноименным полям класса.
public int X
{
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
72

}
X и Y это особые методы – методы-свойства. Они служат для инкапсуляции данных и являются своего рода посредниками, в которых
возможно проделать вспомогательною работу, прежде чем данные будут выведены наружу из класса с помощью параметра get или приняты
классом с помощью параметра set.
public static double Distance(Point a, Point b)
public virtual double Distance(Point a)
Данные методы служат для расчета расстояния между двумя точками. Они обладают разным количеством входных параметров типа
Point, а также выходным параметром с типом double или его отсутствием. Методы, у которых совпадают имена, но отличаются по количеству или по типам входные параметры, называются перегруженными.
Конструкторы тоже могут быть перегруженными.
public virtual void Direction()
Последний метод не обладает входными и выходными параметрами
и служит только для вывода текущих координат на экран.
8.3. Вопросы для самопроверки
1. Каково определение понятия «метод класса»?
2. Какие виды сигнатур методов вы узнали?
3. В чем заключается разница между передачей по ссылке и пере-
дачей по значению?
4. Зачем использовать методы-свойства?
8.4. Задания
1. Дополните класс студента из задания 1 раздела 7 следующими
методами:
73

– студент может получить задачу на лабораторных работах и приступить к ее выполнению;
– студент может попросить у другого студента лекции и переписать
в свою тетрадь;
– студент должен предоставить тетрадь с лекциями по требованию
лектора.
74

9. НАСЛЕДОВАНИЕ
9.1. Краткие теоретические сведения
Объект – это сущность в адресном пространстве вычислительной
системы, появляющаяся при создании экземпляра класса или копирования прототипа (например, после запуска результатов компиляции и связывания исходного кода на выполнение).
Определение класса или структуры подобно чертежу, на котором
указаны действия, выполняемые типом. В сущности, объект является
блоком памяти, выделенной и настроенной в соответствии с чертежом.
Программа может создать множество объектов одного класса. Объекты
также называют экземплярами. Они могут храниться либо в именованной переменной, либо в массиве или коллекции. Клиентский код – это
код, использующий эти переменные для вызова методов и доступа к
открытым свойствам объекта. В объектно-ориентированном языке, таком как C#, стандартная программа состоит из нескольких динамически
взаимодействующих объектов.
Поскольку классы являются ссылочными типами, в переменной
объекта класса хранится ссылка на адрес объекта в управляемой куче.
Если первому объекту назначен второй объект того же типа, обе переменные ссылаются на объект, расположенный по данному адресу. Экземпляры классов создаются с помощью оператора new.
Условно можно выделить четыре базовых принципа, на которых
базируется ООП.
Абстрагирование – это механизм выделения набора значимых характеристик объекта, исключая совсем незначительные. Соответственно, абстракция – это набор всех таких характеристик.
Инкапсуляция – это свойство системы, позволяющее объединять
данные и методы, работающие с ними, в классе и скрывать детали реализации от пользователя.
75

Наследование – это свойство системы, которое позволяет описывать новый класс на основе уже имеющегося, с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс – потомком, наследником или производным
классом.
Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре
объекта.
Центральным элементом ООП является инкапсуляция совокупности данных и соответствующих им операций. Понятие класса с его
функциями-членами и членами данных предоставляет программисту
подходящий для реализации инкапсуляции инструмент. Переменные
класса являются объектами, которыми можно управлять.
Кроме того, классы обеспечивают сокрытие данных. Права доступа
могут устанавливаться или ограничиваться для любой группы функций,
которым необходим доступ к деталям реализации. Тем самым обеспечивается модульность и надежность.
Еще одной важной концепцией ООП является поощрение повторного использования кода с помощью механизма наследования. Суть
этого механизма – получение нового производного класса из существующего, называемого базовым. При создании производного класса базовый класс может быть дополнен или изменен. Таким путем могут
создаваться иерархии родственных типов данных, которые используют
общий код.
Наследование – механизм объектно-ориентированного программирования, позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом.
Другими словами, класс-наследник реализует спецификацию уже существующего класса (базовый класс). Это позволяет обращаться с объектами класса-наследника точно так же, как с объектами базового класса.
76

В некоторых языках используются абстрактные классы. Абстрактный класс – это класс, содержащий хотя бы один абстрактный метод,
он описан в программе, имеет поля, методы и не может использоваться
для непосредственного создания объекта. То есть, от абстрактного
класса можно только наследовать. Объекты создаются только на основе
производных классов, наследованных от абстрактного. Например, абстрактным классом может быть базовый класс «сотрудник вуза», от которого наследуются классы «аспирант», «профессор» и т. д. Так как производные классы имеют общие поля и функции (например, поле «год
рождения»), то эти члены класса могут быть описаны в базовом классе.
В программе создаются объекты на основе классов «аспирант», «профессор», но нет смысла создавать объект на основе класса «сотрудник
вуза».
В зависимости от языка программирования, наследование может
быть простым (когда у класса может быть лишь один родительский
класс) и множественным. C# не допускает множественного наследования классов. Однако, множественное наследование для полностью абстрактных классов (то есть интерфейсов) разрешено.
9.2. Расширение класса с помощью наследования
Расширим класс из предыдущего раздела для работы с 3D-точками.
Для этого создадим новый класс, который будет наследоваться от Point:
class Point3D : Point
{
private int z;
public Point3D(int x, int y, int z):base(x,y)
{
this.z = z;
}
77

public int Z
{
get { return z; }
set { z = value; }
}
public static double Distance(Point3D a, Point3D b)
{
double distance;
distance = Math.Sqrt(Math.Pow(b.X - a.X, 2) +
Math.Pow(b.Y - a.Y, 2) + Math.Pow(b.Z - a.Z, 2));
return distance;
}
public double Distance(Point3D a)
{
double distance;
distance = Math.Sqrt(Math.Pow(X - a.X, 2) +
Math.Pow(Y - a.Y, 2) + Math.Pow(Z - a.Z, 2));
return distance;
}
public override double Distance(Point a)
{
double distance;
distance = Math.Sqrt(Math.Pow(X - a.X, 2) + Math.Pow(Y
- a.Y, 2) + + Math.Pow(Z - 0, 2));
return distance;
}
public override void Direction()
78

{
Console.WriteLine("Координата по X = {0}, Y = {1}, Z =
{2}", X, Y, Z);
}
}
В этом примере стоит обратить внимание, что мы расширяем класс
и добавляем только то, что относится к точке 3D, а не создаем его
заново. Мы создали новое поле и свойство Z, остальные поля и
свойства класс приобретает по наследованию. Конструктор не
наследуется, но с помощью ключевого слова base позволяет
последовательно инициализировать поля. Сначала сработает
конструктор базового класса с 2 полями, и только потом – конструктор
нового класса, который проинициализирует переменную Z. Метод static
double Distance является статическим, поэтому мы его воссоздали
заново с отличным входным типом. Метод public double Distance
является новым (входной тип отличается от того, что было, но осталось
имя) и добавляется к списку перегруженных методов. И, наконец,
последний метод public override double Distance мы модифицировали
под требования класса с точкой 3D. Для этого метода переход из 2D в
3D сделан путем обнуления координаты Z.
9.3. Вопросы для самопроверки
1. Назовите четыре базовых принципа, на которых основывается
ООП.
2. Приведите примеры применения каждого принципа для решения
повседневных задач.
3. Дайте определение абстрактному классу.
4. Что такое множественное наследование?
5. Какие преимущества дает наследование?
79

9.4. Задания для самопроверки
1. Даны 3 вида животных: попугай, ворона и кит. Организуйте для
них иерархию наследования, в которой был бы общий предок, а число
уровней равнялось трём.
(Животное -> Птица/Млекопитающее -> непосредственно класс)
2. Выделите абстрактную сущность из примера выше.
3. Опишите результат множественного наследования между птицей
и млекопитающим.
80
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
