1629295407-c61bfe4caba98380ea3e7cdae6295416 (846200), страница 51
Текст из файла (страница 51)
Язык C#// Метод возвращает площадь треугольника.public double area() {return width * height / 2;}}// Отображаем тип треугольника.public void showStyle() {Console.WriteLine("Треугольник " + style);}class Shapes {public 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и, кроме того, поле style, метод area() и метод showStyle(). В переменной styleхранится описание типа треугольника, метод area() вычисляет и возвращает его площадь,а метод showStyle() отображает данные о типе треугольника.Ниже приведен синтаксис, который используется в объявлении класса Triangle,чтобы сделать его производным от класса TwoDShape.class Triangle : TwoDShape {Глава 11. Наследование279Этот синтаксис можно обобщить.
Если один класс наследует другой, то имя базовогокласса указывается после имени производного, причем имена классов разделяютсядвоеточием. В C# синтаксис наследования класса очень прост для запоминания ииспользования.Поскольку класс Triangle включает все члены базового класса, TwoDShape, онможет обращаться к членам width и height внутри метода area(). Кроме того, внутриметода Main() объекты t1 и t2 могут прямо ссылаться на члены width и height, какесли бы они были частью класса Triangle.
Включение класса TwoDShape в классTriangle схематически показано на рис. 11.1.widthTwoDShapeheightshowDim()styleTriangleareashowStyle()Рис. 11.1. Схематическое представление класса TriangleНесмотря на то что класс TwoDShape является базовым для класса Triangle, этосовершенно независимый и автономный класс.
То, что его использует в качестве базовогопроизводный класс (классы), не означает невозможность использования его самого.Например, следующий фрагмент кода абсолютно легален:TwoDShape shape = new TwoDShape();shape.width = 10;shape.height = 20;shape.showDim();Безусловно, объект класса TwoDShape “ничего не знает” и не имеет права доступа кклассу, производному от TwoDShape.Общая форма объявления класса, который наследует базовый класс, имеет такой вид:class имя_производного_класса : имя_базового_класса {// тело класса}Для создаваемого производного класса можно указать только один базовый класс. ВC# (в отличие от C++) не поддерживается наследование нескольких базовых классов водном производном классе.
Этот факт необходимо учитывать при переводе C++-кода на C#.Однако можно создать иерархию наследования, в которой один производный классстановится базовым для другого производного класса. И конечно же, ни один класс неможет быть базовым (ни прямо, ни косвенно) для самого себя.Основное достоинство наследования состоит в том, что, создав базовый класс,который определяет общие атрибуты для множества объектов, его можно использовать длясоздания любого числа более специализированных производных классов.
В каждомпроизводном классе можно затем точно “настроить” собственную классификацию. Вот,например, как из базового класса TwoDShape можно вывести производный класс, которыйинкапсулирует прямоугольники:280Часть I. Язык C#// Класс прямоугольников Rectangle, производный//от класса TwoDShape.class Rectangle : TwoDShape {// Метод возвращает значение true, если// прямоугольник является квадратом.public bool isSquare() {if(width == height) return true;return false;}}// Метод возвращает значение площади прямоугольника.public double area() {return width * height;}Класс Rectangle включает класс TwoDShape и добавляет метод isSquare(),который определяет, является ли прямоугольник квадратом, и метод area(),вычисляющий площадь прямоугольника.Доступ к членам класса и наследованиеКак разъяснялось в главе 8, члены класса часто объявляются закрытыми, чтобыпредотвратить несанкционированное использование и внесение изменений. Наследованиекласса не отменяет ограничения, связанные с закрытым доступом.
Таким образом, несмотряна то, что производный класс включает все члены базового класса, он не может получитьдоступ к тем из них, которые объявлены закрытыми. Например, как показано в следующемкоде, если члены width и height являются private-членами в классе TwoDShape, токласс Triangle не сможет получить к ним доступ,// Доступ к закрытым членам не наследуется.// Этот пример не скомпилируется.using System;// Класс двумерных объектов.class TwoDShape {double width; // Теперь это private-член.double height; // Теперь это private-член.public void showDim() {Console.WriteLine("Ширина и высота равны " +width + " и " + height);}}// Класс Triangle выводится из класса TwoDShape.class Triangle : TwoDShape {public string style; // Тип треугольника.// Метод возвращает значение площади треугольника.public double area() {return width * height /2;}Глава 11. Наследование// Ошибка, нельзя получить// прямой доступ к закрытым// членам.281// Отображаем тип треугольника.public void showStyle() {Console.WriteLine("Треугольник " + style);}}Класс Triangle не скомпилируется, поскольку ссылка на члены width и heightвнутри метода area() вызовет ошибку нарушения прав доступа.
Поскольку width иheight — закрытые члены, они доступны только для членов их собственного класса. Напроизводные классы эта доступность не распространяется.СоветЗакрытый член класса остается закрытым в рамках этого класса. К немунельзя получить доступ из кода, определенного вне этого класса, включаяпроизводные классы.На первый взгляд может показаться, что невозможность доступа к закрытым членамбазового класса со стороны производного — серьезное ограничение. Однако это не так,поскольку в C# предусмотрены возможности решения этой проблемы. Одна из них —protected-члены, о которых пойдет речь в следующем разделе. Вторая возможность —использование открытых свойств и методов, позволяющих получить доступ к закрытымданным.
Как было показано в предыдущих главах, C#-программисты обычнопредоставляют доступ к закрытым членам класса посредством открытых методов или путемпревращения их в свойства. Перед вами — новая версия класса TwoDShape, в которомбывшие члены width и height стали свойствами.// Использование свойств для записи и чтения закрытых// членов класса.using System;// Класс двумерных объектов.class TwoDShape {double pri_width; // Теперь это private-член.double pri_height; // Теперь это private-член.// Свойства width и height.public double width {get { return pri_width; }set { pri_width = value; }}public double height {get { return pri_height; }set { pri_height = value; }}}public void showDim() {Console.WriteLine("Ширина и высота равны " +width + " и " + height);}// Класс треугольников - производный от класса TwoDShape.class Triangle : TwoDShape {public string style; // Тип треугольника.// Метод возвращает значение площади треугольника.public double area() {return width * height / 2;282Часть I.
Язык C#}}// Отображаем тип треугольника.public void showStyle() {Console.WriteLine("Треугольник " + style);}class Shapes2 {public 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());Базовый и производный классы иногда называют суперклассом и подклассом. Этитермины пришли из программирования на языке Java. Суперкласс в Java — это базовыйкласс в C#. Подкласс в Java — это производный класс в C#.