- •Что такое Java?
- •История создания Java
- •Сложности внутри Sun Microsystems
- •Проект Green
- •Компания FirstPerson
- •Возрождение OaK
- •Java выходит в свет
- •История развития Java
- •Браузеры
- •Сетевые компьютеры
- •Платформа Java
- •Основные версии и продукты Java
- •Заключение
- •Методология процедурно-ориентированного программирования
- •Методология объектно-ориентированного программирования
- •Объекты
- •Состояние
- •Поведение
- •Уникальность
- •Инкапсуляция
- •Наследование
- •Полиморфизм
- •Типы отношений между классами
- •Агрегация
- •Ассоциация
- •Наследование
- •Метаклассы
- •Достоинства ооп
- •Недостатки ооп
- •Заключение
- •Кодировка
- •Анализ программы
- •Пробелы
- •Комментарии
- •Лексемы
- •Виды лексем
- •Идентификаторы
- •Ключевые слова
- •Литералы
- •Целочисленные литералы
- •Дробные литералы
- •Логические литералы
- •Символьные литералы
- •Строковые литералы
- •Null-литерал
- •Разделители
- •Операторы
- •Пример программы
- •Дополнение. Работа с операторами
- •Операторы присваивания и сравнения
- •Арифметические операции
- •Логические операторы
- •Битовые операции
- •Заключение
- •Введение
- •Имена Простые и составные имена. Элементы
- •Имена и идентификаторы
- •Область видимости (введение)
- •Элементы пакета
- •Платформенная поддержка пакетов
- •Модуль компиляции
- •Объявление пакета
- •Импорт-выражения
- •Объявление верхнего уровня
- •Уникальность имен пакетов
- •Область видимости имен
- •"Затеняющее" объявление (Shadowing)
- •"Заслоняющее" объявление (Obscuring)
- •Соглашения по именованию
- •Заключение
- •Введение
- •Модификаторы доступа
- •Предназначение модификаторов доступа
- •Разграничение доступа в Java
- •Объявление классов
- •Заголовок класса
- •Тело класса
- •Объявление полей
- •Объявление методов
- •Объявление конструкторов
- •Инициализаторы
- •Дополнительные свойства классов
- •Метод main
- •Параметры методов
- •Перегруженные методы
- •Заключение
- •Введение
- •Виды приведений
- •Тождественное преобразование
- •Преобразование примитивных типов (расширение и сужение)
- •Преобразование ссылочных типов (расширение и сужение)
- •Преобразование к строке
- •Запрещенные преобразования
- •Применение приведений
- •Присвоение значений
- •Вызов метода
- •Унарное числовое расширение
- •Бинарное числовое расширение
- •Явное приведение
- •Оператор конкатенации строк
- •Числовое расширение
- •Тип переменной и тип ее значения
- •Заключение
- •Статические элементы
- •Ключевые слова this и super
- •Ключевое слово abstract
- •Интерфейсы
- •Объявление интерфейсов
- •Реализация интерфейса
- •Применение интерфейсов
- •Полиморфизм
- •Полиморфизм и объекты
- •Заключение
- •Массивы как тип данных в Java
- •Объявление массивов
- •Инициализация массивов
- •Многомерные массивы
- •Класс массива
- •Преобразование типов для массивов
- •Ошибка ArrayStoreException
- •Переменные типа массив и их значения
- •Клонирование
- •Клонирование массивов
- •Заключение
- •Управление ходом программы
- •Нормальное и прерванное выполнение операторов
- •Блоки и локальные переменные
- •Пустой оператор
- •Оператор if
- •Оператор switch
- •Управление циклами
- •Цикл while
- •Цикл do
- •Цикл for
- •Операторы break и continue
- •Оператор continue
- •Оператор break
- •Именованные блоки
- •Оператор return
- •Оператор synchronized
- •Ошибки при работе программы. Исключения (Exceptions)
- •Причины возникновения ошибок
- •Обработка исключительных ситуаций Конструкция try-catch
- •Конструкция try-catch-finally
- •Использование оператора throw
- •Проверяемые и непроверяемые исключения
- •Создание пользовательских классов исключений
- •Переопределение методов и исключения
- •Особые случаи
- •Заключение
- •Введение
- •Дерево компонентов
- •Положение
- •Видимость
- •Доступность
- •Алгоритм отрисовки
- •Методы класса Graphics для отрисовки
- •Состояние Graphics
- •Clip (ограничитель)
- •Методы repaint и update
- •Прорисовка контейнера
- •Наследники класса Component
- •Класс Canvas
- •Класс Label
- •Класс Button
- •Классы Checkbox и CheckboxGroup
- •Классы Choice и List
- •Классы TextComponent, TextField, TextArea
- •Класс Scrollbar
- •Наследники Container
- •Класс Panel
- •Класс ScrollPane
- •Класс Window
- •Классы Frame и Dialog
- •Класс FileDialog
- •Обработка пользовательских событий
- •Событие ActionEvent
- •События awt
- •Обработка событий с помощью внутренних классов
- •Пример приложения, использующего модель событий
- •Апплеты
- •Жизненный цикл апплета
- •Передача параметров
- •Интерфейс AppletContext
- •Менеджеры компоновки
- •Класс FlowLayout
- •Класс BorderLayout
- •Класс GridLayout
- •Класс CardLayout
- •Заключение
- •Введение
- •Многопоточная архитектура
- •Базовые классы для работы с потоками Класс Thread
- •Интерфейс Runnable
- •Работа с приоритетами
- •Демон-потоки
- •Синхронизация
- •Хранение переменных в памяти
- •Модификатор volatile
- •Блокировки
- •Методы wait(), notify(), notifyAll() класса Object
- •Заключение
- •Введение
- •Классы-обертки
- •Системные классы
- •SecurityManager – менеджер безопасности
- •Потоки исполнения
- •Исключения
- •Заключение
- •Работа с датами и временем Класс Date
- •Классы Calendar и GregorianCalendar
- •Метод set(int field,int value).
- •Метод add(int field,int delta).
- •Метод roll(int field,int delta).
- •Класс TimeZone
- •Класс SimpleTimeZone
- •Интерфейс Observer и класс Observable
- •Коллекции
- •Интерфейсы Интерфейс Collection
- •Интерфейс Set
- •Интерфейс List
- •Интерфейс Map
- •Интерфейс SortedSet
- •Интерфейс SortedMap
- •Интерфейс Iterator
- •Aбстрактные классы, используемые при работе с коллекциями
- •Конкретные классы коллекций
- •Класс Collections
- •Класс Properties
- •Интерфейс Comparator
- •Класс Arrays
- •Класс StringTokenizer
- •Класс BitSet
- •Класс Random
- •Локализация Класс Locale
- •Класс ResourceBundle
- •Классы ListResourceBundle и PropertiesResourceBundle
- •Заключение
- •Система ввода/вывода. Потоки данных (stream)
- •Классы InputStream и OutputStream
- •Классы-реализации потоков данных Классы ByteArrayInputStream и ByteArrayOutputStream
- •Классы FileInputStream и FileOutputStream
- •Классы FilterInputStream и FilterOutputStream и их наследники
- •Сериализация объектов (serialization)
- •Стандартная сериализация
- •Восстановление состояния
- •Граф сериализации
- •Расширение стандартной сериализации
- •Классы Reader и Writer и их наследники
- •Класс StreamTokenizer
- •Работа с файловой системой Класс File
- •Класс RandomAccessFile
- •Заключение
- •Основы модели osi
- •Класс a
- •Класс b
- •Класс c
- •Подсети. Маска подсети
- •Протоколы arp, rarp
- •Утилиты для работы с сетью
- •Пакет java.Net
- •Заключение
Интерфейсы
Концепция абстрактных методов позволяет предложить альтернативу множественному наследованию. В Java класс может иметь только одного родителя, поскольку при множественном наследовании могут возникать конфликты, которые запутывают объектную модель. Например, если у класса есть два родителя, которые имеют одинаковый метод с различной реализацией, то какой из них унаследует новый класс? И какая будет функциональность родительского класса, который лишился своего метода?
Все эти проблемы не возникают в том случае, если наследуются только абстрактные методы от нескольких родителей. Даже если унаследовано несколько одинаковых методов, все равно у них нет реализации и можно один раз описать тело метода, которое будет использоваться при вызове любого из этих методов.
Именно так устроены интерфейсы в Java. От них нельзя порождать объекты, но другие классы могут реализовывать их.
Объявление интерфейсов
Объявление интерфейсов очень похоже на упрощенное объявление классов.
Оно начинается с заголовка. Сначала указываются модификаторы. Интерфейс может быть объявлен как public и тогда он будет доступен для общего использования, либо модификатор доступа может не указываться, в этом случае интерфейс доступен только для типов своего пакета. Модификатор abstract для интерфейса не требуется, поскольку все интерфейсы являются абстрактными. Его можно указать, но делать этого не рекомендуется, чтобы не загромождать код.
Далее записывается ключевое слово interface и имя интерфейса.
После этого может следовать ключевое слово extends и список интерфейсов, от которых будет наследоваться объявляемый интерфейс. Родительских типов может быть много, главное, чтобы не было повторений и чтобы отношение наследования не образовывало циклической зависимости.
Наследование интерфейсов действительно очень гибкое. Так, если есть два интерфейса, A и B, причем B наследуется от A, то новый интерфейс C может наследоваться от них обоих. Впрочем, понятно, что указание наследования от A является избыточным, все элементы этого интерфейса и так будут получены по наследству через интерфейс B.
Затем в фигурных скобках записывается тело интерфейса.
public interface Drawable extends Colorable,
Resizable {
}
Тело интерфейса состоит из объявления элементов, то есть полей-констант и абстрактных методов. Все поля интерфейса должны быть public final static, так что эти модификаторы указывать необязательно и даже нежелательно, чтобы не загромождать код. Поскольку поля объявляются финальными, необходимо их сразу инициализировать.
public interface Directions {
int RIGHT=1;
int LEFT=2;
int UP=3;
int DOWN=4;
}
Все методы интерфейса являются public abstract и эти модификаторы также необязательны.
public interface Moveable {
void moveRight();
void moveLeft();
void moveUp();
void moveDown();
}
Как мы видим, описание интерфейса гораздо проще, чем объявление класса.
Реализация интерфейса
Каждый класс может реализовывать любые доступные интерфейсы. При этом в классе должны быть реализованы все абстрактные методы, появившиеся при наследовании от интерфейсов или родительского класса, чтобы новый класс мог быть объявлен неабстрактным.
Если из разных источников наследуются методы с одинаковой сигнатурой, то достаточно один раз описать реализацию и она будет применяться для всех этих методов. Однако если у них различное возвращаемое значение, то возникает конфликт:
interface A {
int getValue();
}
interface B {
double getValue();
}
Если попытаться объявить класс, реализующий оба эти интерфейса, то возникнет ошибка компиляции. В классе оказывается два разных метода с одинаковой сигнатурой, что является неразрешимым конфликтом. Это единственное ограничение на набор интерфейсов, которые может реализовывать класс.
Подобный конфликт с полями-константами не столь критичен:
interface A {
int value=3;
}
interface B {
double value=5.4;
}
class C implements A, B {
public static void main(String s[]) {
C c = new C();
// System.out.println(c.value); - ошибка!
System.out.println(((A)c).value);
System.out.println(((B)c).value);
}
}
Как видно из примера, обращаться к такому полю через сам класс нельзя, компилятор не сможет понять, какое из двух полей нужно использовать. Но можно с помощью явного приведения сослаться на одно из них.
Итак, если имя интерфейса указано после implements в объявлении класса, то класс реализует этот интерфейс. Наследники данного класса также реализуют интерфейс, поскольку им достаются по наследству его элементы.
Если интерфейс A наследуется от интерфейса B, а класс реализует A, то считается, что интерфейс B также реализуется этим классом по той же причине – все элементы передаются по наследству в два этапа – сначала интерфейсу A, затем классу.
Наконец, если класс C1 наследуется от класса C2, класс C2 реализует интерфейс A1, а интерфейс A1 наследуется от интерфейса A2, то класс C1 также реализует интерфейс A2.
Все это позволяет утверждать, что переменные типа интерфейс также допустимы. Они могут иметь значение null, или ссылаться на объекты, порожденные от классов, реализующих этот интерфейс. Поскольку объекты порождаются только от классов, а все они наследуются от Object, это означает, что значения типа интерфейс обладают всеми элементами класса Object.
