Страница 147 из 502
Далее в классе RangeArray реализуется его индексатор, как показано ниже.
<b>// Это индексатор для класса RangeArray. </b>
<b>public int this[int index] {</b>
<b> // Это аксессор get. </b>
<b> get {</b>
<b> if(ok(index) ) {</b>
<b> Error = false;</b>
<b> return a[index - lowerBound];</b>
<b> } </b>
<b> else {</b>
<b> Error = true; </b>
<b> return 0;</b>
<b> }</b>
<b> }</b>
<b> // Это аксессор set. </b>
<b> set {</b>
<b> if(ok(index)) {</b>
<b> a[index - lowerBound] = value;</b>
<b> Error = false;</b>
<b> }</b>
<b> else </b>
<b> Error = true;</b>
<b> }</b>
<b>}</b>
Этот индексатор подобен тому, что использовался в классе FailSoftArray, за одним существенным исключением. Обратите внимание на следующее выражение, в котором индексируется массив а.
index - lowerBound
В этом выражении индекс, передаваемый в качестве параметра index, преобразуется в индекс с отсчетом от нуля, пригодный для индексирования массива а. Данное выражение действует при любом значении переменной lowerBound: положительном, отрицательном или нулевом.
Ниже приведен метод ok().
<b>// Возвратить логическое значение true, если </b>
<b>// индекс находится в установленных границах, </b>
<b>private bool ok(int index) {</b>
<b> if(index >= lowerBound & index <= upperBound) return true; </b>
<b> return false;</b>
<b>}</b>
Этот метод аналогичен использовавшемуся в классе FailSoftArray, за исключением того, что в нем контроль границ массива осуществляется по значениям переменных lowerBound и upperBound.
Класс RangeArray демонстрирует лишь одну разновидность специализированного массива, который может быть создан с помощью индексаторов и свойств. Существуют, конечно, и другие. Аналогичным образом можно, например, создать динамические массивы, которые расширяются или сужаются по мере надобности, ассоциативные и разреженные массивы. Попробуйте создать один из таких массивов в качестве упражнения.
ГЛАВА 11 Наследование
Наследование является одним из трех основополагающих принципов объектно-ориентированного программирования, поскольку оно допускает создание иерархических классификаций. Благодаря наследованию можно создать общий класс, в котором определяются характерные особенности, присущие множеству связанных элементов. От этого класса могут затем наследовать другие, более конкретные классы, добавляя в него свои индивидуальные особенности.
В языке C# класс, который наследуется, называется базовым, а класс, который наследует, — производным. Следовательно, производный класс представляет собой специализированный вариант базового класса. Он наследует все переменные, методы, свойства и индексаторы, определяемые в базовом классе, добавляя к ним свои собственные элементы.
Основы наследования
Поддержка наследования в C# состоит в том, что в объявление одного класса разрешается вводить другой класс. Для этого при объявлении производного класса указывается базовый класс. Рассмотрим для начала простой пример. Ниже приведен класс TwoDShape, содержащий ширину и высоту двухмерного объекта, например квадрата, прямоугольника, треугольника и т.д.
<b>// Класс для двумерных объектов, </b>
<b>class TwoDShape {</b>
<b> public double Width;</b>
<b> public double Height;</b>
<b> public void ShowDimO {</b>
<b> Console.WriteLine("Ширина и высота равны " +</b>
<b> Width + " и " + Height);</b>
<b> }</b>
<b>}</b>
Класс TwoDShape может стать базовым, т.е. отправной точкой для создания классов, описывающих конкретные типы двумерных объектов. Например, в приведенной ниже программе класс TwoDShape служит для порождения производного класса Triangle. Обратите особое внимание на объявление класса Triangle.
<b>// Пример простой иерархии классов, </b>
<b>using System;</b>
<b>// Класс для двумерных объектов. </b>
<b>class TwoDShape {</b>
<b> public double Width; </b>
<b> public double Height; </b>
<b> public void ShowDim() {</b>
<b> Console.WriteLine("Ширина и высота равны " +</b>