Доступ к наследуемым элементам
Поля класса часто определяется как закрытые (со спецификатором 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);
}
}
Важно! Закрытый элемент класса недоступен для любого кода, определенного вне этого кода, в том числе и для производных классов.
Обеспечить доступ к элементам базового класса можно следующими способами:
-
С помощью спецификаторов доступа protected и public.
-
Через общедоступные методы-свойства базового класса.
Спецификаторы доступа 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
- Лабораторная работа 6 Тема: Наследование классов
- Базовые и производные классы
- Доступ к наследуемым элементам
- 8.1.2. Конструкторы классов и наследование
- 8.2. Виртуальные методы. Динамическое связывание
- 8.3. Абстрактные классы
- 8.4. Класс System.Object
- Главные методы объекта System.Object
- Контрольные вопросы и задания
- Варианты заданий