русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Глава 2 ВСЁ ЯВЛЯЕТСЯ ОБЪЕКТОМ


Дата добавления: 2015-06-12; просмотров: 914; Нарушение авторских прав


 

Содержание · 1 ВСЁ ЯВЛЯЕТСЯ ОБЪЕКТОМ · 2 Для работы с объектами используются ссылки · 3 Все объекты должны создаваться явно · 4 Где хранятся данные · 5 Особый случай: примитивные типы · 6 Числа повышенной точности · 7 Массивы в Java · 8 Ограничение области действия · 9 Область действия объектов · 10 Создание новых типов данных · 11 Поля и методы · 12 Значения по умолчанию для полей примитивных типов · 13 Методы, аргументы и возвращаемые значения o 13.1 Что такое - метод? o 13.2 Список аргументов o 13.3 Возвращаемое значение · 14 Создание программы на Java o 14.1 Видимость имен o 14.2 Использование внешних компонентов o 14.3 Ключевое слово static o 14.4 Наша первая программа на Java o 14.5 Компиляция и выполнение · 15 Комментарии и встроенная документация o 15.1 Документация в комментариях o 15.2 Синтаксис o 15.3 Встроенный HTML · 16 Примеры тегов o 16.1 Пример документации · 17 Стиль оформления программ · 18 Резюме

Хотя язык Java основан на C++, он является более «чистокровным» объектно-ориентированным языком. Как C++, так и Java относятся к семейству смешанных языков, но для создателей Java эта неоднородность была не так важна, если сравнивать с C++. Смешанный язык позволяет использовать несколько стилей программирования; причиной смешанной природы C++ стало желание сохранить совместимость с языком C. Так как язык C++ является надстройкой языка C, он включает в себя много нежелательных характеристик своего предшественника, что приводит к излишнему усложнению некоторых аспектов этого языка. Язык программирования Java подразумевает, что вы занимаетесь только объектно-ориентированным программированием. А это значит, что прежде, чем начать с ним работать, нужно «переключиться» на понятия объектно-ориентированного мира (если вы уже этого не сделали). Выгода от этого начального усилия — возможность программировать на языке, который по простоте изучения и использования превосходит все остальные языки ООП. В этой главе мы рассмотрим основные компоненты Java-программы и узнаем, что в Java (почти) все является объектом.



Для работы с объектами используются ссылки

Каждый язык программирования имеет свои средства манипуляции данными. Иногда программисту приходится быть постоянно в курсе, какая именно манипуляция производится в программе. Вы работаете с самим объектом или же с каким-то видом его косвенного представления (указатель в C или в C++), требующим особого синтаксиса? Все эти различия упрощены в Java. Вы обращаетесь со всем как с объектом, и поэтому повсюду используется единый последовательный синтаксис. Хотя вы обращаетесь со всем как с объектом, идентификатор, которым вы манипулируете, на самом деле представляет собой ссылку на объект. Представьте себе телевизор (объект) с пультом дистанционного управления (ссылка). Во время владения этой ссылкой у вас имеется связь с телевизором, но при переключении канала или уменьшении громкости вы распоряжаетесь ссылкой, которая, в свою очередь, манипулирует объектом. А если вам захочется перейти в другое место комнаты, все еще управляя телевизором, вы берете с собой «ссылку», а не сам телевизор. Также пульт может существовать сам по себе, без телевизора. Таким образом, сам факт наличия ссылки еще не означает наличия присоединенного к ней объекта. Например, для хранения слова или предложения создается ссылка String:

String s;

Однако здесь определяется только ссылка, но не объект. Если вы решите послать сообщение s, произойдет ошибка, потому что ссылка s на самом деле ни к чему не присоединена (телевизора нет). Значит, безопаснее всегда инициализировать ссылку при ее создании:

String s = "asdf";

В данном примере используется специальная возможность Java: инициализация строк текстом в кавычках. Обычно вы будете использовать более общий способ инициализации объектов.

Все объекты должны создаваться явно

Когда вы определяете ссылку, желательно присоединить ее к новому объекту. В основном это делается при помощи ключевого слова new. Фактически оно означает: «Создайте мне новый объект». В предыдущем примере можно написать:

String s = new String("asdf"):

Это не только значит «предоставьте мне новый объект String», но также указывает, как создать строку посредством передачи начального набора символов. Конечно, кроме String, в Java имеется множество готовых типов. Важнее то, что вы можете создавать свои собственные типы. Вообще говоря, именно создание новых типов станет вашим основным занятием при программировании на Java, и именно его мы будем рассматривать в книге.

Где хранятся данные

Полезно отчетливо представлять, что происходит во время работы программы — и в частности, как данные размещаются в памяти. Существует пять разных мест для хранения данных:

· Регистры. Это самое быстрое хранилище, потому что данные хранятся прямо внутри процессора. Однако количество регистров жестко ограничено, поэтому регистры используются компилятором по мере необходимости. У вас нет прямого доступа к регистрам, вы не сможете найти и малейших следов их поддержки в языке. (С другой стороны, языки C и C++ позволяют порекомендовать компилятору хранить данные в регистрах.)

· Стек. Эта область хранения данных находится в общей оперативной памяти (RAM), но процессор предоставляет прямой доступ к ней с использованием указателя стека. Указатель стека перемещается вниз для выделения памяти или вверх для ее освобождения. Это чрезвычайно быстрый и эффективный способ размещения данных, по скорости уступающий только регистрам. Во время обработки программы компилятор Java должен знать жизненный цикл данных, размещаемых в стеке. Это ограничение уменьшает гибкость ваших программ, поэтому, хотя некоторые данные Java хранятся в стеке (особенно ссылки на объекты), сами объекты Java не помещаются в стек.

· Куча. Пул памяти общего назначения (находится также в RAM), в котором размещаются все объекты Java. Преимущество кучи состоит в том, что компилятору не обязательно знать, как долго просуществуют находящиеся там объекты. Таким образом, работа с кучей дает значительное преимущество в гибкости. Когда вам нужно создать объект, вы пишете код с использованием new, и память выделяется из кучи во время выполнения программы. Конечно, за гибкость приходится расплачиваться: выделение памяти из кучи занимает больше времени, чем в стеке (даже если бы вы могли явно создавать объекты в стеке, как в C++).

· Постоянная память. Значения констант часто встраиваются прямо в код программы, так как они неизменны. Иногда такие данные могут размещаться в постоянной памяти (ROM), если речь идет о «встроенных» системах.

· Не-оперативная память. Если данные располагаются вне программы, они могут существовать и тогда, когда она не выполняется. Два основных примера: потоковые объекты (streamed objects), в которых объекты представлены в виде потока байтов, обычно используются для посылки на другие машины, и долгоживущие (persistent) объекты, которые запоминаются на диске и сохраняют свое состояние даже после окончания работы программы. Особенностью этих видов хранения данных является возможность перевода объектов в нечто, что может быть сохранено на другом носителе информации, а потом восстановлено в виде обычного объекта, хранящегося в оперативной памяти. В Java организована поддержка легковесного (lightweight) сохранения состояния, а такие механизмы, как JDBC и Hibernate, предоставляют более совершенную поддержку сохранения и выборки информации об объектах из баз данных.

 

Особый случай: примитивные типы

Одна из групп типов, часто применяемых при программировании, требует особого обращения. Их можно назвать «примитивными» типами (табл. 2.1). Причина для особого обращения состоит в том, что создание объекта с помощью new — особенно маленькой простой переменной — недостаточно эффективно, так как new помещает объекты в кучу. В таких случаях Java следует примеру языков C и C++. То есть вместо создания переменной с помощью new создается «автоматическая» переменная, не являющаяся ссылкой. Переменная напрямую хранит значение и располагается в стеке, так что операции с ней гораздо производительнее.

В Java размеры всех примитивных типов жестко фиксированы. Они не меняются с переходом на иную машинную архитектуру, как это происходит во многих других языках. Незыблемость размера — одна из причин улучшенной переносимости Java-npoгpaмм.

Таблица 2.1. Примитивные типы

Примитивный тип Размер, бит Минимум Максимум Тип упаковки
boolean (логические значения) Boolean
char (символьные значения) Unicode 0 Unicode 2^16-1 Character
byte (байт) -128 +127 Byte
short (короткое целое) -2^15 +2^15-1 Short
int (целое) -2^31 +2^31-1 Integer
long (длинное целое) -2^63 +2^63-1 Long
float (число с плавающей запятой) IEEE754 IEEE754 Float
double (число с повышенной точностью) IEEE754 IEEE754 Double
void (пустое значение) Void

Все числовые значения являются знаковыми, так что не ищите слова unsigned.

Размер типа boolean явно не определяется; указывается лишь то, что этот тип может принимать значения true и false.

«Классы-обертки» позволяют создать в куче не-примитивный объект для представления примитивного типа. Например:

char с = 'х';

Character ch = new Character(c),

Также можно использовать такой синтаксис:

Character ch = new Character('x');

Механизм автоматической упаковки Java SE5 автоматически преобразует примитивный тип в объектную «обертку»:

Character ch = 'х';

и обратно:

char с = ch;

Причины создания подобных конструкций будут объяснены в последующих главах.

 

Числа повышенной точности

В Java существует два класса для проведения арифметических операций повышенной точности: BigInteger и BigDecimal. Хотя эти классы примерно подходят под определение «классов-оберток», ни один из них не имеет аналога среди примитивных типов. Оба класса содержат методы, производящие операции, аналогичные тем, что проводятся над примитивными типами. Иначе говоря, с классами Biglnteger и BigDecimal можно делать то же, что с int или float, просто для этого используются вызовы методов, а не встроенные операции. Также из-за использования увеличенного объема данных операции занимают больше времени. Приходится жертвовать скоростью ради точности.

Класс BigInteger поддерживает целые числа произвольной точности. Это значит, что вы можете использовать целочисленные значения любой величины без потери данных во время операций.

Класс BigDecimal представляет числа с фиксированной запятой произвольной точности; например, они могут применяться для финансовых вычислений. За подробностями о конструкторах и методах этих классов обращайтесь к документации JDK.

 

Массивы в Java

Фактически все языки программирования поддерживают массивы. Использование массивов в C и C++ небезопасно, потому что массивы в этих языках представляют собой обычные блоки памяти. Если программа попытается получить доступ к массиву за пределами его блока памяти или использовать память без предварительной инициализации (типичные ошибки при программировании), последствия могут быть непредсказуемы.

Одной из основных целей Java является безопасность, поэтому многие проблемы, досаждавшие программистам на C и C++, не существуют в Java. Массив в Java гарантированно инициализируется, к нему невозможен доступ за пределами его границ. Проверка границ массива обходится относительно дорого, как и проверка индекса во время выполнения, но предполагается, что повышение безопасности и подъем производительности стоят того (к тому же Java иногда может оптимизировать эти операции). При объявлении массива объектов на самом деле создается массив ссылок, и каждая из этих ссылок автоматически инициализируется специальным значением, представленным ключевым словом null. Оно означает, что ссылка на самом деле не указывает на объект. Вам необходимо присоединять объект к каждой ссылке перед тем, как ее использовать, или при попытке обращения по ссылке null во время исполнения программы произойдет ошибка. Таким образом, типичные ошибки при работе с массивами в Java предотвращаются заблаговременно.

Также можно создавать массивы простейших типов. И снова компилятор гарантирует инициализацию — выделенная для нового массива память заполняется нулями. Массивы будут подробнее описаны в последующих главах. В большинстве языков программирования концепция жизненного цикла переменной требует относительно заметных усилий со стороны программиста. Сколько «живет» переменная? Если ее необходимо удалить, когда это следует делать? Путаница со сроками существования переменных может привести ко многим ошибкам, и этот раздел показывает, насколько Java упрощает решение затронутого вопроса, выполняя всю работу по удалению за вас.

 

Ограничение области действия

В большинстве процедурных языков существует понятие области действия (scope). Область действия определяет как видимость, так и срок жизни имен, определенных внутри нее. В 'C, C++' и Java область действия устанавливается положением фигурных скобок { }. Например:

{

int х = 12;

// доступно только х

{

int q = 96;

// доступны как х, так и q

}

// доступно ТОЛЬКО x

// q находится "за пределами видимости"

}

Переменная, определенная внутри области действия, доступна только в пределах этой области. Весь текст после символов // и до конца строки является комментарием. Отступы упрощают чтение программы на Java. Так как Java относится к языкам со свободным форматом, дополнительные пробелы, табуляция и переводы строк не влияют на результирующую программу.

Учтите, что следующая конструкция не разрешена, хотя в C и C++ она возможна:

{ int х = 12;

{

int х = 96; // неверно

}

}

Компилятор объявит, что переменная х уже была определена. Таким образом, возможность языков C и C++ «прятать» переменные во внешней области действия не поддерживается. Создатели Java посчитали, что она приводит к излишнему усложнению программ.

 

Область действия объектов

Объекты Java имеют другое время жизни в сравнении с примитивами. Объект, созданный оператором Java new, будет доступен вплоть до конца области действия. Если вы напишете:

{String s = new String("строка"); } // конец области действия

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

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

Возникает интересный вопрос. Если в Java объекты остаются в памяти, что же мешает им постепенно занять всю память и остановить выполнение программы? Именно это произошло бы в данном случае в C++. Однако в Java существует сборщик мусора (garbage collector), который наблюдает за объектами, созданными оператором new, и определяет, на какие из них больше нет ссылок. Тогда он освобождает память от этих объектов, которая становится доступной для дальнейшего использования. Таким образом, вам никогда не придется «очищать» память вручную. Вы просто создаете объекты, и как только надобность в них отпадет, эти объекты исчезают сами по себе. При таком подходе исчезает целый класс проблем программирования: так называемые «утечки памяти», когда программист забывает освобождать занятую память.

Создание новых типов данных

Если все является объектом, что определяет строение и поведение класса объектов? Другими словами, как устанавливается тип объекта? Наверное, для этой цели можно было бы использовать ключевое слово type («тип»); это было бы вполне разумно. Впрочем, с давних времен повелось, что большинство объектно-ориентированных языков использовали ключевое слово class в смысле «Я собираюсь описать новый тип объектов». За ключевым словом class следует имя нового типа. Например:

class ATypeName { /* Тело класса */ }

Эта конструкция вводит новый тип, и поэтому вы можете теперь создавать объект этого типа ключевым словом new:

ATypeName а = new ATypeName();

Впрочем, объекту нельзя «приказать» что-то сделать (то есть послать ему необходимые сообщения) до тех пор, пока для него не будут определены методы.

 

Поля и методы

При определении класса (строго говоря, вся ваша работа на Java сводится к определению классов, созданию объектов этих классов и посылке сообщений этим объектам) в него можно включить две разновидности элементов: поля (fields) (иногда называемые переменными класса) и методы (methods) (еще называемые функциями класса). Поле представляет собой объект любого типа, с которым можно работать по ссылке, или объект примитивного типа. Если используется ссылка, ее необходимо инициализировать, чтобы связать с реальным объектом (ключевым словом new, как было показано ранее).

Каждый объект использует собственный блок памяти для своих полей данных; совместное использование обычных полей разными объектами класса невозможно. Пример класса с полями:

class DataOnly { int і; double d; boolean b;}

Такой класс ничего не делает, кроме хранения данных, но вы можете создать объект этого класса:

DataOnly data = new DataOnly();

Полям класса можно присваивать значения, но для начала необходимо узнать, как обращаться к членам объекта. Для этого сначала указывается имя ссылки на объект, затем следует точка, а далее — имя члена, принадлежащего объекту:

ссылка.член

Например:

data.і = 47;

data.d = 1.1;

data.b = false;

Также ваш объект может содержать другие объекты, данные которых вы хотели бы изменить. Для этого просто продолжите «цепочку из точек». Например:

myPlane.leftTank.capacity = 100;

Класс DataOnly не способен ни на что, кроме хранения данных, так как в нем отсутствуют методы. Чтобы понять, как они работают, необходимо разобраться, что такое аргументы и возвращаемые значения. Вскоре мы вернемся к этой теме.

Значения по умолчанию для полей примитивных типов

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

Таблица 2.2. Значения по умолчанию для полей примитивных типов



<== предыдущая лекция | следующая лекция ==>
Программирование на стороне сервера | Что такое - метод?


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.137 сек.