f():
Как здесь Java определит, какая из версий метода f() должна выполняться? И поймет ли читатель программы, что происходит при этом вызове? Именно из-за подобных проблем перегруженные методы не разрешается различать по возвращаемым значениям.
Конструкторы по умолчанию
Как упоминалось ранее, конструктором по умолчанию называется конструктор без аргументов, применяемый для создания «типового» объекта. Если созданный вами класс не имеет конструктора, компилятор автоматически добавит конструктор по умолчанию. Например:
//• initialization/DefaultConstructor.java class Bird {}
public class DefaultConstructor {
public static void main(String[] args) {
Bird b = new BirdO. // по умолчанию!
}
} ///-Строка
new BirdO;
создает новый объект и вызывает конструктор по умолчанию, хотя последний и не был явно определен в классе. Без него не существовало бы метода для построения объекта класса из данного примера. Но если вы уже определили некоторый конструктор (или несколько конструкторов, с аргументами или без), компилятор не будет генерировать конструктор по умолчанию:
//: initi alizati on/NoSynthesi s.java
class Bird2 {
Bird2(int i) {} Bird2(double d) {}
}
public class NoSynthesis {
public static void main(String[] args) {
//! Bird2 b = new Bird2(); // Нет конструктора по умолчанию! Bird2 Ь2 = new Bird2(l); Bird2 ЬЗ = new Bird2(1.0);
}
Теперь при попытке выполнения new Bird2() компилятор заявит, что не может найти конструктор, подходящий по описанию. Получается так: если определения конструкторов отсутствуют, компилятор скажет: «Хотя бы один конструктор необходим, позвольте создать его за вас». Если же вы записываете конструктор явно, компилятор говорит: «Вы написали конструктор, а следовательно, знаете, что вам нужно; й если вы создали конструктор по умолчанию, значит, он вам и не нужен».
Ключевое слово this
Если у вас есть два объекта одинакового типа с именами а и Ь, вы, возможно, заинтересуетесь, каким образом производится вызов метода peel() для обоих объектов:
//: initialization/BananaPeel.java
class Banana { voi'd peel (int i ){/*...*/} }
public class BananaPeel {
public static void main(String[] args) {
Banana a = new BananaO, b = new BananaO;
a.peel(l);
b.peel(2);
}
} ///:-
Если существует только один метод с именем peel(), как этот метод узнает, для какого объекта он вызывается — а или Ь?
Чтобы программа могла записываться в объектно-ориентированном стиле, основанном на «отправке сообщений объектам», компилятор выполняет для вас некоторую тайную работу. При вызове метода peel() передается скрытый первый аргумент — не что иное, как ссылка на используемый объект. Таким образом, вызовы указанного метода на самом деле можно представитьткак:
Banana.рееКаЛ);
Banana.peel(b,2);
Передача дополнительного аргумента относится к внутреннему синтаксису. При попытке явно воспользоваться ею компилятор выдает сообщение об ошибке, но вы примерно представляете суть происходящего.
Предположим, во время выполнения метода вы хотели бы получить ссылку на текущий объект. Так как эта ссылка передается компилятором скрытно, идентификатора для нее не существует. Но для решения этой задачи существует ключевое слово — this. Юночевое слово this может использоваться только внутри не-статического метода и предоставляет ссылку на объект, для которого был вызван метод. Обращаться с ней можно точно так же, как и с любой другой ссылкой на объект. Помните, что при вызове метода вашего класса из другого метода этого класса this вам не нужно; просто укажите имя метода. Текущая ссылка this будет автоматически использована в другом методе. Таким образом, продолжая сказанное:
//: initialization/Apricot.java public class Apricot {
void pickO { /* .. */ } void pit() { pickO; /*..*/} } ///:-
Внутри метода pit() можно использовать запись this.pick(), но в этом нет необходимости 9. Компилятор сделает это автоматически. Ключевое слово this употребляется только в особых случаях, когда вам необходимо явно сослаться на текущий объект. Например, оно часто применяется для возврата ссылки на текущий объект в команде return:
//: initialization/Leaf.java // Simple use of the "this" keyword.
public class Leaf { int i = 0; Leaf increment О { i++;
return this;
}
void printO {
System, out. printlnC'i = " + i).
}
public static void main(String[] args) { Leaf x = new LeafO;
x.i ncrement().i ncrement() i ncrement().pri nt О;
}
} /* Output: i = 3 *///:-
Так как метод increment() возвращает ссылку на текущий объект посредством ключевого слова this, над одним и тем же объектом легко можно провести множество операций.
Ключевое слово this также может пригодиться для передачи текущего объекта другому методу:
//. initialization/PassingThis java
class Person {
public void eat(Apple apple) {
Apple peeled = apple.getPeeledО; System.out.println("Yummy");
}
Читать дальше