Московский государственный университет имени М.В.Ломоносова
Опубликован: 01.11.2004 | Доступ: свободный | Студентов: 11275 / 456 | Оценка: 4.12 / 4.01 | Длительность: 19:20:00
ISBN: 978-5-9556-0077-9
Специальности: Программист
Лекция 16:

C#. Механизмы наследования.Абстрактные классы. Интерфейсы

< Лекция 15 || Лекция 16: 12 || Лекция 17 >

Интерфейсы

Определение интерфейса

В языке 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;}   
  }    
}    
}
< Лекция 15 || Лекция 16: 12 || Лекция 17 >
Александр Демьяненко
Александр Демьяненко

Можно ли сдавать один и тот же тест несколько раз?
Или же один и тот же тест можно сдать лишь однажды?

Максим Стогний
Максим Стогний

Добрый день!

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

тип_метода (имя_класса::*имя_метода_указателя)
    (список параметров);
тип_функции (*имя_ функции_указателя)
    (список параметров);

при этом можно было  тип_функции во втором описании заменить на тип_метода? Т.е.:

тип_метода (*имя_ метода_указателя)
    (список параметров);