Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
JAVA.docx
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
509.86 Кб
Скачать

Void getFood(int food, int drink); // Кормление

              // Прочее 

}

Хозяин и его домашние животные постоянно соприкасаются в жизни. Их взаимодействие выражается глаголами "гулять", "кормить", "охранять", "чистить", "ласкаться", "проситься" и прочими. Для описания взаимодействия объектов применяется третий принцип объектно-ориентированного программирования — обязанность или ответственность.

Ответственность

В нашем примере рассматривается только взаимодействие в процессе кормления, описываемое методом eat(). В этом методе животное обращается к хозяину, умоляя его применить метод getFood().

В англоязычной литературе подобное обращение описывается словом message. Это понятие неудачно переведено на русский язык ни к чему не обязывающим словом "сообщение". Лучше было бы использовать слово "послание", "поручение" или даже "распоряжение". Но термин "сообщение" устоялся и нам придется его применять. Почему же не используется словосочетание "вызов метода", ведь говорят: "Вызов процедуры"? Потому что между этими понятиями есть, по крайней мере, триЪтличия.

  • Сообщение идет к конкретному объекту, знающему метод решения задачи, в примере этот объект — текущее значение переменной person. У каждого объекта свое текущее состояние, свои значения полей класса, и это может повлиять на выполнение метода.

  • Способ выполнения поручения, содержащегося в сообщении, зависит от объекта, которому оно послано. Один хозяин поставит миску с "Chappi", другой бросит кость, третий выгонит собаку на улицу. Это интересное свойство называется полиморфизмом (polymorphism) и будет обсуждаться ниже.

  • Обращение к методу произойдет только на этапе выполнения программы, компилятор ничего не знает про метод. Это называется "поздним связыванием" в противовес "раннему связыванию", при котором процедура присоединяется к программе на этапе компоновки.

Итак, объект sharik, выполняя свой метод eat (), посылает сообщение объекту, ссылка на который содержится в переменной person, с просьбой выдать ему определенное количество еды и питья. Сообщение записано в строке person.getFood(food, drink).

Этим сообщением заключается контракт (contract) между объектами, суть которого в том, что объект sharik берет на себя ответственность (responsibility) задать правильные параметры в сообщении, а объект — текущее значение person — возлагает на себя ответственность применить метод кормления getFood() , каким бы он ни был.

Для того чтобы правильно реализовать принцип ответственности, применяется четвертый принцип объектно-ориентированного программирования — модульность (modularity).

Модульность

Этот принцип утверждает — каждый класс должен составлять отдельный модуль. Члены класса, к которым не планируется обращение извне, должны быть инкапсулированы.

В языке Java инкапсуляция достигается добавлением модификатора private к описанию члена класса. Например:

private int mouseCatched;

private String name;

private void preserve();

Эти члены классов становятся закрытыми, ими могут пользоваться только экземпляры того же самого класса, например, tuzik может дать поручение

sharik.preserve().

А если в классе Master мы напишем

private void getFood(int food, int drink);

то метод getFood() не будет найден, и несчастный sharik не сможет получить пищу. ,

В противоположность закрытости мы можем объявить некоторые члены класса открытыми, записав вместо слова private модификатор public, например:

public void getFood(int food, int drink);

К таким членам может обратиться любой объект любого класса.

Принцип KISS

Самый основной, базовый и самый великий :принцип программирования принцип KISS — не нуждается в разъяснений :и переводе: "Keep It Simple, Stupid!"

5. Коллекция объектов.

Коллекции Java

Коллекции или контейнеры – это классы позволяющие хранить и производить

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

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

Во многих языках программирования (Java, C, C++, Pascal) единственным встроенным

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

значительными недостатками, одним из них является конечный размер массива, как

следствие необходимость следить за размером массива. Другим - индексная адресация, что

не всегда удобно, т.к. ограничивает возможности добавления и удаления объектов. Чтобы

избавиться от этих недостатков уже несколько десятилетий программисты используют

рекурсивные типы данных, такие как списки и деревья. Стандартный набор коллекций Java

служит для избавления программиста от необходимости самостоятельно реализовывать эти

типы данных и снабжает его дополнительными возможностями.

До выхода Java 2 v1.5 Tiger коллекции обладали значительным недостатком по

сравнению с массивами. Дело в том что до версии 1.5 Java не поддерживал настраиваемые

типы данных, что не позволяло создавать типизированные коллекции. С введением в Java 2

v1.5 настраиваемых (generics) типов Collections Framework был переписан и сейчас

поддерживает строгую типизацию. Т.е. можно объявить коллекцию, которая сможет хранить

объекты только определенного класса и потомков этого класса.

В данной статье будут рассмотрены основные классы и интерфейсы Collections

Framework в однозадачной среде. Т.е. в ней не будут рассмотрены вопросы синхронизации

коллекций и коллекции специально созданные для работы в многозадачной среде, которые

находятся в пакете java.util.concurrent.*.

Интерфейсы

Интерфейсы в Collections Framework играют ключевую роль. Все классы коллекций

унаследованы от различных интерфейсов, которые определяют поведение коллекции.

Иными словами интерфейс определяет «что делает коллекция», а конкретная реализация

«как коллекция делает то что определяет интерфейс».

При разработке приложений рекомендуется, там где это возможного, использовать

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

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

сконцентрироваться на задаче, а не на особенностях реализации.

Как не трудно догадаться, первая задача которая встает перед разработчиком при

использовании Collections Framework – это выбор интерфейса. К выбору интерфейса следует

подходить исходя из предметной области. Например, если в реальном мире Вы имеете дело с

очередью на обслуживание, вполне вероятно, что Вам необходимо использовать интерфейс

Queue<E>.

Рассмотрим интерфейсы подробнее:

Iterable<T>

Интерфейс Iterable<T> означает то что данная коллекция может формировать

объект-итератор1, а значит может быть использована в конструкции for (в виде for-each)2

.

Collection<E>

1 Итераторы используются для последовательного обхода всех элементов коллекции.

2 Использовать конструкцию for в виде for-each стало возможным начиная с Java 2 v1.5 Tiger

Это базовый интерфейс Collections Framework. В интерфейсе Collection<E>

определены основные методы для манипуляции с данными, такие как вставка (add,

addAll), удаление (remove, removeAll, clear), поиск (contains). Однако, в

конкретной реализации часть методов может быть не определена, а их использование, в этом

случае, вызовет исключение UnsupportedOperationException. Поэтому я бы

рекомендовал использовать интерфейс более адекватно описывающий предметную область.

6. Обработка исключений и ошибок.

Исключение в Java — это объект, который описывает исключительное состояние, воз­никшее в каком-либо участке программного кода. Когда возникает ис­ключительное состояние, создается объект класса Exception. Этот объект пересылается в метод, обрабатывающий данный тип исключительной ситуации. Исключения могут возбуждаться и «вруч­ную» для того, чтобы сообщить о некоторых нештатных ситуациях.

К механизму обработки исключений в Java имеют отношение 5 клю­чевых слов: — try, catch, throw, throws и finally. Схема работы этого механизма следующая. Вы пытаетесь (try) выполнить блок кода, и если при этом возникает ошибка, система возбуждает (throw) исключение, ко­торое в зависимости от его типа вы можете перехватить (catch) или пере­дать умалчиваемому (finally) обработчику.

Ниже приведена общая форма блока обработки исключений.

try {

// блок кода }

catch (ТипИсключения1 е) {

// обработчик исключений типа ТипИсключения1 }

catch (ТипИсключения2 е) {

// обработчик исключений типа ТипИсключения2

throw(e) // повторное возбуждение исключения }

finally {

}

В вершине иерархии исключений стоит класс Throwable. Каждый из типов исключений является подклассом класса Throwable. Два непосредственных наследника класса Throwable делят иерархию подклассов исключений на две различные ветви. Один из них — класс Ехception — используется для описания исключительных ситуации, кото­рые должны перехватываться программным кодом пользователя. Другая ветвь дерева подклассов Throwable — класс Error, который предназначен для описания исклю­чительных ситуаций, которые при обычных условиях не должны перехватываться в пользовательской программе.

try-catch. Для задания блока программного кода, который требуется защитить от исключений, исполь­зуется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения которое вы хотите обрабатывать.

throw. Оператор throw используется для возбуждения исключения «вруч­ную». Для того, чтобы сделать это, нужно иметь объект подкласса клас­са Throwable, который можно либо получить как параметр оператора catch, либо создать с помощью оператора new.

throws. Если метод способен возбуждать исключения, которые он сам не об­рабатывает, он должен объявить о таком поведении, чтобы вызывающие методы могли защитить себя от этих исключений. Для задания списка исключений, которые могут возбуждаться методом, используется ключе­вое слово throws. Если метод в явном виде (т.е. с помощью оператора throw) возбуждает исключе­ние соответствующего класса, тип класса исключений должен быть ука­зан в операторе throws в объявлении этого метода.

finally . Иногда требуется гарантировать, что определенный участок кода будет выпол­няться независимо от того, какие исключения были возбуждены и пере­хвачены. Для создания такого участка кода используется ключевое слово finally. Даже в тех случаях, когда в методе нет соответствующего воз­бужденному исключению раздела catch, блок finally будет выполнен до того, как управление перейдет к операторам, следующим за разделом try. У каждого раздела try должен быть по крайней мере или один раз­дел catch или блок finally. Блок finally очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для времен­ного использования в начале выполнения метода.

Обработка исключений предоставляет исключительно мощный меха­низм для управления сложными программами. Try, throw, catch дают вам простой и ясный путь для встраивания обработки ошибок и прочих нештатных ситуаций в программную логи­ку.

7. Принципы ООП.

См. 4-ый вопрос.

8. Понятие абстракции.

См. 4-ый вопрос.

9. Понятие объекта. Ссылки. Инстанцирование. Удаление

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

Object - это экземпляр класса. В нашем примере - это может быть какая-то конкретная комната с конкретными размерами, причем количество комнат не ограничено. Предположим у нас есть два экземпляра комнат: спальня и кабинет. Теперь мы можем совершенно не зная с какой комнатой имеем дело узнать ее объем, т.к. вычисление объема - это свойство которое работает для любой комнаты.

Ссылка

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

Ссылки: слабые, мягкие, жёсткие, фантомные

Жёсткая. Если объект доступен через цепочку ссылок (как например объект, на который ссылается переменная buffer), то такая ссылка называется жесткой и сборщик мусора не станет уничтожать такой объект.

StringBuffer buffer = new StringBuffer();

Слабая ссылка - это ссылка, которая недостаточно сильна чтобы объект не собирался сборщиком мусора.

WeakReference<Thing> weakThing = new WeakReference<Thing>(thing);

Мягкая. По своей природе данный вид ссылок очень похож на слабые, с одним очень существенным отличием: объекты по ссылкам уничтожаются в том случае, когда память вашей программы заполнена и появляется вероятность получить OutOfMemoryError. Именно этот вид ссылок рекомендуется использовать для кэша.

SoftReference<Thing> thing = new SoftReference<Thing>(new Thing());

Фантомные ссылки достаточно сильно отличаются от слабых или мягких ссылок. Связь с объектами в этих ссылках такая слабая, что вы даже не сможете получить эти объекты - get() метод всегда будет возвращать null. Единственная область применения этих ссылок в отслеживании момента, когда ссылка помещается в очередь ReferenceQueue. Когда это происходит вы можете быть уверенным, что объект, на которой указывает ссылка, мертв.

PhantomReference<Thing> thing = new PhantomReference<Thing>(new Thing(), queue);

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]