Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование. Введение в разработку на C#. Учебное пособие

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
вают влияния на исходную копию в вызывающем методе. Тип значения по ссылке можно передать с помощью ключевого слова 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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]