Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретический_курс.doc
Скачиваний:
36
Добавлен:
10.11.2019
Размер:
7.68 Mб
Скачать

4.3.2. Защищенный доступ и исключение наследования Защищенный доступ и исключение наследования

1. Организация защищенного доступа

Открытый член базового класса недоступен для производного класса. Из этого можно предположить, что для доступа к некоторому члену базового класса из производного класса этот член необходимо сделать открытым. Но если сделать член класса открытым, то он станет доступным для всего кода, что далеко не всегда желательно. Правда, упомянутое предположение верно лишь отчасти, поскольку в С# допускается создание защищенного члена класса. Защищенный член является открытым в пределах иерархии классов, но закрытым за пределами этой иерархии.

Защищённый член создается с помощью модификатора доступа protected. Если член класса объявляется как protected, он становится закрытым, но за исключением одного случая, когда защищённый член наследуется. В этом случае защищенный член базового класса становится защищенным членом производного класса, а значит, доступным для производного класса. Таким образом, используя модификатор доступа protected, можно создать члены класса, являющиеся закрытыми для своего класса, но все же наследуемыми и доступными для производного класса:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LC_Console

{

class MyClass

{

// Члены закрытые для класса Program

// но открытые для класса ClassA

protected int x, y, z;

}

class ClassA : MyClass

{

public ClassA(int x, int y, int z)

{

this.x = x;

this.y = y;

this.z = z;

}

// Данный метод использует защищенные члены класса MyClass

public double LongVector()

{

return Math.Sqrt(x * x + y * y + z * z);

}

}

class Program

{

static void Main()

{

ClassA obj = new ClassA(x: 12, y: 5, z: 6);

Console.WriteLine("Длина вектора равна: {0:#.##}", obj.LongVector());

Console.WriteLine("Для продолжения нажмите любую клавишу . . .");

Console.ReadKey();

}

}

}

Рис. 1. 1. Результат работы кода выше

В данном примере класс MyClass наследуется классом ClassA, а его члены x, y и z объявлены как protected, и поэтому они доступны для метода LongVector. Если бы члены x, y и z класса MyClass были объявлены как private, то они оказались бы недоступными для класса ClassA, и приведенный выше код нельзя было бы скомпилировать.

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

Хотя protected-поля данных могут нарушить инкапсуляцию, объявлять protected-методы достаточно безопасно (и полезно). При построении иерархий классов очень часто приходится определять набор методов, которые используются только производными типами.

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