Программирование на Java
Шрифт:
Напротив, со статическим контекстом ассоциированных объектов нет. Например, как уже указывалось, стартовый метод main вызывается в тот момент, когда ни один объект еще не создан. При обращении к статическому методу, например, MyClass.staticMethod, также может не быть ни одного экземпляра MyClass. Обращаться к статическим методам класса Math можно, а создавать его экземпляры нельзя.
А раз нет ассоциированных объектов, то и пользоваться динамическими конструкциями нельзя. Можно только ссылаться на статические поля и вызывать статические методы. Либо обращаться к объектам через ссылки на них, полученные
class Test {
public void process {
}
public static void main(String s[]) {
// process;
– ошибка!
// у какого объекта его вызывать?
Test test = new Test;
test.process;
// так правильно
}
}
Ключевые слова this и super
Эти ключевые слова уже упоминались, рассматривались и некоторые случаи их применения. Здесь они будут описаны более подробно.
Если выполнение кода происходит в динамическом контексте, то должен быть объект, ассоциированный с ним. В этом случае ключевое слово this возвращает ссылку на данный объект:
class Test {
public Object getThis {
return this;
// Проверим, куда указывает эта ссылка
}
public static void main(String s[]) {
Test t = new Test;
System.out.println(t.getThis==t);
// Сравнение
}
}
Результатом работы программы будет:
true
То есть внутри методов слово this возвращает ссылку на объект, у которого этот метод вызван. Оно необходимо, если нужно передать аргумент, равный ссылке на данный объект, в какой-нибудь метод.
class Human {
public static void register(Human h) {
System.out.println(h.name+
" is registered.");
}
private String name;
public Human (String s) {
name = s;
register(this);
// саморегистрация
}
public static void main(String s[]) {
new Human("John");
}
}
Результатом будет:
John is registered.
Другое применение this рассматривалось в случае "затеняющих" объявлений:
class Human {
private String name;
public void setName(String name) {
this.name=name;
}
}
Слово this можно использовать для обращения к полям, которые объявляются ниже:
class Test {
// int b=a; нельзя обращаться к
// необъявленному полю!
int b=this.a;
int a=5;
{
System.out.println("a="+a+", b="+b);
}
public static void main(String s[]) {
new Test;
}
}
Результатом работы программы будет:
a=5, b=0
Все
Наконец, слово this применяется в конструкторах для явного вызова в первой строке другого конструктора этого же класса. Там же может применяться и слово super, только уже для обращения к конструктору родительского класса.
Другие применения слова super также связаны с обращением к родительскому классу объекта. Например, оно может потребоваться в случае переопределения (overriding) родительского метода.
Переопределением называют объявление метода, сигнатура которого совпадает с одним из методов родительского класса.
class Parent {
public int getValue {
return 5;
}
}
class Child extends Parent {
// Переопределение метода
public int getValue {
return 3;
}
public static void main(String s[]) {
Child c = new Child;
// пример вызова переопределенного метода
System.out.println(c.getValue);
}
}
Вызов переопределенного метода использует механизм полиморфизма, который подробно рассматривается в конце этой лекции. Однако ясно, что результатом выполнения примера будет значение 3. Невозможно, используя ссылку типа Child, получить из метода getValue значение 5, родительский метод перекрыт и уже недоступен.
Иногда при переопределении бывает полезно воспользоваться результатом работы родительского метода. Предположим, он делал сложные вычисления, а переопределенный метод должен вернуть округленный результат этих вычислений. Понятно, что гораздо удобнее обратиться к родительскому методу, чем заново описывать весь алгоритм. Здесь применяется слово super. Из класса наследника с его помощью можно обращаться к переопределенным методам родителя:
class Parent {
public int getValue {
return 5;
}
}
class Child extends Parent {
// переопределение метода
public int getValue {
// обращение к методу родителя
return super.getValue+1;
}
public static void main(String s[]) {
Child c = new Child;
System.out.println(c.getValue);
}
}
Результатом работы программы будет значение 6.
Обращаться с помощью ключевого слова super к переопределенному методу родителя, т.е. на два уровня наследования вверх, невозможно. Если родительский класс переопределил функциональность своего родителя, значит, она не будет доступна его наследникам.
Поскольку ключевые слова this и super требуют наличия ассоциированного объекта, т.е. динамического контекста, использование их в статическом контексте запрещено.
Ключевое слово abstract
Следующее важное понятие, которое необходимо рассмотреть,– ключевое слово abstract.
Иногда имеет смысл описать только заголовок метода, без его тела, и таким образом объявить, что данный метод будет существовать в этом классе. Реализацию этого метода, то есть его тело, можно описать позже.