Анонимный запрос Inner Class для уточнения - PullRequest
2 голосов
/ 28 февраля 2011

При изучении TTS на Android я наткнулся на следующий фрагмент кода:

    speakBtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
        }});

Я действительно новичок в Java, поэтому мой уровень уверенности в определении различных конструкций не так уж велик.Я думаю, что я вижу выше Anonymous Inner Class , но ' new OnClickListener () ' меня смущает.Поэтому, пожалуйста, подтвердите и / или исправьте любое из следующего понимания:

  1. Внутренний класс определяется сразу после нового OnClickListener ().
  2. OnClickListener - это суперкласс, из которого внутренний класс
  3. (Анонимный) внутренний класс имеет только одну функцию-член: OnClick ().
  4. Что такое @Override внутри определения внутреннего класса?Если это аннотация, то я смущен, так как этот ответ утверждает, что анонимные внутренние классы не могут быть аннотированы.

Наконец, есть ли способ написать приведенный выше фрагмент вчто проще для расшифровки для n00b как я?

Ответы [ 5 ]

4 голосов
/ 28 февраля 2011
  1. Да; это определено между фигурными скобками.
  2. Да, за исключением того, что это интерфейс, а не класс.
  3. Да.
  4. Вы не можете добавлять аннотации на уровне класса .
    @Override является аннотацией уровня метода *1013*, которая отлично работает.
3 голосов
/ 28 февраля 2011

Ну, в основном этот фрагмент кода создает класс, имя которого искажено компилятором для вашего удобства, так что вам не нужно заботиться о присвоении ему имени самостоятельно. Этот класс будет реализовывать интерфейс OnClickListener и содержать реализацию метода onClick (View), как того требует интерфейс.

Таким образом, ваш фрагмент может быть написан примерно так:

class OnClickListenerThingy01 implements OnClickListener { // name is invented from the top of my head and corresponds actual name manging in no way
    @Override
    public void onClick(View view) {
        mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
    }
}
speakBtn.setOnClickListener(new OnClickListenerThingy01());

Аннотация @Override не помещается в сам класс - который не имеет декларации в вашем коде, которую можно добавить, генерируемой компилятором, - но в методе.

Аннотация @Override используется для пометки переопределений (как это ни удивительно) и реализации методов. Его основное назначение - генерировать ошибку компилятора, если изменяется сигнатура переопределенного метода, но вы не можете соответствующим образом обновить объявление переопределения, чтобы вы не удивились, когда переопределения не сработали, потому что, скажем, что было переопределено было переименовано.

В случае реализации интерфейса, если вы забудете полностью реализовать интерфейс, компилятор все равно выдаст ошибку, поэтому @Override может показаться немного избыточным, но это не так. На самом деле, это довольно приятно иметь, чтобы ненужные методы (например, когда объявление метода удалено из интерфейса) не оставались в вашем коде.

Хотя следует отметить, что IDE, такая как Eclipse, скорее всего, сделает эти проблемы недействительными, поскольку предоставленных инструментов рефакторинга более чем достаточно, чтобы избежать такой ситуации. В любом случае, @Override очень приятно иметь при себе методы, когда его можно использовать.

2 голосов
/ 28 февраля 2011

Вот способ переписать ваш фрагмент, который делает его намного понятнее "нубу":)

class MyOuterClass {
    private class MyOnClickListener implements OnClickListener {
        @Override
        public void onClick(View view) {
            mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
        }
    }

    // later (inside some method)...
        speakBtn.setOnClickListener(new MyOnClickListener());
}
1 голос
/ 28 февраля 2011
  • Внутренний класс определяется сразу после нового OnClickListener ().

Думайте о коде, описывающем безымянный подкласс OnClickListener (). Определение класса находится в скобках, как вы и думали.

  • OnClickListener - это суперкласс, из которого происходит внутренний класс.

Да

  • (Анонимный) внутренний класс имеет только одну функцию-член: OnClick ().

Да, но это не обязательно так. Может иметь больше функций-членов.

  • Что такое @Override внутри определения внутреннего класса? Если это аннотация, то я запутался, поскольку в этом ответе говорится, что анонимные внутренние классы не могут быть аннотированы.

@ Override используется для проверки ошибок во время компиляции в методах. Вы можете использовать аннотации уровня метода для анонимного внутреннего класса.

0 голосов
/ 28 февраля 2011

OnClickListener - это суперкласс, из которого происходит внутренний класс

Не совсем: OnClickListener не является классом.Этот синтаксис используется для создания экземпляра нового (анонимного) класса, который реализует интерфейс OnClickListener.Таким образом, у вас есть только один метод для реализации: onClick ().

...