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

lec

.pdf
Скачиваний:
24
Добавлен:
24.03.2015
Размер:
3.43 Mб
Скачать

{

private double мощность; private double цена;

public double Мощность

{

set { мощность = value; } get { return мощность; }

}

public double Цена

{

set { цена = value; } get { return цена; }

}

}

class Прибор

{

private Корпус кор; private Лампочка лам;

private string состояние; //включено или выключено

//конструктор

public Прибор(Корпус кор, Лампочка лам, string состояние)

{

this.кор = кор; this.лам = лам;

this.состояние = состояние;

}

//свойство

public string Состояние

{

set { Состояние = value; }

}

//вывести данные public void Показать()

{

Console.WriteLine("{0} {1} {2} {3} {4} {5}", состояние, кор.Тип, кор.Цена,

лам.Цена, лам.Мощность);

}

}

В основной программе соберем осветительный прибор из корпуса типа «Тюльпан» ценой 800 рублей и лампочки мощностью 60 Вт, ценой 30 рублей.

class Корпус

{

private string тип; // тип корпуса private double цена;

public string Тип

121

{

set { тип = value; } get { return тип; }

}

public double Цена

{

set { цена = value; } get { return цена; }

}

}

class Лампочка

{

private double мощность; private double цена;

public double Мощность

{

set { мощность = value; } get { return мощность; }

}

public double Цена

{

set { цена = value; } get { return цена; }

}

}

class Прибор

{

private Корпус кор; private Лампочка лам;

private string состояние; //включено или выключено

//конструктор

public Прибор(Корпус кор, Лампочка лам, string состояние)

{

this.кор = кор; this.лам = лам;

this.состояние = состояние;

}

//свойство

public string Состояние

{

set { состояние = value; }

}

//вывести данные public void Показать()

{

122

Console.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}", состояние, кор.Тип, кор.Цена,

лам.Цена, лам.Мощность);

}

}

class Program

{

static void Main()

{//1. объявляем ссылки Корпус к; Лампочка л; Прибор п;

//2. создаем объкты к = new Корпус(); к.Тип = "Тюльпан";

к.Цена = 800.0;

л = new Лампочка(); л.Мощность = 60.0;

л.Цена = 30.0;

//3., 4. контейнер

п = new Прибор(к, л, "Включено"); п.Показать();

//меняем лампочку л.Мощность = 200.0; п.Показать();

}

3.Композиция на основе классов

Вэтом случае объект-часть должен создаваться в процессе создания объекта-контейнера.

123

Изменить состояние объекта-части можно только в рамках самого контейнера, извне это сделать нельзя.

Пример Сущности аналогичны базовым. Отличия в предметной области:

осветительный прибор собирается на заводе изготовителе и представляет собой единое целое. Замена частей невозможна.

Отличия в программном коде заключаются в изменении конструктора класса Прибор. В этом конструкторе создаются объекты-части (лампочка и корпус изготавливаются на заводе на основе их технических характеристик, принятых в качестве параметров).

public Прибор(Корпус кор, Лампочка лам, string состояние)

{

this.кор = new Корпус(); this.кор.Тип = кор.Тип; this.кор.Цена = кор.Цена; this.лам = new Лампочка(); this.лам.Цена = лам.Цена;

this.лам.Мощность = лам.Мощность; this.состояние = состояние;

}

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

//смена эталонной лампочки п = new Прибор(к, л, "Включено");

Если поле, определяющее лампочку в классе Прибор сделать открытым, лампочку можно будет заменить, не создавая нового прибора.

п.лам.Мощность = 200.0;

Но это противоречит описанию предметной области.

4. Композиция на основе структур

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

Отличия от класса (основные)

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

Копирование выполняется поверхностное (с полей значения снимается копия значений, с полей ссылок снимается копия ссылки).

Таким образом, задача создания осветительного прибора, не допускающего замены корпуса и лампочки, может быть решена с помощью кода абсолютно идентичного коду базового примера пу-

124

тем замены классов Корпус, Лампочка, Прибор, путем замены классов на структуры.

class Æ struct

2.Для структур не поддерживается механизм наследования.

Прочие отличия

1.Конструктор по умолчанию для структур невозможно переопределить, он всегда есть и всегда доступен. Можно добавить конструктор с параметрами.

2.Создания объекта типа stuct не требует операции new. Но в этом случае поля структуры будут неопределенными по значению.

3.При определении структуры запрещена инициализация полей.

125

НАСЛЕДОВАНИЕ

1 Понятие наследования

С точки зрения моделирования предметной области наследование предназначено для описания некоторой сущности (потомка) путем указания отличий от другой сущности (предка).

В ООП наследование рассматривается как отношение между классами, при котором класс-потомок представляет собой разновидность клас- са-предка.

Отношение наследования раскрывает предметную область по типу «общее - специфическое». Представление предметной области в виде наследования представляет собой иерархию, на вершине которой находится класс-предок (базовый класс), а на нижних уровнях – классы-

наследники (наследуемые классы).

Предок может иметь множество наследников. Наследник может иметь не более одного прямого предка. Другими словами, в С# явным образом не поддерживается множественное наследование. Потомок не может унаследовать поля и методы от нескольких прямых предков. Пример наследования приведен на Рис.1.

Автомобиль базовый комплектации

Кузов

Двигатель

Колеса

Фары

Стекла

Автомобиль с про-

 

Автомобиль с тонированными

 

Автомобиль без фар

тив.тум.фарами

 

стеклами

 

 

 

 

 

 

 

Противотуманные фары

 

Стекла

 

 

 

 

 

 

 

 

 

 

 

 

Кузов

 

Кузов

 

Кузов

Двигатель

 

Двигатель

унаследованы

Двигатель

Колеса

унаследованы

Колеса

 

Колеса

Фары

 

Фары

 

Фары

Стекла

 

Стекла

 

//отсутствие поля

//дополнительное поле

//измененное поле

Стекла

Противотуманные фары

Стекла тонированные

Этот вариант отличия

 

 

 

 

не возможен

Рис.1

Специфические черты классу-потомку могут быть приданы двумя способами:

- Дополнение унаследованных от предка полей и методов новыми полями и методами. В результате потомок становится сложнее по структуре и поведению.

126

- Изменение унаследованных от предка полей и методов. В результате потомок не становится сложнее, меняется лишь способ реализации полей и методов, то есть имеет место отношение: то же самое, но сделано по-другому.

Механизм реализации:

-При определении класса-потомка указывается базовый класс: class ИмяКласса: ИмяБазовогоКласса;

-В классе определяются дополнительные поля и методы или переопределяются поля и методы базового класса.

С точки зрения технологии программирования наследование позволяет решить проблемы:

Повторное использование кода (создание новых классов на основе существующих)

Модификация существующего кода (изменение в базовом классе немедленно приводит к изменению в классах-потомках)

2.Наследование как средство усложнения базового класса

Реализуется путем определения в классе-потомке дополнительных

полей, методов и свойств. Класс-потомок будет иметь:

Унаследованные поля, методы и свойства

Дополнительные поля, методы и свойства

Конструкторы не наследуются, поэтому класс-потомок должен иметь собственный конструктор. При создании объекта класса-потомка конструкторы должны вызываться, начиная с базового класса. В начале инициализируются унаследованные поля, потом – специфические поля, как показано на Рис.2.

Базовый Потомок

Класс 1

 

Класс 2

Создать объект:

 

 

 

Конструктор базового класса

 

 

 

 

 

 

Конструктор потомка

 

 

 

 

Рис.2 Указанная очередность вызовов реализуется одним из способов:

1.Конструктор потомка не имеет вызова конструктора-предка. Автоматически вызывается конструктор предка без параметров.

2.Конструктор потомка явно вызывает конструктор предка.

Рис.3

127

Пример: определить базовый класс «Человек». Человек характеризуется фамилией и умением сообщать свою фамилию. Потомками класса «Человек» являются:

-класс «Владелец», дополнительно характеризующийся номером автомобиля и умением сообщать его

-класс “Служащий”, дополнительно характеризующийся названием фирмы и умением сообщать его.

-класс “Студент”, дополнительно характеризующийся названием ВУЗа

class Человек

{

protected string фам; public Человек(string фам)

{

this.фам = фам;

}

public void Показать()

{

Console.WriteLine("Я - человек: " + фам);

}

}

class Студент:Человек

{

private string вуз;

public Студент(string фам, string вуз):base(фам)

{

this.вуз = вуз;

}

}

class Владелец: Человек

{

private string ном;

public Владелец(string фам, string ном): base(фам)

{

this.ном = ном;

}

public void Инфо()

{

Console.WriteLine("Я - владелец: "+фам+" --> " + ном);

}

}

class Служащий: Человек

{

private string фирма;

public Служащий(string фам, string фирма): base(фам)

{

this.фирма = фирма;

}

128

public void Инфо()

{

Console.WriteLine("Я - служащий: "+фам + "____" + фирма);

}

}

class Program

{

static void Main(string[] args)

{

Студент ст = new Студент("Иванов","ВШЭ");

Владелец вл = new Владелец("Петров", "A777AA-99RUS"); Служащий сл = new Служащий("Сидоров", "Рога и копыта");

ст.Показать(); //Унаследованный метод //Я - человек: Иванов

вл.Показать(); //Унаследованный метод //Я - человек: Петров

сл.Инфо(); // Дополнительно определенный метод //Я - служащий: Сидоров ______ Рога и копыта

вл.Инфо(); //Дополнительно определенный метод

//Я - владелец: Петров --> A777AA-99RUS

}

}

Для работы с объектом-потомком могут быть использованы ссылки типа Предок и Потомок. Ссылке базового класса можно присвоить ссылку на класс-потомок. Ссылки типа Предок можно использовать только для доступа к унаследованным полям, методам и свойствам (предок ничего не знает о том, что «привнесли» потомки).

Рис.4

129

class Человек

{

protected string фам; public Человек(string фам)

{

this.фам = фам;

}

public void Показать()

{

Console.WriteLine("Я - человек: " + фам);

}

}

class Владелец: Человек

{

private string ном;

public Владелец(string фам, string ном): base(фам)

{

this.ном = ном;

}

public void Инфо()

{

Console.WriteLine("Я - владелец: "+фам+" --> " + ном);

}

}

class Program

{

static void Main(string[] args)

{

Человек ч;

Владелец вл = new Владелец("Петров", "A777AA-99RUS");

ч = вл; ч.Показать(); //Унаследованный метод //Я - человек: Петров

вл.Показать(); //Унаследованный метод //Я - человек: Петров

ч.Инфо();

//Ошибка

 

вл.Инфо();

//Дополнительно определенный метод

//Я - владелец: Петров

--> A777AA-99RUS

}

}

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

Наследование – это аналог производства изделия «с нуля». Базовый чертеж (класс) дополняется и полученный чертеж изделия (класснаследник) используется для изготовления изделия (объекта). На этапе

130

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]