Рейтинговые книги
Читем онлайн C# 4.0: полное руководство - Герберт Шилдт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 82 83 84 85 86 87 88 89 90 ... 294

Далее в классе RangeArray реализуется его индексатор, как показано ниже.

// Это индексатор для класса RangeArray.

public int this[int index] {

  // Это аксессор get.

  get {

    if(ok(index) ) {

      Error = false;

      return a[index - lowerBound];

    }

    else {

      Error = true;

      return 0;

    }

  }

  // Это аксессор set.

  set {

    if(ok(index)) {

      a[index - lowerBound] = value;

      Error = false;

    }

    else

      Error = true;

  }

}

Этот индексатор подобен тому, что использовался в классе FailSoftArray, за одним существенным исключением. Обратите внимание на следующее выражение, в котором индексируется массив а.

index - lowerBound

В этом выражении индекс, передаваемый в качестве параметра index, преобразуется в индекс с отсчетом от нуля, пригодный для индексирования массива а. Данное выражение действует при любом значении переменной lowerBound: положительном, отрицательном или нулевом.

Ниже приведен метод ok().

// Возвратить логическое значение true, если

// индекс находится в установленных границах,

private bool ok(int index) {

  if(index >= lowerBound & index <= upperBound) return true;

  return false;

}

Этот метод аналогичен использовавшемуся в классе FailSoftArray, за исключением того, что в нем контроль границ массива осуществляется по значениям переменных lowerBound и upperBound.

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

ГЛАВА 11 Наследование

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

В языке C# класс, который наследуется, называется базовым, а класс, который наследует, — производным. Следовательно, производный класс представляет собой специализированный вариант базового класса. Он наследует все переменные, методы, свойства и индексаторы, определяемые в базовом классе, добавляя к ним свои собственные элементы.

Основы наследования

Поддержка наследования в C# состоит в том, что в объявление одного класса разрешается вводить другой класс. Для этого при объявлении производного класса указывается базовый класс. Рассмотрим для начала простой пример. Ниже приведен класс TwoDShape, содержащий ширину и высоту двухмерного объекта, например квадрата, прямоугольника, треугольника и т.д.

// Класс для двумерных объектов,

class TwoDShape {

  public double Width;

  public double Height;

  public void ShowDimO {

    Console.WriteLine("Ширина и высота равны " +

          Width + " и " + Height);

  }

}

Класс TwoDShape может стать базовым, т.е. отправной точкой для создания классов, описывающих конкретные типы двумерных объектов. Например, в приведенной ниже программе класс TwoDShape служит для порождения производного класса Triangle. Обратите особое внимание на объявление класса Triangle.

// Пример простой иерархии классов,

using System;

// Класс для двумерных объектов.

class TwoDShape {

  public double Width;

  public double Height;

  public void ShowDim() {

    Console.WriteLine("Ширина и высота равны " +

            Width + " и " + Height);

  }

}

// Класс Triangle, производный от класса TwoDShape.

class Triangle : TwoDShape {

  public string Style; // тип треугольника

  // Возвратить площадь треугольника,

  public double Area() {

    return Width * Height / 2;

  }

  // Показать тип треугольника,

  public void ShowStyle() {

    Console.WriteLine("Треугольник " + Style);

  }

}

class Shapes {

  static void Main() {

    Triangle t1 = new Triangle();

    Triangle t2 = new Triangle();

    t1.Width = 4.0;

    t1.Height = 4.0;

    t1.Style = "равнобедренный";

    t2.Width = 8.0;

    t2.Height = 12.0;

    t2.Style = "прямоугольный";

    Console.WriteLine("Сведения об объекте t1: ");

    t1.ShowStyle(); 

    t1.ShowDim();

    Console.WriteLine ("Площадь равна " + t1.Area());

    Console.WriteLine();

    Console.WriteLine("Сведения об объекте t2: ");

    t2.ShowStyle();

    t2.ShowDim();

    Console.WriteLine("Площадь равна " + t2.Area());

  }

}

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

Сведения об объекте t1:

Треугольник равнобедренный

Ширина и высота равны 4 и 4

Площадь равна 8

Сведения об объекте t2:

Треугольник прямоугольный

Ширина и высота равны 8 и 12

Площадь равна 48

В классе Triangle создается особый тип объекта класса TwoDShape (в данном случае — треугольник). Кроме того, в класс Triangle входят все члены класса TwoDShape, к которым, в частности, добавляются методы Area() и ShowStyle(). Так, описание типа треугольника сохраняется в переменной Style, метод Area() рассчитывает и возвращает площадь треугольника, а метод ShowStyle() отображает тип треугольника.

Обратите внимание на синтаксис, используемый в классе Triangle для наследования класса TwoDShape.

class Triangle : TwoDShape {

Этот синтаксис может быть обобщен. Всякий раз, когда один класс наследует от другого, после имени базового класса указывается имя производного класса, отделяемое двоеточием. В C# синтаксис наследования класса удивительно прост и удобен в использовании.

В класс Triangle входят все члены его базового класса TwoDShape, и поэтому в нем переменные Width и Height доступны для метода Area(). Кроме того, объекты t1 и t2 в методе Main() могут обращаться непосредственно к переменным Width и Height, как будто они являются членами класса Triangle. На рис. 11.1 схематически показано, каким образом класс TwoDShape вводится в класс Triangle.

Рис. 11.1. Схематическое представление класса Triangle

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

TwoDShape shape = new TwoDShape();

1 ... 82 83 84 85 86 87 88 89 90 ... 294
На этой странице вы можете бесплатно читать книгу C# 4.0: полное руководство - Герберт Шилдт бесплатно.
Похожие на C# 4.0: полное руководство - Герберт Шилдт книги

Оставить комментарий