
- •[Атрибуты][модификаторы]struct имя_структуры [:список_интерфейсов] {тело_структуры}
- •Классы в c# [атрибуты][модификаторы]class имя_класса [:список_родителей] {тело_класса}
- •Индексаторы
- •Статические поля и методы класса
- •Наследование
- •Интерфейсы
- •Две стратегии реализации интерфейса
- •Преобразование к классу интерфейса
- •Проблемы множественного наследования
- •Коллизия имен
- •Ip1.Prop1("интерфейс iProps: свойство 1");
- •Ip1.Prop2("интерфейс 1 ", 88);
- •Ip2.Prop1("интерфейс iPropsOne: свойство1");
- •2. Наследование от общего предка
- •Обработка исключительных ситуаций
- •Блок finally
- •Завдання до лабораторної роботи
Ip2.Prop1("интерфейс iPropsOne: свойство1");
ip2.Prop2(7777);
ip2.Prop3();
}
2. Наследование от общего предка
Для интерфейсов ситуация дублирующего наследования маловероятна, но возможна, поскольку интерфейс, как и любой класс, может быть наследником другого интерфейса. Поскольку у интерфейсов наследуются только сигнатуры, а не реализации, как в случае классов, то проблема дублирующего наследования сводится к проблеме коллизии имен. По-видимому, естественным решением этой проблемы в данной ситуации является склеивание, когда методам, пришедшим разными путями от одного родителя, будет соответствовать единая реализация.
// Программа 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, создающее новый объект. Если исключение выбрасывается операционной системой, то она сама классифицирует исключение, создает объект соответствующего класса и автоматически заполняет его поля.