Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Медведев_С++_CLI_C#_Java_J#.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.17 Mб
Скачать

6.5Сокрытые переменные, функции и их использование

C#. В C# не разрешается использовать одноимённые переменные и функции в охватываемом и охватывающем блоках, а также в базовом и порождённом классах. Но при необходимости язык C# позволяет скрыть переменную или функцию в охватываемом блоке путём использования ключевого слова new (это не оператор new, применяемый при создании объектов в куче, а ключевое слово new) перед объявлением переменной или функции в порождённом классе. Если же скрытые переменная или функция понадобятся в порождённом классе, то к ним ссылаются с помощью ключевого слова base.

С++ и C++/CLI. В С++ и C++/CLI разрешается использовать одноимённые переменные и функции в охватываемом и охватывающем блоках, а также в базовом и порождённом классах - это разные переменные и функции с одинаковыми именами. Можно использовать их в базовом и порождённом классах, но для разрешения неоднозначности применить оператор привязки.

Пример 6.5.1 иллюстрирует применение сокрытых переменных и функций.

Пример 6.5.1. Сокрытые переменные и функции.

////////////////////

// C++/CLI

#include "stdafx.h"

using namespace System;

class CA // Базовый класс

{

public:

int x; // Открытая переменная x

int F() {return x*x;} // Возвратить x * x

};

class CB : public CA // Производный класс

{

public:

int x; // Открытая переменная x

int F() { return x + CA::x + CA::F();} // Вычислить и возвратить

void Set(int x) {CA::x= x; CB::x=10 * x;} // Установить значения

};

int main() // Главная статическая функция main()

{

// 6.5.1

CB *pCB= new CB; // Создать объект класса CB в куче

pCB -> Set (2); // Установить значения x в классах CA и СВ.

int m= pCB->F(); // Получить значениеСВ::х + CA::x + CA::F ( )

Console::WriteLine(m);

}

Результат:

26

////////////////////

//C#

using System;

class CA // Базовый класс

{

public int x; // Открытая переменная x

public int F() {return x * x;} // Вычислить и возвратить

}

class CB : CA // Производный класс

{

new public int x; // Открытая переменная x

new public int F ( ) { return x + base.x + base.F ();} // Возвратить

public void Set (int mx) {base.x= mx; x=10 * mx;} // Установить значения

}

class Program

{

static void Main(string[] args)

{

// 6.5.1

CB sCB= new CB(); // Создать объект класса CB в куче

sCB.Set(2); // Установить значения всех x

int m= sCB.F(); // Получить значение CB::x + CA: :x + CA::F ( )

Console.WriteLine(m);

}

}

Результат:

26

6.6Интерфейсы

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

Многие классы библиотеки .NET Framework и библиотек Java наследуют потребные интерфейсы. Интересно, что пользователь объекта может вызвать функции базового интерфейса не только обычным образом, воспользовавшись ссылкой или дескриптором к объекту, но, даже не зная тип (класс) объекта. Для этого достаточно воспользоваться так называемыми интерфейсными ссылками соответствующего базового интерфейса, который наследуется классом. Об интерфейсных ссылках будет рассказано позже. Не существует такого понятия, как объект интерфейса - хотя интерфейс описывается отдельно и схоже с описанием класса, используя, правда, ключевое слово interface или пару слов interface class при описании и включая только объявления функций, свойств и событий. Интерфейс - это средство, обязывающее некоторый класс реализовать объявленные в интерфейсе события, свойства и функции. Поскольку функции класса объекта определяют поведение этого объекта, то наследуемый интерфейс обязывает объект уточнить поведение, навязав объявленные в нём функции.

Как известно, ссылаясь к объекту по его ссылке, можно воспользоваться всеми открытыми данными, событиями и функциями его класса. Но если сослаться на интерфейсную ссылку объекта, то придётся ограничиться функциями, свойствами и событиями, объявленными только в интерфейсе. Это обстоятельство часто используется, когда требуется функциональность не всего объекта, а только его части, представленной интерфейсом.