- •2. Основные понятия объектно-ориентированного программирования 7
- •3. Управляемый и неуправляемый код и данные 17
- •3.3 Управляемый и неуправляемый код и данные 17
- •5. Классы 38
- •6. Наследование классов и интерфейсы 49
- •7. Программа ввода/вывода информации 62
- •8. Управляемые данные и их использование 76
- •Предисловие
- •2.1 Объекты
- •2.Основные понятия объектно-ориентированного программирования
- •2.2Классы
- •Пример 2.2.2. Создание и использование объектов.
- •2.3Объекты, классы и uml
- •2.4Основные свойства объектно-ориентированного программирования
- •Пример 2.4.1. Класс cColBall, наследуемый класс cBall.
- •Пример 2.4.2. Использование функций объектов.
- •2.5Библиотеки классов
- •3.Управляемый и неуправляемый код и данные
- •3.1Виртуальная машина языка Java
- •3.2Общеязыковая среда выполнения clr платформы .Net
- •3.3Управляемый и неуправляемый код и данные
- •3.4Сборщик мусора
- •3.5Ссылочные типы и типы-значения
- •3.6Метаданные
- •3.7Библиотеки, пакеты и пространства имён
- •4.1О типах данных
- •4.2Консольный ввод и вывод
- •Void main (void)
- •Import java.Io.*;
- •Int X; // Целочисленная переменная X
- •4.3Объявление переменных
- •4.4Операторы динамического распределения памяти new и delete
- •Int X; // Выделить память в стеке
- •Пример 4.4.2. Использование оператора new в языках Java и c#.
- •Import java.Io.*;
- •Int X; // Выделить память в стеке для переменной
- •Int X; // Выделить память в стеке для переменной
- •4.5 Массивы
- •Пример 4.5.2. Описание одномерных массивов на изыках Java и c#.
- •Пример 4.5.4. Создание массивов объектов на языке Java.
- •Import java.Io.*;
- •4.6Объявления структур и перечислений
- •4.7Ссылки
- •Пример 4.7.1. Использование ссылочной переменной.
- •Void main()
- •4.8Перегрузка функций
- •Пример 4.8.1. Перегруженные функции swap (int &, int &) и swap (bool &,bool &).
- •Void swap (int &a, int &b) // Целочисленные параметры
- •Void swap (bool &a, bool &b) // Булевские параметры
- •4.9Объявление функций и передача аргументов по умолчанию
- •Void swap (int &, int &);
- •Void swap (char 8t, char &);
- •Пример 4.9.1. Задание значений параметров функции по умолчанию.
- •Void main ( )
- •5.Классы
- •5.1Определение класса
- •Пример 5.1.1. Описание класса и создание его объектов.
- •Int X; // Закрытая переменная X
- •Void Show ( ) // Открытая функция
- •Int X; // Закрытая (по умолчанию) переменная X
- •Void Show ( ) // Открытая функция
- •Пример 5.2.1. Описание функций вне класса.
- •Int X; //Закрытая переменная х
- •Void Set(int m,char n); // 0бъявление функции Set
- •Void Show (); // Объявление функции Show()
- •5.3Некоторые замечания о классах
- •Пример 5.3.1. Области видимости.
- •Int GetK() {return k;} // Функция GetK() видна в файле, классе а и в
- •Int n; // Переменная n закрыта и видна только в классе а
- •Int GetM () {return n;} // Функция GetM() открыта и видна
- •5.4Объекты в объектах
- •Пример 5.4.1. Объект содержит объект другого класса.
- •Void Show ()
- •Void Show ()
- •5.5Специальный вид функций класса - конструкторы и деструкторы
- •Пример 5.5.1. Перегруженные конструкторы.
- •Int GetX() {return X;} // Возвратить значение закрытой переменной
- •Void ShowX () // Вывести значение переменной
- •5.6Статические функции класса
- •Пример 5.6.1. Статические функции.
- •Void f() {Console::WriteLine("f()");} // Обычная функция
- •Int main() // Главная статическая функция Main()
- •6.Наследование классов и интерфейсы
- •6.1Об интерфейсах
- •Пример 6.2.1. Программа, использующая порождение public.
- •Void Show ()
- •Void Show()
- •Int main() // Главная статическая функция
- •6.4Использование конструктора базового класса
- •Java и j#
- •Java и j#
- •Пример 6.4.1. Выполнение конструкторов.
- •Int X; // Закрытая переменная X
- •Int Get() {return X;} // Получить значение X
- •Int main() // Главная статическая функция main()
- •6.5Сокрытые переменные, функции и их использование
- •Пример 6.5.1. Сокрытые переменные и функции.
- •6.6Интерфейсы
- •Interface class имя-интерф [ : public имя-базов-интерф
- •Interface имя-интерф [ : имя-базов-интерф [, имя-базов-интерф ] ... ]
- •Interface имя-интерф [ extends имя-базов-интерф
- •Interface Ipe // Интерфейс, объявляющий свойство p и функцию Hallo
- •Int p {set; get;} //Объявить свойство
- •Void Hallo(); // Объявить функцию
- •6.6.1Определение интерфейса
- •6.6.2Базовые интерфейсы
- •6.7 Упаковка и распаковка типов данных
- •Int main() // Главная статическая функция main()
- •7.Программа ввода/вывода информации
- •7.1Постановка задачи
- •Диаграмма вариантов использования
- •7.2 Диаграмма классов
- •7.3Диаграмма последовательности
- •7.4Диаграмма видов деятельности
- •Пример 7.5.1. Реализация класса cComputer.
- •Пример 7.5.2. Реализация класса cShop.
- •Пример 7.5.3. Реализация класса cData.
- •Void main()
- •Пример 7.5.4. Реализация Inf-приложения.
- •Void main()
- •7.6Реализация Inf-приложения иа языке c# Пример 7.6.1. Реализация Inf-приложения иа языке c#.
- •Int cost; // Стоимость компьютера
- •Int year; // Год изготовления
- •Inf.Enter();
- •Inf.Enter();
- •Inf.Show();
- •8.Управляемые данные и их использование
- •Void set(тип value)
- •Пример 8.1.2. Свойства в Java.
- •Import java.Io.*;
- •Пример 8.2.1. Создание и использование делегата.
- •Void main() // Главная функция программы
- •Пример 8.2.2. Использование делегата как параметра функции.
- •Void r(void) {Console::WriteLine ("r");}
- •Void main () // Главная функция программы
- •Void имя-функции ( void );
- •Пример 8.3.1. Событие и делегат.
- •Void main ()
- •Vold имя-функции-активизации()
- •Пример 8.3.2. Использование события.
- •Void GenerateEv() // Функция-генератор события
- •Void main()
- •Void GenerateEv (String л str) // Функция- генератор события
- •Void main ( )
- •06BeKTfirst клaccaUseEvпoлyчилcoбытиe one
- •Interface iEv
- •IE,HandlerEv (); // Выполнить обработчик
- •Void GenerateEv ( ) // Сгенерировать событие
- •Void main (void)
- •V{ oid FireConnectEvent (object sender, SourceEventArgs e)
- •Void FireConnectEvent (object sender, EventArgs args)
- •8.4. Уведомления и события в Java
- •8.4.1. Уведомления в Java
- •Void notifyObservers () - уведомить всех обозревателей данного наблюдаемого
- •Void notifyObservers (Object obj) - уведомить всех обозревателей данного на-
- •Void update(Observable observable. Object obj) - эта функция данного объекта
- •Import java.Util.*;
- •II Два наблюдателя и один наблюдаемый объект
- •Importjava.Util.*;
- •Importjava.Utll,*;
- •Importjava.Util.*;
- •Int num; // Номер уведомляющего объекта
- •8.4.2. События в Java
- •Import java.Utii.*;
- •Void DatePerformed (DataDate dd); // Обработчик
- •Int n; // Номер объекта-приёмника
- •Int num; // Номер объекта приёмника
- •Import cJHappenListerner.*;
- •Importjava.Uti).*;
- •Void performedHappen (HappenData hD);
- •Import cJHappenListerner.*; | | Импортировать библиотеку
- •9. Потоки и синхронизация их выполнения
- •9.1. Процессы
- •9.3. Потоки в Java
- •Int num; // Номер потокового объекта
- •2. Поскольку объявленному в классе cThread потоковому объекту thr типа
- •9.4. Потоковый объект, выдающий событие
- •If (lllfe) // Если потоковый объект не функционирует,
- •ImportJava,util.*;
- •If (!life) // Если потоковый объект не функционирует,
- •9.5. Поток получил событие из объекта
- •If (!life)
- •If (received)
- •Importjava.Utll.*;
- •If (lllfe)
- •If (received)
- •9.6. Синхронизация выполнения потоков
- •9.6.1. Операторы lock и synchronized
- •Int num; // Номер объекта
- •9.6.2. Связи между потоками
- •9.6.2.1. Связи меяеду потоками в Java
- •If(waiting)
- •9.6.2.2. Связи между потоками в c#
- •If (I moving)
- •9.6.2.1.1 Наязыке Java, отличаясьтолько применением функций монитора
- •10. Библиотека .Net Framework и библиотеки
- •10.1. Приложение
- •10.2. Классы, объекты и элементы приложения
- •Visual Studio .Net как библиотеки .Net Framework, так и пакетов языка Java
- •10.3. Простейшие приложения
- •Import java.Awt.*;
- •Void main ( )
- •10.3.1.1. Оказывается, класс Form сам наследует множество других классов,
- •10.4. Сообщения Windows, события и делегаты
- •X0.4.1. Обработка событий мыши на языке c#
- •Void OurMouseDown (object sender, MouseEventArgs args);
- •Vold maln ()
- •10.4.3. Обработка событий мыши на языке Java с использо-
- •10.4.4. Связь события с несколькими объектами на языке c#
- •10.5. Ещё раз о событиях и уведомлении в языке Java
- •10.5.1. Обработка событий элементов интерфейса пользовате-
- •ItemListener, KeyListener, MouseListener, MouseMotionListener, TextListener
- •10.5.2. Обработка событий мыши на языке Java, используя
- •Importjava.Awt.Event.*;
- •Importjava.Awt.*;
- •Import java.Awt.Event.*;
- •Importjava.Awt.*;
- •Import java.Awt.Event.*;
- •10.5.3. Обработка событий мыши на языке Java, используя классы адап-
- •Importjava.Awt.*;
- •Importjava.Awt.Event.*;
- •Importjava.Awt.*;
- •Importjava.Awt.Event.*;
- •10.5.4. Обработка событий мыши на языке Java, используя внутренние
- •Import java.Awt.*;
- •Import java.Awt.Event.*;
- •Importjava.Awt.*;
- •Import java.Awt.Event.*;
- •10.5.5. Обработка события закрытия окна
- •Import java.Awt.*;
- •Import java.Awt.Event.*;
- •10.6. Графика
- •10.6.1. Графические объекты
- •15, 15, 60, 70); // Нарисовать эллипс
- •Vold maln ()
- •10.7. Событие Paint и его обработчик
- •Int len; // Текущая длина массива points
- •Void OurMouseDown (object sender, MouseEventArgs arg)
- •Invalidate ( ); // Перерисовать
- •Int len; // Текущая длина массива points
- •Import java.Awt.Event.*;
- •10.8. Управляющие элементы
- •1 «Button j 1
- •Import java.Awt,event.*;
- •Int n; // Индекс цвета
- •10.8.4,10.8.5 И 10.8.6, а также программа, поэтапно разрабатываемая в разде-
- •Invalidate ();
- •Importjava.Awt.*;
- •Import java.Awt.Event.*;
- •Importjava.Util.*;
- •10.9. Дочерние окна
- •Int n; // Индекс массива colors
- •IiTipOrt jav'a.Avvt. •)
- •Import java.Awt.Event.*;
- •Int n; // Индекс цвета
- •Virtual void OnPaint (PaintEventArgs л arg) override // Перерисовать область
- •10.10.3, В котором вызываются две функции.
- •Importjava.Awt.*;
- •Importjava.Awt.Event.*;
- •It); // Подписать обработчик
- •Void main ( )
- •11.1. Программа с точки зрения пользователя
- •11.2. Объектное представление программы
- •11.3. События, потоки и их синхронизация
- •11.4. Поэтапная разработка программы
- •11.4.1. Первый этап. Разработка класса Warehouse
- •4Cxrt()
- •Int partLoad; // Выгружаемая или загружаемая порция
- •If(full) return false; // Полный грузовик не загружать
- •Invalidate ();
- •Importjava.Awt.*;
- •Importjava,utll.*;
- •Void notifyObs (WarehouseEventArgs arg)
- •Int partLoad; // Получаемая или помещаемая порция груза
- •If (full) return false;
- •If(full) return false; // Полный грузовик не загружать
- •Void Change ( )
- •Invalidate ();
- •Importjava.Awt.*;
- •Importjava.Util.*;
- •Import cjWarehouse.*
- •11.4.2. Второй этап. Разработка классов ContrlRegion и Lorry
- •11.4.2.1, А сам класс представлен в примере 11.4.2.1. Класс ContrlRegion язы-
- •Importjava.Awt.Event.*;
- •Void Work ( ) // Выполнить работу
- •Int number;
- •Int number;
- •Int timePeriod;
- •Int y; // Координата y пути грузовика
- •Invalidate ();
- •11.4.3. Третий этап. Разработка приложения csLorryAndWarehouse
- •4IorryAndWa rho uses()
- •4Main()
- •Int y; // Координата y пути грузовика
- •Invalidate ( );
- •If(lorry.GetFull())
- •If(lorry.GetLeftRight()) g.SetColor(Color.Red);
- •Int numLorry; // Номер грузовика
- •Void But_Run (Object Ло, EventArgs ле)
- •Void main ( )
- •11.4.4. Четвертый этап. Удаление ресурса
- •Int number;
- •If(!lorry.Running)lorry.Run ( );
- •12. Зачетные задачи
- •12.1. Задание 1
- •Importjava.Awt.*;
- •Import Java.Awt.Event.*;
- •Importjava.Util.*;
- •12.2. Задание 2
- •Importjava.Awt.*;
- •Importjava.Awt.Event,*;
- •Importjava.Util.*;
- •Invalidate ( );
- •12.3. Задание 3
- •Importjava.Awt.*;
- •Import java.Awt.Event.*;
- •Importjava.Util.*;
- •If(bool) Start ();
- •If(lrunnlng)
- •Void BallFunc ()
- •Void ThrFunc ( )
- •Vold OnButAdd (object obj, EventArgs arg)
- •Void HandlerEv ( )
- •Invalidate ( );
- •12.4. Задание 4
- •If(reg.R.Contains(p) && !inRect)
- •If(!reg.R,Contains(p) && lnRect)
- •Void OnButAdd (object obj, EventArgs arg)
- •Void HandlerEv ( )
- •Invalidate ();
- •Importjava.Awt.*;
- •Importjava.Awt.Event.*;
- •Importjava.Utll.*;
- •Int w, int h, Color c, Wind wind)
- •If(reg.R.Contains(p) && !lnRect)
- •If(!reg.R.Contains(p) && inRect)
- •If(d.GetDel())
- •13. Ещё о важном в объектно-ориентирован-
- •13.1. Виртуальные функции
- •13.1.1. Преобразование типов
- •Void f ( ) {cout « "ca:: f" « endl;}
- •Void main ( )
- •Void f ()
- •Void main ( )
- •Vold f ( )
- •Vold Do (ca* pCa)
- •Void main ( )
- •13.1.2, Виртуальные функции
- •Virtual void f ( ) {Console::WriteLine ("a:: f");}
- •Void f ( ) {Console::WriteLine ("b:: f");}
- •Void f ( ) {Console::WrlteLlne ("c:: f");}
- •Vold f ( ) {Console::WrlteLlne("b:: f");}
- •Vold Do (a* pA)
- •Void main ()
- •13.1.3. Виртуальные функции, используемые в книге
- •13.2. Абстрактные классы и функции
- •13.2.1. Абстрактные функции
- •13.2.2. Абстрактные классы
- •Void f ( ) {Console::WriteLine ("b:: f");}
- •Vold f ( ) {Console::WriteLine ("d:: f");}
- •Vold main ( )
- •13.2. Нововведения в языке c#
- •13.2.1.Делегаты и события
- •Iorry.Run ( );
- •13.3.2. Статические классы
- •Int partLoad; // Выгружаемая или загружаемая порция
- •If(!full)
- •Invalidate ( );
- •Int number;
- •Int y; // Координата y пути грузовика
- •Iorry.Stop ();
- •If(llorry.Running)lorry.Run ( );
- •Invalidate ( );
- •1) Создать новый проект:
- •Value 28, 30
- •Value type 34
- •Visual Studio .Net и Edipse.
- •420111, Казань, Дзержинского, 3. Тел.: 292-24-76.
ImportJava,util.*;
class CUseEv implements Observer // Класс обозревателя
{
public void update (Observable obj, Object arg)
{
System.out.println("Notify: 1=
+ ((Integer)arg).intValue ( ));
>
>
class Notify extendsObservable // Класс наблюдаемого объекта
{
public void send (int i)
{
setChanged ( );
notifyObservers (new Integer (i));
>
}
class CThread extends Thread
{
// Класс потокового объекта
Notify notify;
int num;
boolean life;
// Ссылка на наблюдаемый объект
// Номер потокового объекта
// Признак жизни
public CThread (int Num)
{
num= Num; llfe= false;
notify= new Notify(); // Создать наблюдаемый объект
public void Start ( ) // Стартовать потоковый объект
{
If (!life) // Если потоковый объект не функционирует,
{
life= true; // то пусть живёт
thls.start(); >
>
public void Finish ( ) {llfe= false; >
public void run() // Потоковая функция
{
int n= 0; // Номер цикла выполнения потока
while (life) // Пока живёт, выполнять
{
n++;
notify.send(n); // Инициировать уведомление
try
{
Thread.sleep (50);
>
catch(InterruptedException e){>
>
System.out.println ("Thread " + num + " finished");
>
>
class TestThread // Главный класс приложения
{
public static vold main ( )
{
CUseEv useEv= new CUseEv (); // Создать объект useEv
CThread threadl- new CThread (1); // Создать потоковый объект
threadl.notify-addObserver(useEv);// Подписать обозреватель
threadl,Start (); // Запустить потоковый объект
try
{
Thread.sleep (200);
>
catch(InterruptedException e){}threadl.Finish (); // Завершить
// потоковый объект
threadl.Finish ();
>
/>*
Result:
Notify: 1= 1
Notify: i= 2
Notify: 1= 3
Notify: i= 4
Thread 1 finished
*/
9.5. Поток получил событие из объекта
Пример 9.5.1 иллюстрирует в отличие от примера 9.4.1 противополож-
ный случай, когда не потоковый объект посылает событие, а потоковому
объекту посылается событие из обычного объекта.
Пример 9.S.1. Поток получил событие из объекта.
////////////////////
/ / C #
using System;
using System.Threading;
namespace CsTEl_2
{
delegate void delEv (string st); // Тип делегата событий
class CGenEv // Класс объекта, посылающего событие потоковому объекту
{
public event delEv ev; // Событие к потоковому объекту
public void GenerateEv (string str ) // Сгенерировать событие
<
if (ev 1= null)
ev (str); // Послать событие ev
>
>
class CThread // Класс потокового объекта
{
bool received; // Признак получения события
string st;
int num;
Thread thread;
bool life;
public CThread (int Num ) {num= Num; life= false;>
~CThread ( ) {iife= false; received= false;}
public void Start ( )
{
If (!life)
{
life= true;
thread= new Thread (new ThreadStart (ThreadFunc));
thread.Start ();
} >
public void Finish ( ) {life= false;}
public void HandlerEv (string str)
{
received= true;
st= str;
>
private vold ThreadFunc ( )
{
int n= 0;
while Hife^
<" " " " ' ^"
n+ + ;
Console.WriteLine ("thread " + num + " n= " + n);
If (received)
{
received= false;
Console.WriteLine ("Поток получил событие: " +
}
Thread.Sleep (50);
>
Console.WriteLine ("Thread " + num + " finished");
>
>
class TestThread
{
static void Maln ( )
{
CThread threadl= new CThread (1);
CGenEv genEv= new CGenEv ();
// Подписать обработчик HandlerEv на событие ev
genEv.ev += new delEv (threadl.HandlerEv);
threadl.Start ();
Thread,Sleep (100);
genEv.GenerateEv ("Здравствуй");
Thread.Sleep (100);
threadl.Finish ();
>
}
I>*
Result:
thread 1 n= 1
thread 1 n= 2
thread 1 n= 3
Поток получил событие: Здравствуй
thread 1 n= 4
Thread 1 finished
* /
////////////////////
// Java и J #
|| Обработать поступившее
// событие
// Событие получено
interface ICThread
{
public void HandlerEv (String str);
>
class CGenEv // Класс объекта, посылающего событие потоковому объекту
{
ICThread ICThread; // Интерфейсная ссылка
public CGenEv (ICThread IC)
/
iCThread= IC; // Установить ссылку на потоковый объект
>
public vold GenerateEv (String str) // "Сгенерировать событие"
{
iCThread.HandlerEv(str); // Послать сообщение
>
>
class CThread extends Thread implements ICThread
{
boolean received;
String st;
int num;
boolean life;
public CThread (int Num ) <num= Num; life= false; received= false;>
public vold Start ( )
{
if (!life)
{
life= true;
this.start();
>
>
public vold Finish ( ) {life= false;}
public void HandlerEv (String str) // Обработать поступившее
{ // событие
receivedc true;
st= str;
>
public void run ()
{
int n= 0;
while (llfe)
{
n++;
System.out,println ("thread " + num + " n= " + n);
if (received)
{
received= false;
System.out.println ("The thread received message: " +
st);
>
try
{
Thread.sleep (50);
>
catch(InterruptedException e){}
>
bystem.out.println ("inread " + num + :: nnisnea");
>
>
class TestThread
{
public static void main ( )
{
CThread threadl= new CThread (1);
CGenEv genEv= new CGenEv (threadl );
try
{
threadl.Start ();
Thread.sleep (100);
>
catch(InterruptedException e){}
genEv.GenerateEv ("hello");
try
{
Thread.sleep (100);
>
catch(InterruptedException e){>
threadl.Finish ( );
>
/>*
Result:
thread 1 n= 1
thread 1 n= 2
thread 1 n= 3
The thread received message: hello
thread 1 n= 4
Thread 1 finished
*/
////////////////////
// C++/CLI
#include "stdafx.h"
using namespace System;
using namespace System::Threading;
delegate vofd delEv (String^};
ref class CGenEv // Класс объекта, посылающего событие в потоковый объект
{
public:
event de!Ev ^ev;
void GenerateEv (String ^str ) // Сгенерировать событие
<
ev (str); // Послать событие ev
>
>;
refclass CThread // Потоковый класс, объект которого получает событие
<
int num;
Thread ^thread;
bool life;
bool received;
String ^st;
public:
CThread (int Num ) {num= Num; life= false; received= false;>
~CThread ( ) {llfe= false;}
void Start ( )
{
If (llife)
{
life= true;
thread= gcnew Thread (gcnew ThreadStart (thls,
&CThread::ThreadFunc));
thread -> Start ( );
>
>
void Finish ( ) {life= false;}
void HandlerEv (String ^str) // Обработать поступившее
< // событие
received= true;
st= str;
>
void ThreadFunc ()
{
int n= 0;
while (life)
{
n++;
Console::Write ("thread {0}", num.ToString ( ));
Console::WriteLine (" n= {0}", n.ToString ());
if (received)
{
received= false;
Console::WrlteLine ("Поток получил событие: {0}", st);
>
Thread::Sleep (50);
Console::Write (Thread {0>", num.ToString ());
Console::WriteLine (" finished");
>
>;
void main ( )
{
CThread ^threadl= gcnew CThread (1);
CGenEv ^genEv= gcnew CGenEv ( );
t h r e a d l -> Start ( );
genEv -> ev += gcnew delEv (threadl, &CThread::HandlerEv);
Thread::Sieep (100);
genEv -> GenerateEv ("Здравствуй");
Thread::Sleep (100);
threadl -> Finish ();
/>*
Result:
thread 1 n= 1
thread 1 n= 2
thread 1 n= 3
Поток получил событие: Здравствуй
thread 1 n= 4
Thread 1 finished
* /
Класс CGenEv обычного объекта объявляет ссылку (или дескриптор) ev
на событие, использующее делегат delEv. Класс CGenEv содержит функцию
GenerateEv(), генерирующую событие ev. Эту функцию применяет функция
main() к объекту genEv класса CGenEv через 100 мс после его старта. Причём
функция GenerateEv() имеет аргумент "Здравствуй".
Класс CThread потокового объекта включает обработчик HandlerEv()
события ev, который подписывается на событие ev объекта genEv с помощью
делегата delEv или интерфейсной ссылки после создания этого объекта, но
перед его запуском.
Потоковый объект использует булевскую переменную received для
фиксации потоком получения события. При этом поток выдаёт на консоль
строку, подтверждающую получение сообщения.
В примере 9.5.2 рассмотрена иная реализация воздействия из объекта на объ-
ект с потоком. Здесь объект с потоком представлен как обозреватель, то есть
объект класса, наследующего интерфейс Observer и содержащий обработчик
update() уведомлений от наблюдаемого объекта. Такая реализация возможна
только на языках Java и J# , библиотека которых включает требуемый класс
Observable и интерфейс Observer.
Пример 9.5.2. Поток получил уведомление из наблюдаемого объекта.
////////////////////
// Java и J#
