Для интерфейсов ситуация дублирующего наследования маловероятна, но возможна, поскольку интерфейс, как и любой класс, может быть наследником другого интерфейса. Поскольку у интерфейсов наследуются только сигнатуры, а не реализации, как в случае классов, то проблема дублирующего наследования сводится к проблеме коллизии имен. По-видимому, естественным решением этой проблемы в данной ситуации является склеивание, когда методам, пришедшим разными путями от одного родителя, будет соответствовать единая реализация.
// Программа 6.
public interface IParent{
void ParentMethod();
}
public interface ISon1:IParent{
void Son1Method();
}
public interface ISon2:IParent{
void Son2Method();
}
public class Pars:ISon1, ISon2{
public void ParentMethod() {
Console.WriteLine("Это метод родителя!");
}
public void Son1Method() {
Console.WriteLine("Это метод старшего сына!");
}
public void Son2Method() {
Console.WriteLine("Это метод младшего сына!");
}
}
Класс обязан реализовать метод ParentMethod, приходящий от обоих интерфейсов. Понимая, что речь идет о дублировании метода общего родителя - интерфейса IParent, лучшей стратегией реализации является склеивание методов в одной реализации, что и было сделано. Приведу тестирующую процедуру, где создается объект класса и три объекта интерфейсных классов, каждый из которых может вызывать только методы своего интерфейса:
public void TestIParsons(){
Console.WriteLine("Объект класса вызывает методы трех интерфейсов!");
Pars ct = new Pars();
ct.ParentMethod();
ct.Son1Method();
ct.Son2Method();
Console.WriteLine("Интерфейсный объект 1 вызывает свои методы!");
IParent ip = (IParent)ct;
ip.ParentMethod();
Console.WriteLine("Интерфейсный объект 2 вызывает свои методы!");
ISon1 ip1 = (ISon1)ct;
ip1.ParentMethod();
ip1.Son1Method();
Console.WriteLine("Интерфейсный объект 3 вызывает свои методы!");
ISon2 ip2 = (ISon2)ct;
ip2.ParentMethod();
ip2.Son2Method();
}
Обработка исключительных ситуаций
Какой бы надежный код ни был написан, сколь бы тщательной ни была отладка при запусках будут встречаться нарушения спецификаций. В таких исключительных ситуациях продолжение выполнения программы либо становится невозможным, либо в возникшей ситуации применение алгоритма приведет к ошибочным результатам. Что делать при возникновении исключительной ситуации?
Язык C# наследовал схему исключений языка С++, внеся в нее свои коррективы. Рассмотрим схему подробнее и начнем с синтаксиса конструкции try-catch-finally:
try {...}
catch (T1 e1) {...}
...
catch(Tk ek) {...}
finally {...}
Всюду в тексте модуля, где синтаксически допускается использование блока, этот блок можно сделать охраняемым, добавив ключевое слово try. Вслед за try-блоком могут следовать catch -блоки, называемые блоками-обработчиками исключительных ситуаций, их может быть несколько, они могут и отсутствовать. Завершает эту последовательность finally-блок - блок финализации, который также может отсутствовать. Вся эта конструкция может быть вложенной - в состав try-блока может входить конструкция try-catch-finally.
throw [выражение] - задает объект класса, являющегося наследником класса Exception. Обычно это выражение new, создающее новый объект. Если исключение выбрасывается операционной системой, то она сама классифицирует исключение, создает объект соответствующего класса и автоматически заполняет его поля.
Блок finally
В блоке try могли быть заняты ресурсы - открыты файлы, захвачены некоторые устройства. Освобождение ресурсов, занятых try-блоком, выполняет finally-блок. Если он присутствует, он выполняется всегда, сразу же после завершения работы try-блока, как бы последний ни завершился.
Задания к лабораторной работе
1. Проработать примеры 1-6, данные в теоретических сведениях. Создать на их основе программы. Получить результаты работы программ и уметь их объяснить. Внести их в отчет с комментариями.
2. Для предложенной структуры данных разработать абстрактный класс и класс наследник. В классе реализовать несколько конструкторов. Создать методы, работающие с полями класса. Часть из них должны быть виртуальными. Добавить методы-свойства и индексаторы.
3. Разработать интерфейсные классы, добавляющие некоторые методы работы с объектами класса. Изучить причины возникновения коллизии имен и способы устранения.
4. Разработать классы исключительных ситуаций и применить их для обработки, возникающих исключений.
5. Написать демонстрационную программу.
Описания компонентных данных пользовательских классов:
1. СТУДЕНТ: ФИО, курс, пол, оценки.
2. СЛУЖАЩИЙ: имя, возраст, рабочий стаж, должности.
3. КАДРЫ: ФИО, номер цеха, разряд, специальности.
4. ИЗДЕЛИЕ: название, шифр, количество, комплектация.
5. ПЕЧАТНОЕ ИЗДАНИЕ: название, ФИО автора, стоимость, оглавление.
6. ЭКЗАМЕН: ФИО студента, дата, оценка, перечень вопросов.
7. АДРЕС: город, улица, номер дома, список жильцов.
8. ТОВАР: название, артикул, стоимость, даты (изготовление, срок реализации)
9. ЦЕХ: название, начальник, кол-во рабочих, перечень номенклатуры выпускаемых изделий.
10. ПЕРСОНА: ФИО, возраст, пол, список увлечений.
11. АВТОМОБИЛЬ: марка, мощность, стоимость, даты ремонта.
12. СТРАНА: название, форма правления, площадь, список областей.
13. ЖИВОТНОЕ: вид, класс, средний вес, места обитания.
14. КОРАБЛЬ: название, водоизмещение, тип, список категорий кают.
15. КАРТИНА: ФИО автора, название, жанр, список владельцев.
16. МУЗЕЙ: Название, адрес, ФИО директора, кол-во и названия залов.
17. КНИГА: Название, жанр, кол-во страниц, список авторов.
18. САМОЛЕТ: ФИО конструктора, марка, год выпуска, кол-во мест, список городов рейса.
Вопросы к защите лабораторной работы
1. К какой группе типов переменных относятся перечисления и структуры?
2. Описание перечисления и его назначение?
3. Числовые значения констант перечисления по умолчанию?
4. Использование перечислений в программах.
5. Описание структуры.
6. Роль конструктора в структуре?
7. Обращение к элементам структуры.
8. Упаковка и распаковка структуры.
9. Что такое класс? Для чего описываются классы?
10. Чем отличается класс от структуры?
11. Модификаторы доступа к полям и методам класса.
12. Модификаторы доступа к классам.
13. Что такое экземпляр класса? Как он создается в C#?
14. Для чего в классе определяется конструктор? Сколько может быть конструкторов в классе? Когда вызывается конструктор?
15. Как можно обратиться к полям и методам класса?
16. Методы-свойства класса. Назначение и описание.
17. Статические поля и методы класса. Назначение, описание и вызов статических методов.
18. Индексаторы. Назначение и описание.
19. Наследование в С#.
20. Изменение методов родителя в классе наследника.
21. Конструкторы при наследовании.
22. Описание абстрактных методов и классов.
23. Вложенные классы.
24. Интерфейсы. Назначение и описание.
25. Наследование в интерфейсах.
26. Реализация методов интерфейсов в классах.
27. Коллизия имен в интерфейсах.
28. Исключения. Обработка исключений в С#.
29. Создание классов исключений и генерация исключения.