Интерфейсы - синтаксис, назначение, особенности

Интерфейс является «крайним случаем» абстрактного класса. В нем задается набор абстрактных методов, свойств и индексаторов, которые должны быть реализованы в производных классах. Иными словами, интерфейс определяет поведение,которое поддерживается реализующими этот интерфейс классами. Основная идеяиспользования интерфейса состоит в том, чтобы к объектам таких классов можнобыло обращаться одинаковым образом.

Каждый класс может определять элементы интерфейса по-своему. Так достигается полиморфизм: объекты разных классов по-разному реагируют на вызовыодного и того же метода.

Синтаксис интерфейса аналогичен синтаксису класса:

[ атрибуты ] [ спецификаторы ] interface иияинтерфейса [ : предки ]

тело_интерфейса [ : ]

Для интерфейса могут быть указаны спецификаторы new, public, protected, internal и private. Спецификатор new применяется для вложенных интерфейсов и имееттакой же смысл, как и соответствующий модификатор метода класса. Остальныеспецификаторы управляют видимостью интерфейса. В разных контекстах определенияинтерфейса допускаются разные спецификаторы. По умолчанию интерфейсдоступен только из сборки, в которой он описан (internal).

Интерфейс может наследовать свойства нескольких интерфейсов, в этом случае предки перечисляются через запятую. Тело интерфейса составляют абстрактныеметоды, шаблоны свойств и индексаторов, а также события.

Пример :

Interfae IExapmle

{

void Example();

int Function( int a);

int Property { get; }

}

Имя интерфейса всегда начинается с заглавной I . И понятно, что классы, которые унаследовали этот интерфейс должны полностью определять методы, которые в нем содержаться, при чем сигнатуры методов описанных в классе и в интерфейсе должны полностью совпадать.

Отличия интерфейса от абстрактного класса:

• элементы интерфейса по умолчанию имеют спецификатор доступа public и не могут иметь спецификаторов, заданных явным образом;

• интерфейс не может содержать полей и обычных методов — все элементы интерфейса должны быть абстрактными;

• класс, в списке предков которого задается интерфейс, должен определять все его элементы, в то время как потомок абстрактного класса может не переопределятьичасть абстрактных методов предка (в этом случае производный класс также будет абстрактным);

• класс может иметь в списке предков несколько интерфейсов, при этом они должен определять все их методы.

В списке предков класса сначала указывается его базовый класс, если он есть, а затем через запятую те интерфейсы, которые реализует этот класс Таким образом в С# поддерживается одиночное наследование для классов и множественное— для интерфейсов.Для реализуемых элементов интерфейса в классе следует указыватьспецификатор public.

Существует второй способ реализации интерфейса в классе: явное указание имени интерфейса перед реализуемым элементом. Спецификаторы доступа при этомне указываются. К таким элементам можно обращаться в программе только через объект типа интерфейса.

Class MyClass : IExample

{

Void IExample.Example();

}

IExample Ex = new MyClass();

Ex.Example();

//MyClassEx = newMyClass();

//Ex.Example(); error!!!!

***

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

бинарной операции is.

if ( объект is тип )

{

// выполнить преобразование "объекта" к "типу"

// выполнить действия с преобразованным объектом

}

***

Более эффективной является другая операция — as. Она выполняет преобразование к заданному типу, а если это невозможно, формирует результат null, например:

static void Act( object A )

{

IExampleEx= A as IExample;

if ( Ex != null ) Ex.Example();

}

10. Преобразование и приведение типов.

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

Если операнды разного типа и/или операция для этого типа не определена, перед вычислениями автоматически выполняется преобразование типа по правилам, обеспечивающим приведение более коротких типов к более длинным для сохранения значимости и точности. Автоматическое (неявное) преобразование возможно не всегда, а только если при этом не может случиться потеря значимости. Если неявного преобразования из одного типа в другой не существует, программист может задать явное преобразование типа с помощью операции (тип)х. Его результат остается на совести программиста.

!!!Арифметические операции не определены для более коротких, чем int, типов. Это означает, что если в выражении участвуют только величины типов sbyte, byte, short и ushort, перед выполнением операции они будут преобразованы в int. Таким образом, результат любой арифметической операции имеет тип не менее int

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

Интерфейсы - синтаксис, назначение, особенности - student2.ru

Преобразование более коротких, чем int, типов выполняется при присваивании. Обратите внимание на то, что неявного преобразования из float и double в decimal не существует.

Преобразование из типов int, uint и long в тип float и из типа long в тип double может вызвать потери точности, но не потери значимости. В процессе других вариантовнеявного преобразования никакая информация не теряется.

Наши рекомендации