Классы, объекты и элементы приложения
Создание приложений (для Windows) требует знания объектно-ориентированного программирования. Разрабатывая приложения на С++, желательно использовать библиотеки классов .NET Framework, MFC, OWL, ATL или другие, которые существенно облегчают реализацию программ.
При разработке программ на языке C# применяется библиотека .NET Framework, а на языке Java – пакеты java.lang, java.awt, java.util, java.swing и другие. Все классы библиотеки .NET Framework и пакетов Java порождаются из класса Object.
C языком Visual J# можно использовать как пакеты языка Java так и библиотеку .NET Framework. В данной книге в программах на языке Visual J# будет применяться только пакеты языка Java. Наличие в среде разработки Visual Studio .NET как библиотеки .NET Framework, так и пакетов языка Java упрощает изучение как языка Java, аналогичному языку Visual J#, так и языка C# в одной среде разработки с родными для них библиотеками и пакетами.
При объектно-ориентированном программировании приложений следует различать такие понятия, как объект и элемент.
Объект – понятие языков С++, C# и Java. Вне модуля приложения объект размещается в памяти, будучи созданным из класса с помощью оператора new или gcnew. Из одного класса можно создать несколько объектов, которые, как правило, отличаться своим состоянием.
Элемент – это то, что представляет объект на экране, обеспечивая интерактивную связь пользователя с приложением. Обычно элемент представляется в виде специализированных дочерних окон – кнопок, панелей редактирования, ползунков и других. При применении библиотеки .NET Framework окна являются объектами класса Form и называются формами, а при применении пакетов java.awt языка Java окна являются объектами класса Frame и называются фреймами. Управляющие элементы – объекты, создаваемые из классов Control и UserControl.
Простейшие приложения
Создадим простейшее Windows-приложение, которое выдаёт на экран прикладное окно с именем “Hello”.
Рис.9.3.1. Прикладное окно приложения Hello примера 9.3.1
Пример 9.3.1. C#. Простое Windows-приложение. Два варианта.
///////////////
// C# Вариант 1
class MainClass
{
static void Main ( )
{
System.Windows.Forms.Form form=
new System.Windows.Forms.Form ( );
form.Size= new System.Drawing.Size (300, 100);
form.Text= "Hello";
System.Windows.Forms.Application.Run (form);
}
}
///////////////
// C# Вариант 2
using System.Windows.Forms;
using System.Drawing;
class MainClass
{
static void Main ( )
{
Form form= new Form ( );
form.Size= new Size (300, 100);
form.Text= "Hello";
Application.Run (form);
}
}
C#. Windows-приложение начинает выполнять главная функция Main(). Функция Main() примера 9.3.1 создаёт объект form прикладного окна из класса Form пространства имён System.Windows.Forms библиотеки .NET Framework. Затем она устанавливает свойство Size объекта form окна, присвоив этому свойству ссылку на объект класса Size пространства имён System.Drawing, содержащий ширину и высоту окна. Потом определяется свойство Text, указывающее заголовок объекта form окна. Сформировав прикладное окно, функция Main() запускает приложение, вызвав статическую функцию Run() класса Application пространства имён System.Windows.Forms и передав ей ссылку form на объект окна в качестве её аргумента. Аргументом функции Run() является ссылка на главное (прикладное) окно приложения. Получив ссылку на прикладное окно, функция Run() высвечивает его на экране. В дальнейшем будут рассмотрены и другие окна, но они отображаются на экране с помощью функции Show().
Для сокращения текста программы во втором варианте программы употреблён оператор using, указывающий на возможность применения в программе классов пространства имён System.Windows.Forms и пространства имён System.Drawing без указания их перед каждым классом, как это имело место в первом варианте программы.
Пример 9.3.2. Java. Простое оконное приложение.
///////////////
// Javaи J#
import java.awt.*;
class MainClass
{
public static void main ( )
{
Frame frame= new Frame ( );
frame.setSize (300, 100);
frame.setTitle ("Hello");
frame.show ( );
}
}
Java. В отличие от C# программы примера 9.3.1 функция main() Java программы примера 9.3.2 создаёт объект frame прикладного окна из класса Frame пакета java.awt. Затем функция main(), используя функцию-свойство setSize(), устанавливает ширину и высоту размер окна. Потом функция-свойство setTitle() определяет заголовок прикладного окна. Как видим, в случае языка Java не требуется явно вызывать функцию Run(), она вызывается неявно. Чтобы показать прикладное окно на экране, надлежит обязательно вызвать функцию show().
C# и Java. Примеры 9.3.1 и 9.3.2 показывают сходство и отличие C# и Java программ при написании простых приложений. Разные библиотеки содержат разноимённые классы и разноимённые свойства для создания сходных объектов и при использовании сходных свойств. В C# программе для подключения требуемых стандартных классов применяется оператор using, а в Java программе – оператор import. Функция Main() в C# программе пишется с большой буквы, а в Java программе – c маленькой. В C# программе используются непосредственно свойства Size и Text, а в Java программе – функции setSize() и setTitle() свойств. В C# программе явно применяется функция Run() и показывает прикладное окно, а в Java программе эта функция вызывается неявно и не показывает окно, так что приходится вызвать функцию show(). Надо заметить, что на языке C# принято писать имена функций с большой буквы, а на языке Java с маленькой.
Пример 9.3.3 иллюстрирует оконное приложение на языке C++/CLI.
Пример 9.3.3. C++/CLI. Простое Windows-приложение.
///////////////
// C++/CLI
#include "stdafx.h"
#using<System.dll>
#using<System.Windows.Forms.dll>
#using<System.Drawing.dll>
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Drawing;
ref class MainClass : public Form
{
public:
MainClass (void)
{
this->Size = *gcnew Drawing::Size (300,300);
// или this->Size = Drawing::Size (300,300);
this->Text = "Hello";
}
};
void main ( )
{
Application::Run (gcnew MainClass ());
}
C++/CLI. Программа на языке C++/CLI требует не только указания об использовании требуемых пространств имен библиотек классов с помощью using, но и подключения этих библиотек с помощью операторов #using. Управляемый класс MainClass помечается словом ref. Используются двоеточия и стрелки. Функция main() пишется с маленькой буквы.
Как просто получается приложение с классом Form библиотеки .NET Framework, как просто создаётся порождением из этого базового класса наш класс MainClass прикладного окна в примере 9.3.3. Но сам класс Form сложен. Он содержит множество свойств, событий и интерфейсных функций, с некоторыми из которых мы познакомимся позднее. Взгляните на рис. 9.3.1.1. Оказывается, класс Form сам наследует множество других классов, каждый из которых обогащает его функциональность. Как любой другой класс библиотеки .NET Framework, класс Form наследует корневой базовый класс Object, позволяющий всем объектам в системе сравниваться друг с другом, воспользовавшись функцией Equals() этого класса, или получать описание любого объекта с помощью функции ToString(). Обратим особое внимание на класс Control, включающий богатый набор свойств, событий и функций, которые наследуются не только классом окна, но многими другими классами, объекты которых, как и объекты окна, должны обладать общим поведением управляющих элементов (controls). Потом мы рассмотрим такие управляющие элементы, как кнопки и редакторы, классы которых наследуют также класс Control. Мы скоро убедимся, что объекты окон, кнопок и редакторы содержат не только одноимённые свойства Size, Text, применённые в примерах 9.3.1 и 9.3.3, но и многие другие свойства, например, Location, Name, Visible и др.
Рис. 9.3.1.1. Наследование классов классом Form
Пакеты, содержащие классы языка Java, отличается от библиотеки .NET Framework языков C# и C++/CLI. Отличаются и наследования классов, в чём убеждает рис. 9.3.1.2. В языке Java классу Control библиотеки .NET Framework соответствует класс Component. Этот класс Component включает свойства setSize(), getSize(), setLocation(), getLocation(), setVizible(), setName, getName() и др., используемых при создании интерфейсных элементов. Но в отличие от класса Component языка Java, класс Component библиотеки .NET Framework используется иначе – он применяется при разработке так называемых объектов компонентов, из которых создаются многокомпонентные программы в соответствиями с рекомендациями компонентно-ориентированного программирования. Посему необходимо отличать эти одноимённые, но функционально разные классы.
Рис. 9.3.1.2. Наследование классов классом Frame
Обсуждение.
C#.
Читатель.
Хорошо бы оживить простое приложение?
Автор.
Воспользуемся потоком, который будет изменять одно из свойств объекта окна – его заголовок. Имя заголовка окна определяется свойством Text.
// Пример 9.3.4. Обсуждение. Простое C#приложение
using System;
using System.Threading;
using System.Windows.Forms;
class Window: Form // Класс прикладного окна
{
Thread t; // Ссылка на поток
bool life; // Признак жизни потока
bool key; // Переключатель
public Window ( ) // Конструктор
{
key= true;
// Создать и запустить поток
life= true;
t= new Thread (new ThreadStart (Change));
t.Start ( );
}
// Выполнить поток
private void Change ( )
{
while(life)
{
if(key) this.Text= "university";
else this.Text="student";
key= !key;
Thread.Sleep (1000);
}
}
// Закрыть прикладное окно
protected override void OnClosed (EventArgs e)
{
life= false;
}
static void Main ( )
{
// Создать окно и запустить приложение
Application.Run (new Window());
}
}
Java.
Читатель.
Интересно, а как же это приложение выглядело бы на языке Java?
Автор.
На языке Java применяется другая библиотека классов, в которой имена классов, функций и свойств иные. Имя заголовка окна задается свойством setTitle(). Но в Java программе в отличие от C# программы, в которой размер окна и его видимость уже установлены по умолчанию, необходимо явно с помощью свойств setSize() и setVisible() установить их, иначе прикладное окно не появится на экране. И еще надо осуществить закрытие прикладного окна, которое здесь реализуется, но о котором сейчас не хотелось бы говорить, поскольку об этом будет подробно рассказано дальше.
// Пример 9.3.5. Обсуждение. Простое Java приложение
import java.awt.*;
import java.awt.event.*;
class Window extends Frame implements Runnable // Класс прикладного окна
{
Thread t; // Ссылка на поток
boolean life; // Признак жизни потока
boolean key; // Переключатель
public Window ( ) // Конструктор
{
this.setSize (300, 100);
this.setVisible (true);
// Закрыть прикладное окно
this.addWindowListener (new WindowAdapter ( )
{
public void windowClosing (WindowEvent wE)
{
life= false;
System.exit (0);
}
});
key= true;
// Создать и запустить поток
life= true;
t= new Thread (this);
t.start ( );
}
// Выполнить поток
public void run ( )
{
while(life)
{
if(key) this.setTitle ("university");
else this.setTitle ("student");
key= !key;
try
{
Thread.sleep(1000);
}
catch (InterruptedException ex) { }
}
}
public static void main ( )
{
// Создать окно и запустить приложение
new Window ( );
}
}