Кто-нибудь может объяснить работу следующего кода ...? - PullRequest
6 голосов
/ 05 июня 2010

Кто-нибудь может объяснить работу следующего кода ...?

interface myInterface{}

public class Main {

    public static void main(String[] args) {

        System.out.println(new myInterface(){public String toString(){return "myInterfacetoString";}});

        System.out.println(new myInterface(){public String myFunction(){return "myInterfacemyFunction";}});
    }
}

Вывод ...

myInterfacetoString
primitivedemo.Main$2@9304b1

Все ответы о том, что myInterface в выражении println () является анонимным классом. Но поскольку я уже объявил его как интерфейс, почему он позволяет мне создавать анонимный класс с тем же именем ....?

еще раз ... если это анонимные классы, то класс main должен позволить мне дать любое имя этим анонимным классам ... Но если попытаться это сделать ... Я получаю ошибку компиляции

Ответы [ 4 ]

14 голосов
/ 05 июня 2010

Когда вы распечатываете объект, он вызывает метод toString (). В первом операторе вы создаете новый объект, а также переопределяете метод с именем toString. Поэтому этот метод toString () вызывается при печати объекта.

Во втором операторе вы также создаете объект, но не переопределяете метод toString (), чтобы он использовал метод toString () класса Object.

Для нового вопроса, эта ссылка имеет хорошее объяснение для вашего понимания: Анонимные классы

Вот копия объяснения:

new className(optional argument list){classBody}

Это выражение создает новый объект из неназванного и ранее неопределенного класса, который автоматически расширяет класс с именем className и который не может явно реализовать какие-либо интерфейсы . Тело нового класса задается classBody.

Результатом выполнения этого выражения является то, что определен новый класс , который расширяет className , создан экземпляр нового объекта нового класса и выражение заменено по ссылке на новый объект .

new interfaceName(){classBody}

Это выражение создает новый объект из неназванного и ранее неопределенного класса , который автоматически реализует интерфейс с именем interfaceName и автоматически расширяет класс с именем Object . Класс может явно реализовывать один и только один интерфейс , а не может расширять любой класс, кроме Object . Еще раз, тело нового класса дается classBody.

Вам теперь понятно?

3 голосов
/ 05 июня 2010

myAbstractClass - минимальный класс. Он наследуется от объекта.

Класс main создает два анонимных внутренних класса из myAbstractClass и печатает их вывод toString.

  1. Внутренний класс переопределяет метод toString, и вы видите его вывод.
  2. Внутренний класс получает метод, добавленный вами к стандартному определению toString.
3 голосов
/ 05 июня 2010

В первом println() вы переопределяете метод toString() из анонимного экземпляра myAbstractClass, поэтому вы получаете строку, возвращенную переопределенным методом toString(), это поведение по умолчанию для функции println().

На втором println() вы не переопределяете метод toString(), поэтому println() использует метод по умолчанию (унаследованный от Object).

Обратите внимание: попробуйте правильно отформатировать код, его намного легче читать и понимать.

abstract class myAbstractClass{}

public class Main { 
    public static void main(String[] args) { 
        System.out.println(new myAbstractClass(){
            public String toString(){
                return "myAbstractClass toString";
            }
        });

        System.out.println(new myAbstractClass(){
            public String myFunction(){
                return "myAbstractClass myFunction";
            }
        }); 
    } 
}
1 голос
/ 05 июня 2010

В обоих сценариях вы напечатали объект. Так он будет вызывать toString() метод объекта. В первом сценарии, поскольку вы переопределили метод toString(), значит, он печатает myAbstractClass toString. Во втором сценарии, поскольку он не был переопределен, он вызывает значение по умолчанию toString(), реализованное в классе Object.

Я думаю, что вы ожидаете вызова функции во втором сценарии, что неправильно. Вы только что изменили это, но никогда не звонили.

...