Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Вопрос 14 Потеря и восстановление информации о типе. Операторы is и as.

Читайте также:
  1. А. Сбор информации
  2. Аварийное восстановление
  3. Анализ входной информации предметной области и выделение информационных объектов
  4. Анализ геофизической информации.
  5. БЛОК 5. ЖУРНАЛИСТ И ИСТОЧНИК ИНФОМАЦИИ. Источник информации как объект нравственного отношения журналиста. Способы, методика сбора информации: нравственный аспект.
  6. В наш век потребительской культуры - главное не потерять свою духовную основу, развиваться и идти к Богу. 1 страница
  7. Ввод информации в ячейки. Автозаполнение ячеек. Раскрывающиеся списки

Если присвоить объект производного класса (Rectangle) переменной базового класса (Shape), как ниже:

Shape myShape = new Rectangle();

часть информации об объекте Rectangle будет утрачена. Теперь нельзя четко определить, относится ли myShape к типу Rectangle, или Triangle. Чтобы убедится в этом, добавим в класс Circle новую переменную. Даже если известно, что myShape содержит Circle, попытка обратиться к свой­ству Radius с помощью опера­тора:

myShape.Radius = 20.4; //Неверно

приведет к ошибке, поскольку в момент компиляции неизвестно, указывает ли myShape на объект типа Rectangle, Triangle или Circle.

Для примера создадим объект аналогичного класса:

Circle myCircle = new Circle();

myCircle.Radius = 5;

Console.WriteLine(myCircle.Radius);

В данном случае код будет верен, т.к. тип переменной экземпляра Circle myCircle совпадает с классом Circle.

В случае, когда мы вызываем метод следующим образом:

myShape = new Triangle();

myShape.DrawYouself();

Пока вызываются только те элементы класса Rectangle, которые определены и в Shape, ограничение в доступе не проявляется.

Упакуем созданные объекты в некий массив. Напоминаю, что массив должен содержать элементы одного типа, в данном случае типа Shape. Фрагмент кода имеет вид:

Shape[] ShapeCollection = new Shape[3];

ShapeCollection[0] = new Triangle();

ShapeCollection[1] = new Rectangle();

ShapeCollection[2] = new Circle();

 

for (int i = 0; i < ShapeCollection.Length; i++)

{

ShapeCollection[i].DrawYouself();

 

}

В программе черчения, например, реаль­ное содержимое элементов массива ShapeCollection типа Shape не требовалось, поскольку вы­зывался только метод DrawYotirself (посредством динамического связывания).

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

Стандартное обращение к переменной Radius не дает результата, поскольку элементы ShapeCollection принадлежат типу Shape и не поддер­живают обращения к Radius. Если бы можно было четко определить, что в элементе хра­нится объект типа Circle и затем преобразовать переменную к этому типу, можно было бы и обратиться к свойству Radius.

К счастью, С# следит за тем, на какой объект (и какого типа) указывает переменная в каждый момент времени. (Иначе не реализовать механизм динамического связыва­ния.) Для доступа к этой информации в программе применяются операции is и as, пред­ставленные далее. Операция is позволяет проверить, является ли переменная (например, myShape) ука­зателем на объект определенного типа (например, Circle). Результат ее — логичес­кое значение true или false. Чтобы проверить, содержит ли myShape объект Circle, используется логическое выражение:

myShape is Circle,

которое возвращает true, если myShape указывает на Circle, и false — в противном случае.

Если в myShape хранится Circle, эту переменную можно преобразовать к типу Circle и обратиться к свойству Radius. Для этого применяется операция приведения типа.

Оператор присваивания

Shape myShape = new Circle();

показывает, что объект класса Circle можно присвоить переменной myShape типа Shape. Это возможно, поскольку класс Circle — производный от класса Shape, т. е. все эле­менты класса, доступные в Shape, доступны и в Circle. Shape в иерархии выше, чем Circle, и такое присваивание требует восходящего приведения типа.

ыо не указано явно. В отличие с

Движение в противоположном направлении, с приведением переменной к типу, рас­положенному в иерархии ниже, называется нисходящим приведением типа. Нисходящее приведение создает некоторые трудности. Например, нельзя использовать оператор вида:

Circle myCircle = myShape;

поскольку myShape может также содержать Rectangleили Triangle, а эти классы могут и не иметь элементов, к которым можно обращаться через Circle. Тем не менее, если известно, что myShape фактически указывает на объект Circle, можно воспользовать­ся явным приведением типа:

Circle myCircle = (Circle)myShape;

Отсюда следует правило. Если объект класса А приводится к классу В, причем А — потомок В, это называется восходящим приведением. При этом не требуется явной операции приведения типа. Если же А — предок В, это называется нисходящим приведением. Нисходящее приведе­ние всегда требует явной операции (<Tип>).

Используя операцию is(позволяющую узнать, указывает ли переменная на объект определенного типа) и операцию нисходящего приведения типа, можно решить проблему с Circle и вычислить общую площадь объектов этого типа в массиве ShapeCollection.

 


Дата добавления: 2015-10-23; просмотров: 112 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Вопрос 13 Полиморфизм как концепция ООП.| Вопрос 29 Текстовые поля. Элемент управления Label и TextBox. Сравнительный анализ.

mybiblioteka.su - 2015-2024 год. (0.014 сек.)