logo
lab_rab_6

Доступ к наследуемым элементам

Поля класса часто определяется как закрытые (со спецификатором private) для предотвращения их несанкционированного использования. Это в полной мере относится и к полям базового класса, поэтому методы производного класса не имеют доступа к полям базового, если они являются закрытыми, например не будет скомпилирован код, приведенный в листинге 8.1.

Листинг 8.1. Производный класс B не имеет доступа к приватному полю d базового класса A

class A

{

int d=5; // закрытое поле базового класса

}

class B : A

{

public void Print ()

{

// метод Print производного класса не имеет доступа к

// закрытому полю d базового класса

Console.WriteLine("значение унаследованного поля = {0}", d);

}

}

Важно! Закрытый элемент класса недоступен для любого кода, определенного вне этого кода, в том числе и для производных классов.

Обеспечить доступ к элементам базового класса можно следующими способами:

  1. С помощью спецификаторов доступа protected и public.

  2. Через общедоступные методы-свойства базового класса.

Спецификаторы доступа protected и public обеспечивают доступ из методов производного класса к элементам базового. Однако применение спецификатора public позволяет получить доступ к элементам базового класса любому классу, в том числе и не производному от него. Такое расширение прав доступа во многих случаях может оказаться не оправданным и даже недопустимым с точки зрения поддержки принципа инкапсуляции, поэтому в большинстве случаев используется спецификатор доступа protected. Элементы базового класса, объявленные как protected, доступны только методам базового и производным от него класса и не доступны никаким другим классам (листинг 8.2).

Листинг 8.2. Доступ из производного класса B к protected – элементу базового класса A

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

class A

{

protected int d=5; // объявление защищенного поля

}

class B : A

{

public void Print()

{

// защищенное поле d доступно в производном классе

Console.WriteLine("значение унаследованного поля = {0}", d);

}

}

class Program

{

static void Main(string[] args)

{

A obj = new A();

// ошибка! Класс Program не является производным от класса A, поэтому

// защищенное поле d не доступно методу Main класса Program

// этот код не будет скомпилирован

obj.d = 8;

}

}

}

Добавим в код базового класса, приведенного в листинге 8.1. общедоступные методы-свойства для доступа к его приватному полю d. Вызов этих методов-свойств возможен как в производном классе, так и в любом другом классе (листинг 8.3).

Листинг 8.3. Приватное поле d базового класса A доступно через его public-свойство D

using System;

using System.Collections.Generic;

using System.Text;

namespace ConsoleApplication1

{

class A

{

int d=5;

// определение public - свойства D в базовом классе

public int D

{

get

{ return d; }

}

}

class B : A

{

public void Print ()

{

// доступ из метода Print производного класса к закрытому полю d базового

// класса A через public - свойство D базового класса A

Console.WriteLine("значение унаследованного поля = {0}", D);

}

}

class Program

{

static void Main(string[] args)

{

// объект obj является локальным внутри метода Main

B obj = new B();

obj.Print();

// Доступ из метода Main класса Program

// к закрытому полю d класса A через public - свойство D класса A

Console.WriteLine("значение поля d в классе А = {0}", obj.D);

}

}

}

Эта программа выведет следующие строки:

Значение унаследованного поля = 5

Значение поля d в классе А =5