Чтение онлайн

на главную - закладки

Жанры

Программирование на Java
Шрифт:

}

package first;

// Класс Child наследуется от класса Parent,

// но имеет ограничение доступа по умолчанию

class Child extends Parent {

}

public class Provider {

public Parent getValue {

return new Child;

}

}

К методу getValue класса Provider можно обратиться и из другого пакета, не только из пакета first, поскольку метод объявлен как public. Данный метод возвращает экземпляр класса Child, который недоступен из других пакетов. Однако следующий вызов

является корректным:

package second;

import first.*;

public class Test {

public static void main(String s[])

{

Provider pr = new Provider;

Parent p = pr.getValue;

System.out.println(p.getClass.getName);

// (Child)p - приведет к ошибке компиляции!

}

}

Результатом будет:

first.Child

То есть на самом деле в классе Test работа идет с экземпляром недоступного класса Child, что возможно, поскольку обращение к нему делается через открытый класс Parent. Попытка же выполнить явное приведение вызовет ошибку. Да, тип объекта "угадан" верно, но доступ к закрытому типу всегда запрещен.

Следующий пример:

public class Point {

private int x, y;

public boolean equals(Object o) {

if (o instanceof Point) {

Point p = (Point)o;

return p.x==x && p.y==y;

}

return false;

}

}

В этом примере объявляется класс Point с двумя полями, описывающими координаты точки. Обратите внимание, что поля полностью закрыты – private. Далее попытаемся переопределить стандартный метод equals таким образом, чтобы для аргументов, являющихся экземплярами класса Point, или его наследников (логика работы оператора instanceof ), в случае равенства координат возвращалось истинное значение. Обратите внимание на строку, где делается сравнение координат,– для этого приходится обращаться к private -полям другого объекта!

Тем не менее, такое действие корректно, поскольку private допускает обращения из любой точки класса, независимо от того, к какому именно объекту оно производится.

Другие примеры разграничения доступа в Java будут рассматриваться по ходу курса.

Объявление классов

Рассмотрим базовые возможности объявления классов.

Объявление класса состоит из заголовка и тела класса.

Заголовок класса

Вначале указываются модификаторы класса. Модификаторы доступа для класса уже обсуждались. Допустимым является public, либо его отсутствие – доступ по умолчанию.

Класс может быть объявлен как final. В этом случае не допускается создание наследников такого класса. На своей ветке наследования он является последним. Класс String и классы-обертки, например, представляют собой final -классы.

После списка модификаторов указывается ключевое слово class, а затем имя класса – корректный Java-идентификатор. Таким образом, кратчайшим объявлением класса может быть такой модуль компиляции:

class A { }

Фигурные скобки обозначают тело класса, но о нем позже.

Указанный идентификатор становится простым именем класса. Полное составное

имя класса строится из полного составного имени пакета, в котором он объявлен (если это не безымянный пакет), и простого имени класса, разделенных точкой. Область видимости класса, где он может быть доступен по своему простому имени, – его пакет.

Далее заголовок может содержать ключевое слово extends, после которого должно быть указано имя (простое или составное) доступного не- final класса. В этом случае объявляемый класс наследуется от указанного класса. Если выражение extends не применяется, то класс наследуется напрямую от Object. Выражение extends Object допускается и игнорируется.

class Parent {

}

// = class Parent extends Object { }

final class LastChild extends Parent { }

// class WrongChild extends LastChild { }

// ошибка!!

Попытка расширить final -класс приведет к ошибке компиляции.

Если в объявлении класса A указано выражение extends B, то класс A называют прямым наследником класса B.

Класс A считается наследником класса B, если:

* A является прямым наследником B ;

* существует класс C, который является наследником B, а A является наследником C (это правило применяется рекурсивно).

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

Если компилятор обнаруживает, что класс является своим наследником, возникает ошибка компиляции:

// пример вызовет ошибку компиляции class

A extends B { }

class B extends C { }

class C extends A { }

// ошибка! Класс А стал своим наследником

Далее в заголовке может быть указано ключевое слово implements, за которым должно следовать перечисление через запятую имен (простых или составных, повторения запрещены) доступных интерфейсов:

public final class String implements Serializable, Comparable { }

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

Далее следует пара фигурных скобок, которые могут быть пустыми или содержать описание тела класса.

Тело класса

Тело класса может содержать объявление элементов (members) класса:

* полей;

* внутренних типов (классов и интерфейсов);

и остальных допустимых конструкций:

* конструкторов;

* инициализаторов

* статических инициализаторов.

Элементы класса имеют имена и передаются по наследству, не-элементы – нет. Для элементов простые имена указываются при объявлении, составные формируются из имени класса, или имени переменной объектного типа, и простого имени элемента. Областью видимости элементов является все объявление тела класса. Допускается применение любого из всех четырех модификаторов доступа. Напоминаем, что соглашения по именованию классов и их элементов обсуждались в прошлой лекции.

Поделиться:
Популярные книги

Возрастные кризисы

Малкина-Пых Ирина Германовна
Справочник практического психолога
Научно-образовательная:
психология
5.00
рейтинг книги
Возрастные кризисы

Отречение

Балашов Дмитрий Михайлович
6. Государи московские
Проза:
историческая проза
6.50
рейтинг книги
Отречение

Второгодка. Книга 4. Подавать холодным

Ромов Дмитрий
4. Второгодка
Фантастика:
героическая фантастика
альтернативная история
сказочная фантастика
5.00
рейтинг книги
Второгодка. Книга 4. Подавать холодным

Сухой лиман (сборник)

Катаев Валентин Петрович
Проза:
советская классическая проза
5.00
рейтинг книги
Сухой лиман (сборник)

Том 24. Письма 1895-1897

Чехов Антон Павлович
24. Полное собрание сочинений в тридцати томах
Проза:
русская классическая проза
5.00
рейтинг книги
Том 24. Письма 1895-1897

Я не бог. Книга XXXIV

Дрейк Сириус
34. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не бог. Книга XXXIV

Федор Алексеевич

Мосияш Сергей Павлович
Романовы. Династия в романах
Проза:
историческая проза
5.00
рейтинг книги
Федор Алексеевич

Газлайтер. Том 6

Володин Григорий Григорьевич
6. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 6

Корсаков

Кощеев Владимир
1. Корсаков
Фантастика:
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Корсаков

Анна Иоановна

Сахаров Андрей Николаевич
9. Романовы. Династия в романах
Проза:
историческая проза
5.60
рейтинг книги
Анна Иоановна

Лестница бога. Пенталогия

Киселев Юрий Львович
Вселенная EVE Online
Фантастика:
фэнтези
боевая фантастика
6.67
рейтинг книги
Лестница бога. Пенталогия

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович
Компьютеры и Интернет:
программирование
5.00
рейтинг книги
О чём не пишут в книгах по Delphi

Русь. Том I

Романов Пантелеймон Сергеевич
Проза:
советская классическая проза
5.00
рейтинг книги
Русь. Том I

Том 7. Пьесы 1873-1876

Островский Александр Николаевич
7. Собрание сочинений в шестнадцати томах
Поэзия:
драматургия
5.00
рейтинг книги
Том 7. Пьесы 1873-1876