Средства ООП

advertisement
Основы программирования на
языке Java
Средства ООП Java
(С) Всеволод Рылов, все права защищены
Новосибирск, 2004
1
Ключевые слова – статус
Ключевые слова, которые уже известны на текущий момент:
abstractdefault
do
double
else
extends
if
implements
import
instanceof
int
private
protected
public
return
short
this boolean
throw break
throws byte
transient case
try
catch
char
class
final
finally
float
interface
long
native
static
strictfp
super
void
volatile
while
const
goto
for
package
new
synchronized
switch
continue
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
2
Виды переменных







переменные классов (class variable - переменная-член
объявленная static )
переменные экземпляра (instance variable –
переменная-член класса объявленная без static)
компоненты массивов: int ia[] = new int[3]; ia[0]
параметры методов: void doSome(int i, Object o) {…}
параметры конструкторов: MyClass(Object param) {…}
параметры перехватчиков исключений: catch(Exception
ex) {…}
локальные переменные, объявленные внутри
методов, блоков, и в операторе for
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
3
Модификатор final


Переменная объявленная final может быть проинициализирована ровно
один раз, после этого ее значение изменить нельзя.
Если ссылка объявлена с модификатором final, то это не значит, что
нельзя изменить состояние объекта на который она ссылается! Нельзя
изменить лишь саму переменную ссылочного типа.
void unflow(boolean flag) {
final int k;
if (flag)
{
k = 3; System.out.println(k);
}
else
{
k = 4; System.out.println(k);
}
} // all ok
Новосибирск, 2004
void unflow(boolean flag) {
final int k;
if (flag)
{
k = 3; System.out.println(k);
}
if (!flag)
{
k = 4; System.out.println(k);
}
} //compile-time error!
(С) Всеволод Рылов, все права защищены
4
Объекты и значения ссылочного типа
Объекты - экземпляры классов (class instance) и массивы.
ClassInstanceCreationExpression:
new ClassOrInterfaceType ( ArgumentListopt ) ClassBodyopt
Primary.new Identifier ( ArgumentListopt ) ClassBodyopt
ArgumentList:
Expression
ArgumentList , Expression
//Создание объектов – экземпляров классов
class MyClass implements MyInterface {…}
MyClass myObj = new MyClass();
MyInterface anotherObj = new MyClass(“parameter”);
MyClass reflObj =
(MyClass)Class.forName(“MyClass”).newInstance();
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
5
Операции над ссылками







доступ к полю: obj.x = 10; super.y = 20;
вызов метода: obj.doSome(); super.doAnother();
преобразование типа: (Object)obj
строковый оператор + : String s = “one” + obj;
//вызывается метод obj.toString();
оператор проверки типа instanceof:
if (obj instanceof MyClass) {…} //Проверяется тип obj
операторы сравнения ссылок == и !=:
if (obj == obj2 && obj != obj3) {…}
условный тернарный оператор ? :
obj = ( obj2.size() < obj3.size() ) ? obj2: obj3;
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
6
Объекты – массивы: грамматика
ArrayCreationExpression:
new PrimitiveType DimExprs Dimsopt
new TypeName DimExprs Dimsopt
new PrimitiveType Dims ArrayInitializer
new TypeName Dims ArrayInitializer
DimExpr:
[ Expression ]
Dims:
[]
Dims [ ]
DimExprs:
DimExpr
DimExprs DimExpr
Индексация элементов массива начинается с 0 а не с 1 !!!
Диапазон допустимых значений индекса – от 0 до length - 1
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
7
Создание и инициализация массивов
// Создание массивов примеры:
// Создание объекта – массива из трех ссылок на объекты типа MyClass
MyClass array[] = new MyClass[3];
// Инициализация элемента массива (ссылки):
array[0] = new MyClass();
// Создание объекта – массива из двух ссылок на объекты-массивы
//ссылок на объекты класса MyClass
MyClass array2[][] = new MyClass[2][];
// Инициализация элементов 0 и 1 массива array2
array2[0] = new MyClass[5]; //объект – массив из 5 ссылок
array2[1] = new MyClass[4]; //объект – массив из 4 ссылок
// Объект - массив из трех элементов типа int
int array3[] = new int[3]; array3[0] = 0;
// Создание и инициализация массива из четырех элементов int
int array4 [] = new int [] {1,2,3,4};
// Создание и инициализация объекта-массива ссылок на объекты
//класса MyClass
MyClass array5[] = {new MyClass(“a”), new MyClass(“b”)};
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
8
Особенности использования массивов
Члены объектов-массивов:
 public final int length это поле содержит длину массива
 public Object clone() – создает копию массива
 + все методы класса Object.
Любой массив можно привести к классу Object или к массиву
совместимого типа.
class Test {
public static void main(String[] args) throws Throwable
{
int ia[][] = { { 1 , 2}, null };
int ja[][] = (int[][]) ia.clone();
System.out.print( (ia == ja) + "
");
System.out.println(ia[0] == ja[0] && ia[1] == ja[1]);
}
} // this program prints: false true
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
9
Особенности использования массивов
class Point { int x, y; }
class ColoredPoint extends Point { int color; }
class Test {
public static void main(String[] args)
{
ColoredPoint[] cpa = new ColoredPoint[10];
Point[] pa = cpa;
System.out.println(pa[1] == null);
try {
pa[0] = new Point();
} catch (ArrayStoreException e) {
System.out.println(e);
}
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
10
Классы




Классы объявляют новый ссылочный тип и определяют
его реализацию
Вложенный (nested) класс – это класс объявленный
внутри другого класса или интерфейса (в том числе
класс объявленный внутри метода или блока):
 member class – объявленный внутри класса
 local class – объявленный внутри метода
 anonymous class – не имеющий имени
Верхнеуровневый (top-level) класс – это класс, не
являющийся вложенным
Именованные (named) классы могут быть абстрактными
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
11
Классы


Каждый класс кроме Object является наследником
другого класса и может реализовывать (implements)
произвольное количество интерфейсов
Тело класса может содержать:
 члены (members):
поля
 методы
 вложенные классы и интерфейсы

инициализаторы экземпляра
 статические инициализаторы
 конструкторы
Видимость членов и конструкторов регулируется
модификаторами доступа public, private, protected


Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
12
Классы и наследование




Членами класса являются унаследованные и определенные в классе
члены
Вновь объявленные поля могут скрывать поля суперклассов и
суперинтерфейсов
Вновь объявленные методы могут скрывать, реализовывать или
перегружать методы, объявленные в суперклассе или
суперинтерфейсе
Вложенные классы бывают статическими и внутренними (inner), в
зависимости от контекста в котором они объявлены (если в точке
объявления имеет смысл ссылка this – то вложенный класс будет
внутренним)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
13
Методы






Методы описывают участки кода, которые могут быть вызваны с
помощью выражения вызова метода
Метод класса исполняется в контексте переменных класса (static
context)
Метод экземпляра исполняется в контексте конкретного объекта,
доступного по this
Методы не имеющие реализации должны быть объявлены abstract
Допускается перегрузка методов по списку и типам аргументов
Метод может иметь платформенно-зависимую реализацию (native
method)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
14
Статический контекст
public class MyClass
MyClass.s == 10
{
Static data
private int a,b;
private static int s =10;
public MyClass(int arg1, int arg2) {
a = arg1;
b = arg2;
}
public void changeA(int v) {
a = v;
}
public static void changeS(int v) {
s = v;
}
public static void main(String args[]) {
MyClass mc1 = new MyClass(2,3);
MyClass mc2 = new MyClass(4,5);
mc1.changeA(100);
mc2.changeA(200);
MyClass.changeS(25) ;
mc1.changeS(30);
mc2.changeS(40);
MyClass.s == 40
}
Static data
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
:MyClass
a == 2
b == 3
:MyClass
a == 4
b == 5
HEAP
:MyClass
a == 100
b == 3
:MyClass
a == 200
b == 5
HEAP
15
Конструкторы и инициализаторы

Инициализаторы экземпляра – блоки кода {…} выполняемые при
инициализации объекта. Выполняются перед вызовом конструктора.

Статические инициализаторы – статические блоки кода static {…}
выполняемые при первом использовании класса (после его загрузки
но перед созданием первого объекта или доступом к полю)

Конструкторы в отличие от методов не могут быть вызваны
непосредственно с помощью выражения вызова метода.
Конструкторы вызываются при создании экземпляров объектов и
могут быть перегружены
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
16
Грамматика объявления класса
ClassDeclaration:
ClassModifiersopt class Identifier Superopt Interfacesopt ClassBody
ClassModifiers:
ClassModifier
ClassModifiers ClassModifier
ClassModifier: one of
public protected private abstract static final strictfp
Super:
//Определяет «прямой суперкласс»
extends ClassType
Interfaces:
//Определяет «прямые суперинтерфейсы»
implements InterfaceTypeList
InterfaceTypeList:
InterfaceType
InterfaceTypeList , InterfaceType
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
17
Пример объявления класса
public abstract class MyClass extends Parent
implements MyInterface, AnotherInterface
{
static {
//Static initializer
}
{
//Non static initializer
}
public MyClass()
{
super(); //Вызов конструктора супер класса
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
18
Модификаторы объявления класса




public – класс доступен извне пакета.
abstract – класс является абстрактным (в нем есть абстрактные
методы)
final – класс является конечным в иерархии наследования. От него
нельзя унаследовать другой класс
strictfp – для всех методов класса действуют правила строгой
проверки арифметических выражений во время вычислений
Для вложенных(внутренних) классов дополнительно
действуют следующие модификаторы:



static – класс является статическим (вложенный класс)
protected – к классу имеют доступ только классы наследники
объемлющего класса или классы в том же пакете
private – к классу имеет доступ только объемлющий класс
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
19
Строгое определение абстрактного класса
Класс C является абстрактным, если:
 C явно содержит объявление абстрактного метода
 Какой-либо класс-родитель C содержит объявление
абстрактного метода, который не был реализован в
классе C или в его родительских классах
 «Прямой суперинтерфейс» C определяет или наследует
метод, который не реализован (и поэтому является
абстрактным) т.е. ни C ни его родительские классы не
определяют реализацию этого метода
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
20
Внутренние (inner) классы






Внутренний (inner) класс – это класс который ни явно,
ни неявно не является static
Внутренний класс не может содержать блоков
статической инициализации или членов-интерфейсов
Внутренний класс не может содержать статических
членов за исключением полей-констант времени
компиляции
Внутренние классы могут наследовать статические
члены, не являющиеся константами времени
компиляции
Члены-интерфейсы всегда являются static по
умолчанию
Вложенные классы могут свободно содержать
статические члены как и обычные классы Java
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
21
Пример вложенности классов
class HasStatic {
static int j = 100;
}
class Outer {
class Inner extends HasStatic {
static final int x = 3; //ok - compile-time constant
static int y = 4; //compile-time error, an inner class
}
static class NestedButNotInner{
static int z = 5; // ok, not an inner class
}
interface NeverInner{} // interfaces are never inner
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
22
Статический контекст


Выражение находится в статическом контексте, тогда
и только тогда, когда наиглубочайший включающий его
метод, конструктор, блок инициализации или
инициализатор поля является статическим методом,
статическим инициализатором или инициализатором
статической переменной соответсвенно.
Проще говоря, если в точке объявления класса имеет
семантику ссылка this на объект объемлющего класса,
то контекст объявления является динамическим (non
static) и класс будет внутренним.
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
23
Immediately enclosing instance




Внутренний класс C является непосредственным внутренним
классом (direct inner class of) класса O если O непосредственно
лексически включает класс C, и декларация C не находится в
статическом контексте. Класс C является внутренним классом (inner
class) класса O если это непосредственный внутренний класс
класса O либо является внутренним классом внутреннего класса O.
Класс O является лексически объемлющим классом порядка 0
(zeroth enclosing class of itself) для самого себя. Класс O является
лексически объемлющим классом порядка n (nth lexically enclosing
class) класса C если он является непосредственным объемлющим
классом для лексически объемлющего класса порядка n – 1 класса
C.
Экземпляр объекта i непосредственного внутреннего класса C
класса O всегда связан с объектом класса O, известным как
непосредственно объемлющий объект для i (the immediately
enclosing instance of i). Непосредственно объемлющий объект, если
таковой имеется, связывается с объектом при его создании.
Объект o является лексически объемлющим объектом порядка 0
(zeroth lexically enclosing instance) самого себя. Объект o является
лексически объемлющим объектом порядка n для объекта i, если
он является непосредственно объемлющим объектом для
лексически объемлющего объекта порядка n – 1 объекта i.
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
24
Immediately enclosing instance



Анологично, если суперкласс S класса C является
непосредственным внутренним классом класса SO, то существует
экземпляр SO, связанный с объектом i класса C, известный как
непосредственно объемлющий экземпляр по отношению к S (the
immediately enclosing instance of i with respect to S).
Непосредственно объемлющий экземпляр объекта по отношению к
его прямому суперклассу, если таковой имеет место быть,
определяется в момент вызова конструктора суперкласса
посредством вызова конструктора суперкласса по умолчанию.
Когда внутренний класс ссылается на переменную экземпляра
являющуюся членом лексически объемлющего класса,
используется переменная (поле) соответствующего лексически
объемлющего объекта. Неинициализированное final поле
объемлющего класса не может быть использовано в контексте
внутреннего класса.
Любая локальная переменная, формальный параметр метода, или
параметр перехватчика исключения используемые во внутреннем
классе, но объявленные в объемлющем, должны быть объявлены
со спецификатором final, и должны быть явно
проинициализированы до их использования в теле внутреннего
класса.
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
25
Пример – ограничение доступа
class Outer {
int i = 100;
static void classMethod() {
final int l = 200;
class LocalInStaticContext {
int k = i; // compile-time error
int m = l; // ok
}
}
void foo() {
class Local { // a local class
int j = i;
}
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
26
Пример – глубокая вложенность
class WithDeepNesting {
boolean toBe;
WithDeepNesting(boolean b) { toBe = b;}
class Nested {
boolean theQuestion;
class DeeplyNested {
DeeplyNested(){
theQuestion = toBe || !toBe;
}
}
}
}
Каждый экземпляр WithDeepNesting.Nested.DeeplyNested имеет
объемлющий объект класса WithDeepNesting.Nested (его
непосредственно объемлющий объект) и объемлющий объект –
экземпляр класса WithDeepNesting (объемлющий объект ранга 2).
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
27
Суперклассы и подклассы
Класс C является суперклассом класса A если верно одно из
следующих утверждений:
 A является непосредственным подклассом C.
 Существует класс B такой , что A является подклассом B, и B
является подклассом C, применяя это правило рекурсивно.
class Point { int x, y; }
class ColoredPoint extends Point { int color; }
final class Colored3dPoint extends ColoredPoint { int z; }
Класс Point является суперклассом класса ColoredPoint.
 Класс Point является суперклассом класса Colored3dPoint.
 Класс ColoredPoint является подклассом класса Point.
 Класс ColoredPoint является суперклассом класса Colored3dPoint.
 Класс Colored3dPoint является подклассом класса ColoredPoint.
 Класс Colored3dPoint является подклассом класса Point.

Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
28
Зависимость между классами
Классы и интерфейсы зависят по загрузке от других типов
(классов и интерфейсов), приведенных в декларации
наследования (extends и implements)
 Зависимость типов друг от друга может формировать цепочку:
 A зависит от B, B зависит от C тогда A зависит от C.
class B implements C {…}
class A extends B {…}
…
A theA = new A(); // Будут загружены интерфейс C и
//классы B и A
 Циклические зависимости вызывают ошибку времени компиляции:
class Point extends ColoredPoint { int x, y; }
class ColoredPoint extends Point { int color; }
 Если цикл обнаружен во время исполнения программы и загрузки
классов в JVM, то выбрасывается ошибка
ClassCircularityError

Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
29
Суперинтерфейсы класса

Суперинтерфейсами (родительскими интерфейсами)
для класса являются:
 Прямые суперинтерфейсы (объявленные
implements)
 Суперинтерфейсы прямых суперинтерфейсов
 Суперинтерфесы родительского класса

Говорят, что класс реализует все свои
суперинтерфейсы
У класса может быть несколько прямых
суперинтерфейсов:

interface One { void doIt();}
interface Two { void doIt(); void doAnother();}
class MyClass implements One, Two {
void doIt() {} //Общая реализация для One и Two
void doAnother{}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
30
Грамматика объявления тела класса
ClassBody:
{ ClassBodyDeclarationsopt }
ClassBodyDeclarations:
ClassBodyDeclaration
ClassBodyDeclarations ClassBodyDeclaration
ClassBodyDeclaration:
ClassMemberDeclaration
InstanceInitializer
StaticInitializer
ConstructorDeclaration
ClassMemberDeclaration:
FieldDeclaration
MethodDeclaration
ClassDeclaration
InterfaceDeclaration ;
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
31
Члены класса





Областью видимости члена m, объявленного или
унаследованного классом C, является тело класса C, включая
тела всех типов объявленных внутри C.
Если C сам по себе является вложенным классом, то объявления
одноименных членов (полей, методов или типов) m в
объемлющих областях видимости (блоках, классах или пакете)
будут сокрыты данным членом m класса С.
Членами класса являются:
 Члены, унаследованные от его прямого суперкласса
(исключением является класс Object не имеющий
суперклассов)
 Члены, унаследованные от его прямых суперинтерфейсов
 Члены, объявленные в теле класса
Члены класса объявленные private не наследуются подклассами.
Конструкторы и инициализаторы не являются членами и не
наследуются
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
32
Пример наследования членов
class Point {
int x, y;
private Point() { reset(); }
Point(int x, int y) { this.x = x; this.y = y; }
private void reset() { this.x = 0; this.y = 0; }
}
class ColoredPoint extends Point {
int color;
void clear() { reset(); } // error – reset() is private
} //error: ColoredPoint() {super();} – default constructor
class Test {
public static void main(String[] args) {
ColoredPoint c = new ColoredPoint(0,0);//error –
//ColoredPoint has no such constructor
c.reset(); //error – reset() is private
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
33
Наследование и доступ по умолчанию
package points;
public class Point {
int x, y;
public void move(int dx, int dy) {
x += dx; y += dy;
}
}
import points.*;
class Point4D extends Point3D {
int w;
public void move(int dx, int dy, int dz,
int dw) {
x+=dx; y+=dy; z+=dz; //error!
w+=dw;
}
}
Новосибирск, 2004
package points;
public class Point3D extends Point {
int z;
public void move(int dx, int dy, int dz) {
x += dx; y += dy; z += dz;
}
}
import points.*;
class Point4D extends Point3D {
int w;
public void move(int dx, int dy, int dz,
int dw) {
super.move(dx,dy,dz); //Good!
w+=dw;
}
}
(С) Всеволод Рылов, все права защищены
34
Поля-члены класса (грамматика)
FieldDeclaration:
FieldModifiersopt Type VariableDeclarators ;
VariableDeclarators:
VariableDeclarator
VariableDeclarators , VariableDeclarator
FieldModifiers:
FieldModifier
FieldModifiers FieldModifier
FieldModifier: one of
public protected private
static
final transient volatile
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
35
Статические поля
class Point {
int x, y, useCount;
Point(int x, int y) { this.x = x; this.y = y; }
final static Point origin = new Point(0, 0);
}
class Test {
public static void main(String[] args) {
Point p = new Point(1,1); Point q = new Point(2,2);
p.x = 3; p.y = 3; p.useCount++; p.origin.useCount++;
System.out.println("(" + q.x + "," + q.y + ")");
System.out.println(q.useCount);
System.out.println(q.origin == Point.origin);
System.out.println(q.origin.useCount);
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
36
Singleton (объект одиночка)

Данный шаблон используется для обеспечение
единственности объекта определенного класса
public class Singleton {
private static Singleton instance = null;
private Singleton(){} //никто не может вызвать конструктор
//все должны использовать данный метод для получения объекта
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
37
Поля-члены, объявленные final



Переменные классов(static) и переменные
экземпляров могут быть объявлены final
Статическая переменная, объявленная final
должна быть инициализирована непосредственно
при объявлении либо в блоке статической
инициализации
Переменная экземпляра, объявленная final должна
быть проинициализирована непосредственно при
объявлении либо в блоке инициализации, либо ей
должно быть присвоено значение к концу исполнения
каждого конструктора
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
38
Модификаторы volatile и transient
Переменные, объявленные transient не являются частью
persistent состояния объекта и не сохраняются во время
сериализации.
Для переменных, объявленных volatile, осуществляется
синхронизация локальной и главной копий при каждом обращении
к значению переменной в многопоточной среде.
class Test {
static int i = 0, j = 0;
static void one() { i++; j++; }
static void two() {
System.out.println("i=" + i
+ " j=" + j);
} // может напечатать j
} // большее, чем i
Новосибирск, 2004
class Test {
static volatile int i = 0, j = 0;
static void one() { i++; j++; }
static void two() {
System.out.println("i=" + i
+ " j=" + j);
} // i всегда >= j !!!
}
(С) Всеволод Рылов, все права защищены
39
Инициализация полей






Инициализация полей экземпляра происходит каждый раз при
создании нового объекта.
Инициализация статических полей класса происходит один раз при
первом использовании класса.
При инициализации поля экземпляра могут использовать
статические поля, т.к. они гарантированно инициализированы к
моменту создания объекта
При инициализации статические поля класса не могут использовать
поля экземпляра, а также ключевые слова this и super
Инициализация полей происходит в порядке объявления и в порядке
исполнения блоков инициализации. Константы времени компиляции
инициализируются первыми. Код конструкторов исполняется в
последнюю очередь
Стоит избегать зависимости от порядка инициализации полей
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
40
Разрешение перекрытия полей
class Point { static int x = 2; }
class Test extends Point {
static double x = 4.7;
public static void main(String[] args) {
new Test().printX();
}
void printX() {
System.out.println(x + " " + super.x);
}
}
Для доступа к полям, перекрытым при наследовании
можно использовать super, а также полную
квалификацию (super.x или Point.x)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
41
Множественное перекрытие
interface Frob { float v = 2.0f; }
class SuperTest { int v = 3; }
class Test extends SuperTest implements Frob {
public static void main(String[] args) {
new Test().printV();
}
void printV() {
System.out.println((super.v + Frob.v)/2);
}
}
При множественном перекрытии необходимо использовать
полную квалификацию
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
42
Грамматика объявления метода

Метод определяет участок исполняемого кода, который
может быть вызван с передачей фиксированного
количества параметров определенного типа
MethodDeclaration:
MethodHeader MethodBody
MethodHeader:
MethodModifiersopt ResultType MethodDeclarator Throwsopt
ResultType:
Type
void
MethodDeclarator:
Identifer ( FormalParameterListopt )

В классе может быть объявлен метод, имя которого
совпадает с именем члена-поля, вложенного класса,
интерфейса или другого метода (стоит избегать!!!)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
43
Сигнатура метода


Методы класса должны различаться по своей сигнатуре.
Сигнатура метода определяется его именем,
количеством параметров и типами этих параметров
FormalParameterList:
FormalParameter
FormalParameterList , FormalParameter
FormalParameter:
finalopt Type VariableDeclaratorId
VariableDeclaratorId:
Identifier
VariableDeclaratorId [ ]


Имена параметров метода должны быть различны
Список формальных параметров метода может быть
пуст
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
44
Параметры метода





Во время вызова метода вычисленные значения передаваемых
аргументов используются для инициализации переменныхпараметров метода
Таким образом всегда имеет место передача «по значению»
Область видимости параметра ограничивается методом, в котором
он объявлен. При этом доступ к нему осуществляется с помощью
обычного имени.
Параметры перекрывают собой поля-члены класса, в котором
объявлен метод, содержащий эти параметры. Для доступа к
перекрытым полям-членам нужно использовать this либо полное
квалифицированное имя
Параметры типов double и float всегда содержат значения из
множества double и float соответственно. Они не могут принимать
расширенных значений появляющихся во время вычисления
выражений не являющихся strictfp
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
45
Модификаторы метода
MethodModifiers:
MethodModifier
MethodModifiers MethodModifier
MethodModifier: one of
public protected private abstract static final synchronized native strictfp
Запрещенные комбинации:



два из public, protected, private
abstract с любым из: private, static, final, native, strictfp,
synchronized
native strictfp
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
46
Абстрактные методы


Абстрактный метод определяет сигнатуру и список выбрасываемых
исключений для метода, который должен быть реализован ниже по
иерархии наследования
Абстрактный класс может перегружать метод, оставляя (или делая)
его абстрактным и сохраняя его сигнатуру. При этом может
измениться список выбрасываемых исключений.
class BufferEmpty extends Exception {…}
class BufferError extends Exception {…}
public interface Buffer {
char get() throws BufferEmpty, BufferError;
}
public abstract class InfiniteBuffer implements Buffer
{
abstract char get() throws BufferError;
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
47
Осторожность при перегрузке
abstract class Point {
int x, y;
public abstract String toString();
}
class ColoredPoint extends Point {
int color;
public String toString() {
//ошибка – вызов абстрактного метода:
return super.toString() + ": color " + color;
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
48
Модификаторы метода (продолжение)

В статическом методе не может использоваться ссылка this

Ссылки super и this могут использоваться только в методах
объекта (т.е. методах, не объявленных static)
Метод, объявленный final, не может быть перегружен в классахнаследниках.

Никакой метод класса, объявленного final не может быть
перегружен (так как такой класс не может иметь наследников) и,
таким образом, все его методы являются final

По своей сути метод, объявленный private является final

Компилятор или оптимизатор могут использовать «inline»
подстановку для final и private методов, тем самым увеличивая
скорость исполнения программы
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
49
Модификаторы метода (продолжение)
native методы используются для реализации их тела в
платформенно-зависимой библиотеке, написанной на языке C, C++,
Fortran и т.д.
пример: файл производного доступа

package java.io;
public class RandomAccessFile implements DataOutput, DataInput
{
...
public native void open(String name, boolean writeable)
throws IOException;
public native int readBytes(byte[] b, int off, int len) throws IOException;
public native void writeBytes(byte[] b, int off, int len) throws IOException;
public native long getFilePointer() throws IOException;
public native void seek(long pos) throws IOException;
public native long length() throws IOException;
public native void close() throws IOException;
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
50
Модификаторы метода (окончание)


synchronized методы используются для реализации синхронных
классов-серверов (Параллелизм: класс-сервер может быть
последовательным, защищенным или синхронным)
strictfp определяет метод, в котором все вычисляемые
выражения float и double будут FP-strict. Это значит, что все
промежуточные результаты вычисления выражения будут являться
элементами множества float и double языка java и не могут
принадлежать к расширенному набору float или double, которые
может предоставлять конкретная платформа для обеспечения
высокой точности вычисления выражений с плавающей точкой. При
этом всегда будет происходит приведение промежуточного
результата к элементу множества float или double, либо возникнет
переполнение.
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
51
Выбрасываемые исключения

Список throws определяет исключения, которые должны
обрабатываться при вызове метода (checked exceptions)
Throws:
throws ClassTypeList
ClassTypeList:
ClassType
ClassTypeList , ClassType




Класс, объявленный в списке throws должен быть наследником
класса Throwable или самим классом Throwable
Классы-наследники RuntimeException можно не объявлять в
списке throws
Классы-наследники Error используются для сигнализации о сбое
машины и не должны использоваться в прикладном коде
Метод, перегружающий метод родительского класса или
реализующий метод интерфейса не может «расширять» список
throws (may not be declared to throw more checked exceptions)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
52
Тело метода
MethodBody:
Block
;




Метод, не объявленный как abstract или native должен иметь тело,
являющееся блоком
Метод, объявленный void не может содержать оператор вида
return Expression;
Метод, объявленный с возвращаемым типом Type должен
содержать выражение вида return Expression; на каждой
возможной ветви завершения метода. При этом тип результата
вычисления выражения Expression должен быть совместимым с
типом Type
В случае, если возможная ветвь метода завершается явным
выбросом исключения, выражение return Expression; может
быть опущено
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
53
Перегрузка методов (Overriding)


Перегрузка методов экземпляра (не статических методов):
Метод m1 класса C перегружает метод m2 класса A с той же
сигнатурой, тогда и только тогда, когда:

Класс C является наследником класса A

либо






m2 не является private и доступен из C
m1 перегружает m3, который перегружает m2 и
отличен от m1 и m2
Если m1 не является abstract, то говорят что он реализует
абстрактные методы, которые перегружает.
Для доступа к перегруженному методу используется super
Приведение к типу суперкласса содержащего объявление
перегруженного метода не обеспечивает вызов этого метода
(виртуальный полиморфизм) в отличие от обеспечения доступа к
сокрытым переменным
static, private, final методы не могут быть перегружены
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
54
Сокрытие методов (Hiding)



Если класс декларирует статический метод, то этот
метод скрывает методы с той же сигнатурой
объявленные в его суперклассах
Для доступа к сокрытому методу можно использовать
выражение со словом super, либо квалифицированное
имя, либо приведение к типу класса в котором этот
метод объявлен. В этом случае сокрытые методы ведут
себя также как и сокрытые поля
Статический метод не может скрывать метод
экземпляра (не являющийся статическим)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
55
Требования к перегрузке и сокрытию

Перегружаемые и скрываемые методы должны совпадать не только
по сигнатуре но и по возвращаемому значению

Перегружающий или перекрывающий метод должен иметь такой же,
либо более открытый уровень доступа:


public -> public

protected -> protected, public

package(default) -> package(default), protected, public
private методы не наследуются и не перегружаются поэтому могут
иметь совпадающую сигнатуру, но разные возвращаемые значения и
не совместимые списки throws на разных уровнях абстракции
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
56
Наследование нескольких методов с
одинаковой сигнатурой




Наследование нескольких методов с одинаковой сигнатурой не
всегда приводит к ошибке. При этом возможны следующие
варианты:
Если один из методов не является абстрактным, то:
 Если этот метод static то возникает ошибка времени
компиляции
 Иначе этот метод реализует (implements) или перегружает все
унаследованные методы. Если при этом выявляется
несовместимость по возвращаемому значению или списку
исключений, то возникает ошибка времени компиляции
Если метод абстрактный, то и класс является абстрактным и при
этом говорят что данный метод перегружает все унаследованные
методы. При этом также проверяется совместимость по
возвращаемому значению и списку выбрасываемых исключений
В языке java не может возникнуть ситуация, когда два из
наследуемых методов с одинаковой сигнатурой не являются
абстрактными (т.к. одиночное наследование)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
57
Overloading, Overriding, and Hiding
class Point {
int x = 0, y = 0;
int color;
void move(int dx, int dy) { x += dx; y += dy; }
}
class RealPoint extends Point {
float x = 0.0f, y = 0.0f; // hiding x and y
// overriding move
void move(int dx, int dy) {
move((float)dx, (float)dy);
}
//overloading move
void move(float dx, float dy) {
x += dx; y += dy;
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
58
Некорректное перекрытие
class Point {
int x = 0, y = 0, color;
void move(int dx, int dy) { x += dx; y += dy; }
int getX() { return x; }
int getY() { return y; }
}
class RealPoint extends Point {
float x = 0.0f, y = 0.0f;
void move(int dx, int dy) {
move((float)dx, (float)dy);
}
void move(float dx, float dy) {
x += dx; y += dy;
}
float getX() { return x; }
float getY() { return y; }
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
59
Вызов перегруженных методов
class Super {
static String greeting() { return "Goodnight"; }
String name() { return "Richard"; }
}
class Sub extends Super {
static String greeting() { return "Hello"; }
String name() { return "Dick"; }
}
class Test {
public static void main(String[] args) {
Super s = new Sub();
System.out.println(s.greeting() + ", "
+s.name() );
}
}
produces the output:
Goodnight, Dick
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
60
Несоответствие списков исключений
class BadPointException extends Exception {
BadPointException() { super(); }
BadPointException(String s) { super(s); }
}
class Point {
int x, y;
void move(int dx, int dy) { x += dx; y += dy; }
}
class CheckedPoint extends Point {
void move(int dx, int dy) throws BadPointException {
if ((x + dx) < 0 || (y + dy) < 0)
throw new BadPointException();
x += dx; y += dy;
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
61
Интерфейсы
InterfaceDeclaration:
InterfaceModifiersopt interface Identifier ExtendsInterfacesopt
InterfaceBody
InterfaceModifiers:
InterfaceModifier
InterfaceModifiers InterfaceModifier
InterfaceModifier: one of

public protected private abstract static strictfp
Допустимо множественное наследование интерфейсов:
ExtendsInterfaces:
extends InterfaceType
ExtendsInterfaces , InterfaceType



Все интерфейсы являются abstract
protected, static, private относятся только к членаминтерфейсам
Глобальные (не вложенные) интерфейсы являются public
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
62
Отношение наследования




Интерфейс I напрямую зависит от типа T если T присутствует в
списке extends интерфейса I как родительский интерфейс, либо как
квалификатор в имени родительского интерфейса.
Интерфейс I зависит от ссылочного типа T если выполняется одно
из условий:
 I напрямую зависит от T.
 I напрямую зависит от класса C который зависит от T.
 I напрямую зависит от интерфейса J который зависит от T
(применяя правило рекурсивно).
Интерфейс K является родительским (суперинтерфейсом)
интерфейса I если выполняется одно из условий:
 K является прямым суперинтерфейсом I.
 Существует интерфейс J такой что K является
суперинтерфейсом J, и J является суперинтерфейсом I,
применяя это правило рекурсивно
Интерфейс I называется подинтерфейсом (subinterface)
интерфейса K, если K является суперинтерфейсом I.
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
63
Тело и члены интерфейса
InterfaceBody:
{ InterfaceMemberDeclarationsopt }
InterfaceMemberDeclarations:
InterfaceMemberDeclaration
InterfaceMemberDeclarations InterfaceMemberDeclaration
InterfaceMemberDeclaration:
ConstantDeclaration
AbstractMethodDeclaration
ClassDeclaration
InterfaceDeclaration
;
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
64
Члены интерфейса




Членами интерфейса являются:
 Члены, объявленные в интерфейсе
 Члены унаследованные от прямых суперинтерфейсов
Если у интерфейса нет прямых суперинтерфейсов, то интерфейс
по умолчанию (неявно) декларирует public abstract метод m
сигнатуры s, возвращаемого типа r, и списка исключенийt для
каждого public instance метода m сигнатуры s, возвращаемого типа
r, и списка исключений t, объявленного в классе Object, кроме
таковых объявленных явно в этом интерфейсе.
Если интерфейс декларирует метод с той же сигнатурой, но с
отличным типом возвращаемого значения либо несовместимым
списком исключений то будет ошибка компиляции.
Интерфейс наследует от интерфейсов, которые расширяет
(extends) всех членов этих интерфейсов за исключением полей,
классов, интерфейсов которые он скрывает(hides) и методов,
которые перегружает(overrides).
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
65
Константные поля интерфейсов
ConstantDeclaration:
ConstantModifiersopt Type VariableDeclarators
ConstantModifiers:
ConstantModifier
ConstantModifiers ConstantModifer
ConstantModifier: one of


public static final
Фактически все поля интерфейса являются public static final
константами. Декларация данных спецификаторов является
избыточной.
В случае если интерфейс унаследует два и более поля с
одинаковыми именами от своих суперинтерфейсов, ошибка времени
компиляции будет иметь место только при попытке обращения к
этим полям по простому имени (без полной квалификации).
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
66
Инициализация полей интерфейсов



Каждое поле в теле интерфейса должно быть
проинициализировано выражением, значение которого должно
быть вычислено на стадии компиляции. При этом возможно
использование в выражении уже проинициализированных полей
самого интерфейса или его суперинтерфейсов.
Поля инициализируются в порядке их декларации за исключением
полей, явно инициализируемых константами.
В выражениях инициализации нельзя использовать ключевые
слова this и super кроме случая если эти слова используются
внутри декларации тела анонимного класса реализующего
интерфейс.
interface
float f
int j =
int k =
}
Test {
= j; //error – j используется до объявления
1;
k+1; //error – k инициализируется с использованием k
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
67
Неоднозначность при наследовании
interface BaseColors {
int RED = 1, GREEN = 2, BLUE = 4;
}
interface RainbowColors extends BaseColors {
int YELLOW = 3, ORANGE = 5, INDIGO = 6,
VIOLET = 7;
}
interface PrintColors extends BaseColors {
int YELLOW = 8, CYAN = 16, MAGENTA = 32;
}
interface LotsOfColors extends RainbowColors,
PrintColors {
int FUCHSIA = 17, VERMILION = 43, CHARTREUSE = RED+90;
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
68
Декларация абстрактных методов
AbstractMethodDeclaration:
AbstractMethodModifiersopt ResultType MethodDeclarator Throwsopt ;
AbstractMethodModifiers:
AbstractMethodModifier
AbstractMethodModifiers AbstractMethodModifier
AbstractMethodModifier: one of



public abstract
Фактически все методы интерфейса являются public abstract, и
использование данных спецификаторов является избыточным
Будьте осторожны при наследовании интерфейсом от своих
суперинтерфейсов методов с одинаковой сигнатурой но
несовместимыми возвращаемыми значениями или throws clauses
Все члены-классы и члены-интерфейсы, объявленные в
интерфейсе, являются static public по умолчанию и не могут быть
внутренними (inner)
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
69
Анонимные классы
public interface MyInterface {
void doIt();
}
public abstract class MyAbstractClass {
int i,j;
public MyAbstractClass (int i, int j)
{ this.i = i; this.j = j;}
public abstract void doAnother();
}
//Использование:
…
MyInterface impl = new MyInterface() {
void doIt() { System.out.println(“Hello!”); }
};
impl.doIt();
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
70
public class Main {
public static void main(String[] args) {
MyInterface myInterfaceImpl = new MyInterface () {
public void doIt () {
System.out.println("Hello!");
}
};
myInterfaceImpl.doIt();//prints: Hello!
MyAbstractClass myAbstractImpl = new MyAbstractClass() {
public void doAnother() {
System.out.println("Hello again! "+i+" "+j);
}
};
MyAbstractClass myAbstractImpl2
= new MyAbstractClass(5,6) {
public void doAnother() {
System.out.println("Hello again! "+i+" "+j);
}
};
myAbstractImpl.doAnother(); //prints: Hello again! 0 0
myAbstractImpl2.doAnother(); //prints: Hello again! 5 6
}
}
71
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
Перечисления (enum), начиная с java 1.5




В отличие от статических констант, предоставляют
типизированный, безопасный способ задания
фиксированных наборов значений
Являются классами специального вида, не могут иметь
наследников, сами в свою очередь наследуются от
java.lang.Enum. Не могут быть абстрактными и
содержать абстрактные методы, но могут реализовывать
интерфейсы
Экземпляры объектов перечисления нельзя создать с
помощью new, каждый объект перечисления уникален,
создается при загрузке перечисления в виртуальную
машину, поэтому допустимо сравнение ссылок для
объектов перечислений, можно использовать switch
Как и обычные классы могут реализовывать поведение,
содержать вложенные и внутренние классы-члены
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
72
Пример
public enum Days {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
SATURDAY;
public boolean isWeekend() {
switch(this) {
case SUNDAY:
case SATURDAY:
return true;
default:
return false;
}
}
}
…
System.out.println( Days.MODAY+” isWeekEnd(): “ +
Days.MONDAY.isWeekend() );
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
73
Перечисления (продолжение)



Каждый класс перечисления неявно содержит
следующие методы:
 values() - возвращает массив элементов
перечисления (статический метод)
 ordinal() - возвращает порядковый номер элемента
перечисления (в порядке декларации)
 valueOf(String name) – возвращает элемент
перечисления по его строковому имени (статический
метод, выбрасывает IllegalArgumentException
если нет элемента с указанным именем)
Класс перечисления может иметь конструктор (private
либо package), который вызывается для каждого
элемента при его декларации
Отдельные элементы перечисления могут
реализовывать свое собственное поведение
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
74
Пример более сложного перечисления
public enum Direction {
FORWARD(1.0) {
public Direction opposite() {return BACKWARD;}
},
BACKWARD(2.0) {
public Direction opposite() {return FORWARD;}
};
private double ratio;
Direction(double r) { ratio = r; }
public double getRatio() {return ratio;}
public static Direction byRatio(double r) {
if (r == 1.0) return FORWARD;
else if (r == 2.0) return BACKWARD;
else throw new IllegalArgumentException();
}
}
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
75
Пакеты: организация java программ







В типичном случае программа состоит из нескольких пакетов
Каждый пакет имеет собственное пространство имен для типов
объявленных в пакете
Верхнеуровневый тип доступен извне пакета только если он
объявлен со спецификатором public
Пакеты образуют иерархическую структуру имен.
Членами пакета являются:
 классы и интерфейсы, объявленные в единицах компиляции
пакета
 подпакеты, которые имеют свои собственные подпакеты и
единицы компиляции
Пакеты могут располагаться на файловой системе или в базе
данных
Пакеты размещаемые на файловой системе имеют ряд
ограничений на их организацию для обеспечения однозначности
при поиске и загрузке (а также компиляции) типов (и единиц
компиляции) и пакета
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
76
Пакеты: организация программ
com.somecompany.project
one
subpackage
First.java:
public class
First {...}
class Cls {...}
another
Third.java

Second.java
Filesystem:
/com
/somecompany
/project
/one
First.java
First.class
Cls.class
Second.java
Second.class
/subpackage
/another
Third.java
Third.class
При отображении (хранении) на файловой системе единица
компиляции может содержать тоьлко один тип объявленный
public совпадающий по имени с именем файла единицы
компиляции
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
77
Единицы компиляции



Пакет содержит несколько единиц компиляции
Типы внутри единицы компиляции имеют доступ ко
всем верхнеуровневым типам, объявленным в других
единицах компиляции данного пакета а также к типам
пакета java.lang
Для доступа к другим пакетам используется
декларация import
CompilationUnit:
PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt
ImportDeclarations:
ImportDeclaration
ImportDeclarations ImportDeclaration
TypeDeclarations:
TypeDeclaration
TypeDeclarations TypeDeclaration
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
78
Именованные и безымянные пакеты
Объявление именованного пакета:
PackageDeclaration:
package PackageName;

В качестве имени пакета выступает полное квалифицированное
имя: например com.somecompany.project.one для
First.java

Единицы компиляции безымянного пакета не содержат
объявление пакета
Безымянные пакеты следует использовать только в небольших
тестовых программах
Переменная окружения CLASSPATH содержит точки привязки
иерархий пакетов к точкам в файловой системе (коими могут
являться директории и архивные jar или zip файлы)
Классы находящиеся во всех «корневых» директориях точек
привязки CLASSPATH принадлежат к единому безымянному пакету



Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
79
Декларация import



Декларация имени пакета распространяется на всю единицу
компиляции
Декларации import также распространяются на всю единицу
компиляции
Для того чтобы получить доступ к членам подпакета в единице
компиляции, нужно явно импортировать эти члены. По
умолчанию они не видны
ImportDeclaration:
SingleTypeImportDeclaration
TypeImportOnDemandDeclaration
import java.io.InputStream; // single type import declaration
import java.net.*;
// import on demand declaration

Будучи импортированными типы становятся доступны
в единице компиляции с использованием простого (не
квалифицированного) имени.
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
80
Статический импорт (начиная с java 1.5)

Для того чтобы иметь возможность обращаться к
статическим методам, полям класса, а также к элементам
перечислений без использования квалифицированного
имени, можно воспользоваться статической декларацией
импорта:
import static Days.* ;
import static java.lang.Math.*;
…
Day d = MONDAY;
Day d2 = valueOf(“SATURDAY”);
double v = sin(PI/2);

Однако злоупотреблять статическим импортом не стоит
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
81
Сокрытие и конфликты import
single-type-import декларация d в единице компиляции c пакета p
импортирующая тип n, скрывает:
 любой верхнеуровневый тип n, объявленный в другой единице
компиляции пакета p
 любой тип n импортированный type-imoprt-on-demand
декларацией в c
 нельзя импортировать пакет, можно импортировать только типы:
import java.util; - ведет к ошибке времени компиляции


верхнеуровневые типы объявленные внутри единицы компиляции,
а также вложенные типы скрывают типы, импортируемые typeimport-on-demand декларацией, при использовании простого
имени.
для разрешения неоднозначности или доступа к сокрытому типу
можно воспользоваться квалифицированным именем
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
82
«Странный» пример
package Vector;
public class Mosquito {
int capacity;
}
package strange.example;
import java.util.Vector;
import Vector.Mosquito;
class Test {
public static void main(String[] args){
System.out.println(new Vector().getClass());
System.out.println(new Mosquito().getClass());
}
}
Вывод:
class java.util.Vector
class Vector.Mosquito
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
83
Двойная декларация
package test;
import java.util.Vector;
class Point {
int x, y;
}
interface Point { // compile-time error #1
int getR();
int getTheta();
}
class Vector { // compile-time error #2
Point[] pts;
}
--------------------------------------------------package test;
import java.util.*;
class Vector { Point[] pts; } // not a error
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
84
Опережающее использование
package points;
class Point {
int x, y; // coordinates
PointColor color; // color of this point
Point next; // next point with this color
static int nPoints;
}
class PointColor {
Point first; // first point with this color
PointColor(int color) {
this.color = color;
}
private int color; // color components
} //all is OK!
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
85
Правила именования пакетов


Для обеспечения уникальности имени пакета в качестве
основы следует использовать доменное имя организации,
например: ru.nsu.fit.mylastname.task1
В случае если доменное имя не может быть использовано в
силу наличия специальных символов, запрещенных к
использованию в идентификаторах, нужно произвести
следующую трансформацию:



если имя содержит знак ‘-’, его заменяют на ‘_’: some-ware.com ->
com.some_ware
если имя является ключевым словом, то к нему добавляют ‘_’:
do.something.com -> com.something.do_;
если имя начинается с цифры, то спереди добавляется ‘_’:
just.4you.com -> com._4you.just
Примеры имен:
com.sun.java.jag.scrabble
com.apple.quicktime.v2
com.novosoft.siberon.someproject

Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
86
Полное квалифицированное имя
Полным квалифицированным именем является:
 для примитивных типов – ключевое слово типа
 для именованного пакета первого уровня – простое имя этого
пакета
 для именованного пакета уровня N – полное квалифицированное
имя объемлющего пакета плюс простое имя пакета:
outer1.outer2.outerN-1.packagename
 для класса или интерфейса в безымянном пакете – простое имя
этого класса или интерфейса
 полное квалифицированное имя класса или интерфейса в
именованном пакете – это полное квалифицированное имя пакета
плюс простое имя класса или интерфейса:
outerpackage1...outerpackageN-1.packagename.ClassName
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
87
Полное квалифицированное имя
класс (интерфейс) – член другого класса имеет полное
квалифицированное имя только если таковое имеется у класса его
содержащего:
outerpackage1.….outerpackageN.OuterClass1.….OuterClassM.Member
исключение – безымянные классы
 Полное квалифицированное имя массива – это полное
квалифицированное имя компонентного типа с последующим []

Примеры полностью квалифицированных имен:
java.lang.Object
java.util.Map.Entry
int
java.lang.String[]
Новосибирск, 2004
(С) Всеволод Рылов, все права защищены
88
Download