Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Н.Р. Бухараев (3 семестр)(ООП в интегрированной...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.41 Mб
Скачать

И нкапсуляция данных

Инкапсуляция - кибернетика – функциональное описание систем, слишком сложных для классического анализа.

В этом понятии скрыта идея чёрного и серого ящиков. Строение интересует настолько, насколько оно определяет поведение. Это нужно для того, чтобы скрыть сложность реализации.

Принцип инкапсуляции не является программистским, а является общеметодическим (функциональным, бихевиористским). Его сформулировал Норберт Винер.

Идея инкапсуляции - идея явного разделения логики и реализации с целью сокрытия сложности не нова в программировании:

  1. языки высокого уровня скрывают идеи реализации той машинной программы, в которой они транслируются (такие как Фортран, Кобол, Алгол, Pascal, Java, C, C++, C#, Objective C, Smalltalk, Delphi и т.д.)

  2. пользовательские процедуры и функции скрывают детали алгоритма определения функции от самой функции

  3. любое наименование скрывает детали алгоритма

  4. в модульном программировании это определяется так:

Implementation (private)- относится к функциям (операторам)- не является доступной пользователю

Interface (public )-доступный пользователю


э то старая идея локализации

Таким образом, идея локализации в объектно – ориентированном программировании приобретает ОТНОСИТЕЛЬНЫЙ СМЫСЛ: не только что прятать, но и от кого прятать.

Для реализации ограничения доступа применяются модификаторы доступа- PUBLIC, PRIVATE, PROTECTED, INTERNAL.

-public- расширяет область видимости (можно обращаться из любого места программы)

-private- обеспечивает самую жёсткую локализацию, ограничивая доступ (область видимости) пределами описания данного класса (т.е. пользователь не видит private- полей и методов, а обращение к этим полям является синтаксической ошибкой)

-protected- виден классам-наследникам. Это даёт возможность скрыть от наследников переменную так, чтобы они не «напортачили» в ней.

-internal- модификатор доступа, который используется для методов, доступных всем классам, определённым в конкретной сборке

Public и private нужны для разделения логики и реализации (сокрытие реализации) - идея «чёрного ящика»

Организация памяти:

Процедуры и функции хранятся в памяти и именуются точно также как данные (т.е. явное пользовательское именование в языках высокого уровня, а адреса на нижнем уровне).

//Пример: Описать класс РАЦИОНАЛЬНЫЕ ЧИСЛА.

using System; //стандартная библиотека - ввод-вывод, базовые классы

namespace Fraction //логически связанное определение имён (Пространства имён (namespace) предоставляют возможность логической взаимосвязи классов и других типов.)

{

class tRational

{//поля - см. далее Сокрытие данных (set,get- подход)

public Int32 numerator; //числитель

public Int32 denominator;// знаменатель

//не в нормализованном виде, если нужно, то напиши метод

//методы:

//консольный ввод и вывод

private Int32 ReadInt(string s)

{

Console.WriteLine(s); //выводим на консоль информацию, которая содержалась в s

string input = Console.ReadLine(); // нет параметров, т.к. системный оператор

return Int32.Parse(input); // преобразование типов (читается строковое, а преобразуется в int)

}

public void read(string s)

{

Console.WriteLine(s);

numerator = ReadInt("Числитель: ");

denominator = ReadInt("Знаменатель: ");

}

private void WriteInt(string s, Int32 x)

{

Console.WriteLine(s);

Console.WriteLine(x.ToString()); //возвращает строку, представляющую текущий объект.

}

public void write(string s)

{

Console.WriteLine(s);

WriteInt("Числитель:", numerator);

WriteInt("Знаменатель:", denominator);

Console.ReadKey(); //задержка - получает следующий нажатый пользователем символ или функциональную клавишу. Нажатая клавиша отображается в окне консоли.

}

public void assign(tRational a)//присваивание значений- "клонирование"

{

this.numerator = a.numerator;

this.denominator = a.denominator;

}

public void add(tRational a) //добавить к this

{

this.numerator = this.numerator * a.denominator + a.numerator * this.denominator;

this.denominator = a.denominator * this.numerator;

}

public void subtract(tRational a) //вычесть из this

{

this.numerator = this.numerator * a.denominator - a.numerator * this.denominator;

this.denominator = a.denominator * this.numerator;

}

public void multiply(tRational a) //домножить

{

this.numerator = this.numerator * a.numerator;

this.denominator = a.denominator * this.denominator;

}

public void divide(tRational a)//поделить

{

this.numerator = this.numerator * a.denominator;

this.denominator = this.denominator * a.numerator;

}

} //tRational

class Program

{//программа-запускалка

//метод:

static void main()

{

//сложение двух дробей y<--y+x

tRational y, x; //указатели (объявление)

x = new tRational(); // вызов конструктора (выделение памяти)

y = new tRational();

y.read("Введите первое слагаемое:");

x.read("Введите второе слагаемое:");

y.add(x);

y.write("Сумма равна:");

}

}// Program

}// Fraction

Теперь возникает проблема сокрытия реализации данных.

Set-get подход

Set-get подход- управление доступом к полю объекта- семантика присваивания.

Set-get подход разделяет фактическое хранение данных и пользовательское представление о данных, возвращает к вопросу: «Что такое данные? »

Разделение логических и физических данных знакомо по СУБД (view).

С точки зрения процедурного программирования, состояние- это значения переменных, а объектного - несколько иное. К примеру, работаем с декартовыми координатами, а пользователю представляем как полярные.

Идея пользовательского представления данных отражается в виде set-get- подхода, которые подразумевает виртуальные (пользовательские) поля.

Тем самым гарантируется, что при изменении реализации данных, не «посыпятся» программы, которые зависят от этого типа.

Есть поле private, которое недоступно, а есть парочка функций его обслуживающих, где одна записывает, другая возвращает значение

Типы рассматриваются как значения.

//set-get:

class cFraction

{

private int numerator;

private int denominator;

public void add(cFraction a)

{

//...

}

//set-переопределение

//get-вычисляемая функция в точке

// конструктор- эквивалентно write:

cFraction(int x, int y) //set

{

//неявно вызывается системныый конструктор

this.denominator = x;

this.numerator = y;

}

//эквивалентно read:

public int get_denominator()

{

return denominator;

}

public int get_numerator()

{

return denominator;

}

}