Можно ли сдавать один и тот же тест несколько раз? |
C#. Механизмы наследования.Абстрактные классы. Интерфейсы
Интерфейсы
Определение интерфейса
В языке C# отсутствует множественное наследование: каждый класс может иметь только один непосредственный базовый класс. Частичной заменой множественному наследованию может служить использование интерфейсов.
Интерфейсы могут содержать свойства, методы и индексаторы, но без их реализации.
Один класс языка C# может наследовать несколько интерфейсов.
В C# интерфейс определяет новый ссылочный тип, содержащий объявления методов, которые обязательно должны быть реализованы в классе, наследующем данный интерфейс.
Можно сказать, что интерфейс определяет некоторую модель поведения, которая должна быть реализована в любом классе, наследующем данный интерфейс.
Объявление интерфейса может иметь следующее формальное описание:
[атрибуты] [модификаторы] interface имя_интерфейса [:список_базовых_интерфейсов] {тело_интерфейса}[;]
Например:
interface IMyInterface: IBase1, IBase2 { int M1(); int M2(); }
Если класс, наследующий интерфейс, не является абстрактным, то он обязательно должен реализовать методы, объявленные в интерфейсе. При наследовании интерфейса абстрактным классом методы, объявленные в интерфейсе, могут не иметь реализации только в том случае, если они объявляются с модификатором abstract.
Например:
public abstract class CMyInterface : IMyInterface { public CMyInterface() { // } public abstract int M1(); public abstract int M2(); } interface IMyInterface { int M1(); int M2(); }
Определение типа объекта
Для получения информации о том, является ли тип объекта времени выполнения совместимым с заданным типом, используется оператор is. Если типы совместимы, то оператор возвращает значение true.
Оператор as аналогичен оператору is, с той лишь разницей, что выполняет приведение в случае совместимости типов или устанавливает ссылку на несовместимый объект равной null.
Применение оператора is имеет следующее формальное описание:
выражение is тип
Например:
string str1 = myObjects; if (str1 is string) Console.WriteLine ("тип string");
Применение оператора as имеет следующее формальное описание:
выражение as тип
Например:
string str1 = myObjects as string; if (str1 != null) Console.WriteLine ( "это строка" );
При этом предыдущая форма записи эквивалентна следующей записи:
выражение as тип ? (тип)выражение : (тип)null
Приведение типа объекта к типу интерфейса
При создании объект сразу можно приводить к типу интерфейса, используя оператор as
Например:
Object ivar1 = varb1 as IA;
Если приведение допустимо, то переменная будет содержать ссылку на интерфейс. Если приведение типа объекта типу интерфейса недопустимо, то в результате приведения типа переменная примет значение null.
Следующий пример иллюстрирует определение типов объектов и приведение типа объекта к типу интерфейса.
using System; namespace MyAClass1 { class Class1 {[STAThread] // Класс // System.STAThreadAttribute, // определяющий однопотоковую модель static void Main(string[] args) { CB varb1 = new CB(); /* Запрос о совместимости типа объекта с типом наследуемого им интерфейса */ if (varb1 is IA) /* Если переменная типа CB является переменной типа класса, реализующего запрашиваемый интерфейс IA, то оператор is вернет значение true. */ {Console.WriteLine ("varb1 - это ссылка на класс, который реализует интерфейс IA");} // Создание объекта типа интерфейса IA IA ivar=(IA)varb1; if (ivar is IA) {Console.WriteLine ("ivar - это ссылка на интерфейс IA");} bool var1=ivar.F1(); Console.WriteLine("Вызов метода F1 интерфейса IA: {0}",var1); // Приведение объекта к типу интерфейса Object ivar1 = varb1 as IA; if (ivar1 != null) Console.WriteLine ( "ivar1 - это ссылка на интерфейс IA"); } } } using System; namespace MyAClass1 { public class CB : MyAClass1.CA,IA {public CB() { } public bool F1() { return true; } public int F2(int a) { return a*10; } } interface IA { bool F1();} } using System; namespace MyAClass1 { public abstract class CA { public CA() { } public abstract int F2(int a); } }Листинг 16.2.
Вложенные классы
Язык C# позволяет создавать вложенные классы. Вложенный класс объявляется как член другого класса.
Права доступа для вложенного класса могут быть или меньшими, или такими же, как у содержащего его класса. Так, вложенный класс не может быть общедоступным, если содержащий его класс объявлен как internal.
При доступе к имени вложенного класса из членов внешнего класса квалификация именем внешнего класса не требуется.
Например:
using System; namespace MyNClass1 {class Class1 { static void Main(string[] args) {Class1.Class2 var1= new Class1.Class2(); // Эквивалентно // записи: Class2 var1= new Class2(); //Вызов метода вложенного класса Console.WriteLine( var1.F1()); } class Class2 { private int a=12345; public int F1() {return this.a;} } } }