Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{




Скачать 102.5 Kb.
НазваниеJava есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{
Дата публикации24.10.2013
Размер102.5 Kb.
ТипДокументы
skachate.ru > География > Документы
Языки программирования. Лекция 13.
На прошлой лекции мы рассматривали статические и нестатические члены.

Членами могут быть:

-данные;

-функции;

-другие ТД (например, классы, т.е. вложенные классы);

В языке Java есть статические и нестатические классы:

Статические классы:

Перед любым членом, в т.ч. и классом может стоять ключевое слово static.
class X{

static public class Y {...};

}
Статический класс – то же самое, что и вложенный класс в языке С. Областью видимости которого является объемлющий класс (класс Х). Доступ к классу Y можно осуществить только посредством класса Х (в зависимости от спецификации доступа приватный или нет).

^ Нестатический класс (отсутствие идентификатора static) может использоваться только внутри класса Х (похож на функцию-член нестатическую). Все функции-члены класса Y имеют доступ ко всем членам класса X.

В классе Х может быть несколько экземпляров нестатического класса:

Y y1; Y y2;

Членам нестатического класса передается ссылка на объемлющий член класса.

Однако такого рода конструкция не является необходимой - её можно промоделировать, добавив во вложенный класс ссылку на объемлющий.
^ Константные члены
В языке Java есть модификатор final - указывает, что значение не будет меняться.

final int i = 0;

Значение присваивается немедленно.
Если значение будет константным, то есть ли смысл делать его статическим?

В языке Си# пошли на следующее: все константы по определению являются статическими членами. Она инициализируется только один раз и может существовать вне зависимости от существования экземпляров объекта.

Но в Си# допускается модификатор read-only - они могут быть инициализированы в произвольных функциях-членах (не статическая инициализация), но присваивание допускается только один раз, изменять его уже нельзя.

Разница между константами и read-only-переменными - во времени связывания.
В С++ такого различия нет, константы этого языка ближе к read-only объектам.

константы бывают нестатическими (инициализируются в конструкторе и только в нем) и статическими:
class X {

static const int i; // По стандарту нельзя здесь инициализировать i!

}
Инициализировать его можно в соответствующем срр-файле:

int X::i = 0;

Т.к. она должна существовать независимо от наличия объектов данного класса.

Если мы забудем инициализацию, то при обращении к ней будет выдана ошибка связывания.

В остальных ЯП такого различия констант на const и reаd-only нет.

^ Специальные функции-члены
Во многих ЯП есть такие специальные функции-члены как конструкторы и деструкторы.

Ещё специальные функции-члены - это операторы (например, преобразования).

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

- Инициализация приложения;

- Уничтожение;
Проблема большинства языков без классов - программисты забывают вовремя вызывать процедуры инициализации и уничтожения, освобождение ресурсов. Например, стек, если стек в виде списка, то уничтожение необходимо, если в виде указателя на свободный элемент, то необязательно.

Впервые конструкторы и деструкторы предложены в Си++.
Ранее были вспомогательные ф-ии thunks, ф-ии-помошники, но вызов их зависел от программиста. Конструктор вызывается при размещении объекта в памяти, деструкторы при удалении из памяти.
class X{

X(...);// конструктор

~X();//деструктор, ~ введена для того, чтобы не вводить новое служебное слово, для совместимости с Си

...

}
Когда вызываются конструкторы статических объектов?

Очевидно, до начала работы программы.

Деструкторы статических объектов (если речь идёт о нормальном выходе) выполняются после завершения работы программы (стандартный пролог и эпилог).

Конструкторы квазистатических объектов выполняются при входе в блок. Деструкторы - при выходе из блока.

Для динамических объектов - при вызове new и delete соответственно.
^ 1). Конструктор

В С++ (самый гибкий) любой конструктор имеет 2 составляющих:

1. Системная (стандартная);

2. Пользовательская (тело конструктора) - есть только у явных конструкторов (описанных программистами).
Неявные конструкторы - сгенерированные конструкторы.

Если конструктор неявный, то у него пустая пользовательская часть, а системная присутствует.
Может ли системная часть быть пустой?

struct Complex {

double Re, Im;

}

у этого класса системная составляющая может быть пустая, нет наследования и членов других классов.
В системной составляющей конструктора происходит
class Y public X{

Z z;

}

наследование: T--> T1-->....-->TN
- инициализация (вызов конструкторов) базовых классов (вызываются сверху вниз, т.е. от Т к ТN)

  • инициализация подчленов (объектов подклассов)( конструктор класса Z)

  • после этого выполняется пользовательское тело конструктора.


Аналогично и с деструкторами, но сначала выполняется пользовательская часть, а потом деструкторы подчленов, потом базовых классов( снизу вверх).
^ Классификация конструкторов:

  1. Конструктор умолчания (конструктор без параметров с точностью до параметров по умолчанию: Х( int i=0)-->

X()-не конструктор умолчания и X(int)) - вызывается автоматически (Z z;); если у класса отсутствуют пользовательские конструкторы, то конструктор умолчания генерируется автоматически, в том и только в том случае, если у класса нет конструкторов вообще.
2. Конструктор копирования X(const X&).

int i = 1; // инициализация, а не присваивание. Вызов конструктора умолчания.
T *p;

p = new X(); // вызов конструктора умолчания, можно без скобок
T a(); // а это уже выглядит как прототип функции!
T a = b;// копирования

T(b);

a = b;// нет копирования, т.к. а инициализирован--> нет неинициализированных объектов, т.к. всегда есть конструктор по крайней мере умолчания.

Конструктор всегда работает только с неинициализированным объектом! Т. е. если у класса есть хоть один конструктор, то он не может быть не инициализирован!
void f(X x); // здесь так же вызывается конструктор копирования, передача параметров по значению!

X f(); // и здесь тоже, возвращает объект типа Х - return
Явный конструктор копирования стоит описывать только, когда нам не хватает семантики. ^ Если нет конструктора копирования, то он генерируется по умолчанию - но он не только побитово копирует один класс в другой, у него есть базовая семантика(для членов простых ТД производится побитовое копирование, а для членов-классов - соответствующий конструктор копирования класса).

Если надо будет, то мы можем запретить использовать конструктор копирования (объявить его в private-секции).

Явный конструктор копирования следует описывать тогда, когда побитовой семантики копирования бывает недостаточно (вложенные ссылки, классы и т.д.).
Есть два типа копирования:

1. Поверхностное копирование (Shallow) - при копировании ссылки на другие объекты просто копируются;

2. Глубокое копирование (Deep) - при копировании другие объекты (на которые ссылается копируемый объект) тоже копируются.
^ Если мы сами переопределяем конструктор копирования, то мы должны переопределить оператор присваивания и наоборот. Присваивание работает с уже созданными объектами, и ресурсы, которые мы затираем, их надо освобождать.

Пример(разница между копированием и присваиванием ):

проблема глубокой копии
char String {

char *body;

String(String&);

String &operator = (String&);

};
String(String &S)

{

body = new char [S.Length() + 1];

strcpy(body, S.body);

}
String &operator = (String& S)

{

delete [] body;

body = new char [S.Length() + 1];

strcpy(body, S.body);

}

// если копировать строку саму в себя, то будет ошибка
3. Конструктор преобразования
X(T)

X(T&)

X(const T&)

Т отличен от Х!
В языке Си++ допустимы неявные преобразования (это преобразования, которые вставляются не программистом, а компилятором). Стоит заметить, что неявные преобразования - довольно опасная вещь.
class Vector {

....

Vector (int size);//конструктор, кол-во объектов в данном классе

T& operator [] (int i);//оператор индексирования

}
Vector V(20);

Vector X(10);

похоже на:

T V[20];

T X[10];

но в отличие от обычных массивов :

V = X;
V = 3; // ошибка, но не с точки зрения компилятора - он считает, что это V = Vector(3), отыскивая пользовательские конструкторы копирования;

Для этих случаев в Си++ создан модификатор explicit - невозможность использования неявных преобразований.

В языке Java разрешено всего два неявных преобразования: преобразование к типу данных Object и вызов метода ToString.

Нет неявных преобразований в Delphi, Ada.
Возникает вопрос: почему в языке Си++ неявные преобразования очень сильно распространены?

Рассмотрим пример вычисления выражения:

A = B + C * exp(I*X);

На языке Си без неявных преобразований:

A = Plus(B, Mult(C, EXP(Mult(I,X)))).

При добавлении комплексного типа данных, проблема при перегрузке операторов: большое кол-во вариантов, из-за возможных комбинаций типов.

При использовании неявных преобразований все становится проще: 11 конструкторов преобразования и варианты ф-ий.

Си# неявные преобразования разрешены.
4. Все остальные конструкторы (никакой особой семантики нет).
2).Деструктор

Деструкторы бывают двух видов:

1. Деструктор умолчания;

2. Пользовательский деструктор.

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

Cи++ все конструкторы.
В языке Cи# и Java есть конструктор умолчания. А вот конструктора копирования у них нет! Потому что у них нет побитовой семантики по определению - вместо объектов там все операции идут с указателями на объекты (a = b) - ссылочная семантика.

А для копирования есть метод Object Clone()- возвращает ссылку на объект. Для копирования- переопределить Object Clone().

Конструкторы преобразования в Java и Delphi отсутствуют, в Cи# преобразование делается исключительно при помощи операторов преобразования.
В силу ссылочной семантики конструктор вызывается явно.

Си# - base(...);

Java - Super(); от smalltalk
Во всех этих языках есть инициализаторы при членах (T x = e), выполняется она сверху вниз(в порядке, в котором они расположены в тексте).

static {...блок с любыми присваиваниями статическим членам класса вызывается, когда инициализируется первый статический член данного класса}; - статический инициализатор.
Если в языке Cи# есть у конструктора static, то это статический конструктор и он аналогичен статическому инициализатору в языке Java . Этот статический конструктор - конструктор умолчания .Т.к. инициализация явная и никаких параметров нет.

Для класса vector конструктор умолчания нецелесообразен, т.к. нет кол-ва элементов по умолчанию.

Если кто-то берёт и унаследует класс Vector, создавая класс X (c переменной int &k ). Должна быть специальная конструкция для вызова конструкторов баз и подчленов (Vector(20), k(i)).

В Си++ следующая семантика:
конструктор:
X(int i): Vector(20), k(i) {

k = i;// операция присваивания--> нужна явная инициализация

}
...

Си# - base(...);- в Си нельзя, т.к. баз может быть много.

Java - Super();
В языке Delphi немного другой синтаксис. Есть специальные ключевые слова constructor и destructor. Как правило, их называют Create и Free соответственно (сделано это по примеру объекта TObject).

Нет умолчания, т.к. все явно.
i:X;

i := X.Create(..);

i.Free;
Inherited имя метода - вызов родительского метода(конструктор и деструктор, соблюдая порядок).

^ Т.к. нет множественного наследования.

С деструкторами всё тоже просто - есть только обычные деструкторы (деструкторы умолчания есть только в Си++!). Явный вызов в Delphi - i.Free .
В языке Java есть защищенный метод void finalize() {...} - вызывается тогда, когда объект уходит из памяти, когда его уничтожает сборщик мусора. Объект удаляется из памяти, когда не хватает места, но он может быть и не удален--> гарантировать время освобождения объекта нельзя.

Идеологически работы с ресурсами в Си++:

Конструктор - захват ресурса, деструктор - освобождение ресурса. И каждому ресурсу ставится в соответствие какой-то класс.

смена курсора на песочные часы:

{

CWaitCursor c;// смена курсора с помощью конструктора и деструктора

long op

}
Java и Cи#

try {

...

} finally

{

.. // здесь код будет выполнен в любом случае, даже если в блоке try произошло исключение

}
Т.е.

try {

X = захват

} finally {

if (X != null)

X.Dispose();

}
C# IDisposable Dispose();- вызывается, если ресурс надо освободить, ибо деструктор может быть и не вызван.
using (инициализация объекта - выражение - захват ресурса: X = new XX())

{

блок: эквивалентно

try {X = new XX();

...

} finally {

if (X != null) X.Dispose;

}

}- гарантирует, что объект будет освобожден.






Похожие:

Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconСтатические и динамические
...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconБэйтсон Г. Логические категории обучения и коммуникации. – Новосибирск:...
Класс в формальном логическом или математическом рассуждении не может быть членом самого себя; что класс или классы не могут быть...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconДля специальности Информатика Луганск 2005г Лекция 1 Введение в язык...
Основой популярности Java являются встроенные классы-абстракции, сделавшие его языком, действительно независимым от платформы. Библиотеки,...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconКонкурс проводится по трем возрастным группам: 1 4 классы; 5 8 классы;...
Цель Конкурса – создание условий для воспитания у подрастающего поколения любви и уважения к истории и традициям школы
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconОрганизация объединенных наций
Специализированная секция уточнила, что международные классы были введены в стандарт в целях обеспечения международной согласованности,...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconРабочая программа по искусству (базовый уровень)
«Искусство 8-9 классы», авторы программы Г. П. Серге­ева, И. Э. Кашекова, Е. Д. Критская. Сборник: «Программы для общеобразовательных...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconРабочая программа по искусству (базовый уровень)
«Искусство 8-9 классы», авторы программы Г. П. Серге­ева, И. Э. Кашекова, Е. Д. Критская. Сборник: «Программы для общеобразовательных...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconК рабочей программе по русскому языку (углубленный уровень) для учащихся 9 б класса
Ным изучением русского языка 5-9 классы. Автор В. В. Бабайцева/ Программы для общеобразовательных учреждений: Русский язык. 5-9 классы.,...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconСведения об обеспеченности образовательного процесса учебной литературой
«Программы общеобразовательных учреждений. Литература» под редакцией В. Я. Коровиной 5-11 классы, 10-11 классы. М., «Просвещение»,...
Java есть статические и нестатические классы: Статические классы: Перед любым членом, в т ч. и классом может стоять ключевое слово static class X{ iconЭкзаменационные вопросы: Собственная и примесная электропроводности полупроводников
Биполярные транзисторы: входные и выходные статические характеристики по схеме оэ

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2014
контакты
skachate.ru
Главная страница