Виртуальные и невиртуальные методы в C#. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Виртуальные и невиртуальные методы в C#.



Функция объявляется виртуальной в базовом классе с помощью модификатора virtual. Если для производного класса требуется переопределить свой вариант данной функции, то используется ключевое слово override. Синтаксической ошибкой является одновременное использование обоих модификаторов. Ошибкой является одновременное использование модификаторов new и override.

Public class Square

{protected int side=2;

Virtual public int Area();

{return side*side;}

Public void Print()

{Console.Writeline (“S={0}”, Area());}}

Public class Cube:Square

{override public int Area()

{return 6*side*side;}}}

Square S= new Square();

s.Print();

Cube c = new Cube();

c.Print();

Результат: s=4; s=4.

Если метод не виртуальный, будет вызван вариант метода, соотв. типу объявленной переменной. Либо типу объекта, к которому приводится данный. Если метод объявлен виртуальным и в потомках переопределен, то вызовется метод, соотв. типу созданного объекта.

+ Square s1 = new Square();

+ Square s2 = new Cube();

- Cube c1 = new Cube();

- Cube c2 = new Square();

Console.Writeline(…);

S1.Area() new (4); virtual/override(4)

S2.Area() new (4); virtual/override(24)

C1.Area() new (24); virtual/override(24)

(Square(c1)).Area(); new (4); virtual/override(24)


Приведение и проверка типов в C#.

 

Для проверки принадлежности объекта к какому-либо типу используется параметр is. Синтаксис записи следующий: <выражение> is <тип>. Результатом является либо true, либо false.

1) if (s1 is Cube)

Console.Writeline(“yes”);

else Console.Writeline(“no”); результат: “no”

2) if (s2 is Cube) результат: “yes”

3) if (s2 is Square) результат: “ yes

4) if (s2 is Square результат: “yes”

Приведение типов доступно в C#. Различают неявное (implicit) и явное (explicit) приведение типов (type-cast(ing)). Неявное приведение: автоматически:

Int i = 78;

Long l = I;

i неявно переводится к типу long, т.к. long охватывает большое число значений.

Явное приведение:

Long l = 45;

Int i = (int)l;

Т.к. int более короткий, чем long.

Class Overl

{Public void f(int I, long l) {}

Public void f(long l, int i) {}}

Overl O = new Overl();

Int i1=14, i2=24;

O.f(i1,i2); - ошибка

O.f((long)i1,i2); - 2-ой метод

O.f(i1,i2); - 1-ый метод

Для структурных типов – это единственный способ приведения. Этот же способ работает и для ссылочных типов. Для ссылочных типов существует еще один способ. Это использование оператора as.

C1 as Square = (Square) c1

Различия есть: 1) (Cube) s1; 2) s1 as Cube

(Cube)s1 – s1 не является объектом Cube. В первом случае возникает исключительная ситуация System.InvalidCasеException. Оператор as действует по другому: сначала выполняется проверка на соответствие типов, т.е. вызывается оператор is. Если тип преобразовать невозможно, исключение не возникает, а результатом будет нулевая ссылка null.


Абстрактные классы в C#.

Часто при анализе предметной области выясняется, что в классах, объединенной иерархией, можно выделить особенности, общие для всех классов. Например, машина – Audi, BMW, ВАЗ, Lexus. Для того, чтобы не реализовывать общие особенности для каждого класса в иерархии, это удобно сделать в базовом классе, а после пользоваться этой реализацией в производных классах. При этом может оказаться, что объекты базового класса не будут соответствовать никаким объектам или процессам реального мира. Если создан класс, объекты, которые не могут существовать, то такой класс д.б. описан абстрактно. С помощью ключевого слова abstract. Объекты абстрактного класса не могут быть созданы в программе. Ошибкой является одновременное использование abstract и sealed. Хотя объекты абстрактного класса не могут быть созданы, для них можно определить конструкторы. Класс м.б. объявлен абстрактно на любом уровне иерархии.

 

Классы могут быть объявлены абстрактными путем помещения ключевого слова abstract перед определением класса. Пример.

public abstract class A

{

// Class members here.

}

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

Абстрактные классы могут определять абстрактные методы. Для этого перед типом возвращаемого значения метода необходимо поместить ключевое слово abstract. Пример.

Язык C#

public abstract class A

{ public abstract void DoWork(int i);}

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

Язык C#

// compile with: /target:library

public class D

{

public virtual void DoWork(int i)

{

// Original implementation.

}

}

public abstract class E: D

{

public abstract override void DoWork(int i);

}

public class F: E

{

public override void DoWork(int i)

{

// New implementation.

}

}

Если метод virtual объявляется abstract, он все равно считается виртуальным по отношению к любому классу, наследующему от абстрактного класса. Класс, наследующий от абстрактного метода, не может получить доступ к исходной реализации метода — см. предыдущий пример, DoWork в классе F не может вызыватьDoWork в классе D. Таким образом абстрактный класс может принуждать производные классы предоставлять новые реализации метода для виртуальных методов.


Интерфейсы в С#.

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

Public interface IPlayer

{void Play();

Viod Stop();

Void Forward();

}

Интерфейс – ссылочный тип данных. В нем можно определить методы, свойства, индексаторы и события. Каждый компонент интерфейса является неявно абстрактным, модификатор доступа неявно public. Явно все это в интерфейсе не указывается. Имя интерфейса принято начинать с I. Для интерфейсов возможно наследование, синтаксис такой же, как для классов. Но в отличие от классов допустимо множественное наследование.

Public interface IBase1

{void MethodA();}

Public interface IBase2

{void MethodB();}

Public interface IMyInterface: Ibase1, IBase2

{void MethodC();}

От интерфейсов могут наследоваться структуры и классы. Класс, который наследует интерфейс, обязан наследовать все его методы. В реализации методов в классе не следует указывать модификатор override, в отличие от абстрактного класса, абстрактные методы, которые нужно перекрывать с использованием данного модификатора. О такой ситуации, когда класс наследует интерфейс и реализует все его методы, говорят, что класс поддерживает интерфейс. Один класс может наследоваться сразу от нескольких интерфейсов – единственный способ реализации множественного наследования. Класс может наследоваться и от другого класса и интерфейса или интерфейсов. В этом случае первым в списке указывают класс, а затем перечисляют интерфейсы. Порядок следования интерфейсов значения не имеет. Если класс поддерживает какой-либо интерфейс, то он должен поддерживать и все базовые интерфейсы данного. При наследовании класса наследование идет от последнего интерфейса в иерархии, но при этом реализуются и методы всех базовых интерфейсов.


Виды массивов в C#.

Массив – индексированный набор элементов одного типа. В С# индексация начинается с нуля и изменить это нельзя. Для реализации массивов в C# существует класс System.Array. Для него реализована встроенная поддержка.

Тип [] имя_переменной


Int [] a1 = new int [10];

Int [] a2 = {1,2,3};

Int [] a3 = new int[] {1,2,3,4};

Int [] a4 = new int [4] {1,2,3,4};


В первом случае создается массив из заданного количества элементов(10), инициализация значений по умолчанию. Следующие 3 способа абсолютно одинаковы. Массив задается определением его элементов явно. В любом случае длина массива задается при его создании, а не определении. Для указания длины массива обычно используются константы, но это м.б. и переменная или выражение, если не определяется значение его элементов. Возможно создание массивов структур, объектов, классов и интерфейсов. Если не инициализировать элементы массивов ссылочных типов, то каждый элемент будет содержать нулевую ссылку null. Место в куче под каждый элемент требуется выделять отдельно.

Class MyClass

MyClass [] ac = {new MuClass(), newMyClass, newMyClass(2)};

или


MyClass [] ac = new MyClas[3];

Ac [0] = newMyClass();

Ac[1] = newMyClass();

Ac[2]= newMyClass();


Прямоугольные массивы – это массивы с 2 и более измерениями.

Тип [,] имя

Тип [,,] имя

Int [,] aa5 = new int [3,4];

Int [,] aa6 = {{2,3},{4,5},{6,7}};

Int [,] aa7 = new int [3,2] {{2,3}, {4,5}, {6,7}};

Невыровненные массивы(jagged arrays)- массив массивовневыровненный потому, что сотавляющие его массивы могут иметь различную длину.

Тип [] имя

Int [] [] ja = new int [4] [];

Ja[0] = new int [2];

Ja[1] = new int [4];

Ja[2] = new int [3];

Обращение к неинициализированному элементу массива приводит к возникновению исключения System.NullReferenceExceprion.



Поделиться:


Последнее изменение этой страницы: 2016-08-15; просмотров: 579; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.135.183.187 (0.02 с.)