Эти ключевые слова уже упоминались, рассматривались и некоторые случаи их применения. Здесь они будут описаны более подробно.
Если выполнение кода происходит в динамическом контексте, то должен быть объект, ассоциированный с ним. В этом случае ключевое слово this возвращает ссылку на данный объект:
class Test {public Object getThisO {return this; // Проверим, куда указывает эта ссылка}
public static void main(Sthng s[]) {Testt = newTestO;
То есть внутри методов слово this возвращает ссылку на объект, у которого этот метод вызван. Оно необходимо, если нужно передать аргумент, Равный ссылке на данный объект, в какой-нибудь метод.
class Human {public static void register(Human h){System.out.println(li.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 а=5; {
Все происходит так же, как и для статических полей — b получает значение по умолчанию для а, т.е. ноль, а затем а инициализируется значением 5.
Наконец, слово this применяется в конструкторах для явного вызова впервой строке другого конструктора этого же класса. Там же может применяться и слово super, только уже для обращения к конструктору родительского класса.
Другие применения слова super также связаны с обращением к родительскому классу объекта. Например, оно может потребоваться в случае переопределения (overriding) родительского метода.
Переопределением называют объявление метода, сигнатура которого совпадает с одним из методов родительского класса.
class Parent {public int getValueO { return 5;} }
class Child extends Parent { // Переопределение метода public int getValueO {return 3; }
public static void main(String s[]) { Childc = newChild{);
// пример вызова переопределенного метода System.ourprintln(c.getValue{));} }
Вызов переопределенного метода использует механизм полиморфизма, который подробно рассматривается в конце этой лекции. Однако ясно, что результатом выполнения примера будет значение 3. Невозможно, используя ссылку типа Child, получить из метода getVaue() значение 5, родительский метод перекрыт и уже недоступен.
Иногда при переопределении бывает полезно воспользоваться результатом работы родительского метода. Предположим, он делал сложные вычисления, а переопределенный метод должен вернуть округленный результат этих вычислений. Понятно, что гораздо удобнее обратиться к родительскому методу, чем заново описывать весь алгоритм. Здесь применяется слово super. Из класса наследника с его помощью можно обращаться к переопределенным методам родителя:
class Parent {public intgetValue{) { return 5;} }
class Child extends Parent {// переопределение метода public intgetValueO {// обращение к методу родителя return supergetValue()+1; }
public static void main(String s[]) {Childc = newChild();
System.ourprintln(c.getValue()); } }
Результатом работы программы будет значение 6.
Обращаться с помощью ключевого слова super к переопределенному методу родителя, т.е. на два уровня наследования вверх, невозможно. Если родительский класс переопределил функциональность своего родителя, значит, она не будет доступна его наследникам.
Поскольку ключевые слова this и super требуют наличия ассоциированного объекта, т.е. динамического контекста, использование их в статическом контексте запрещено.