Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Анонимные классы


Автор: Sherst 13.4.2006, 18:04
Привет всем!
Объясните пожайлуста принцип работы анонимных внутренних классов и зачем они используются.
Заранее спасибо.

Автор: garm 13.4.2006, 19:39
И тебе привет.
Анонимные внутренние классы - это внутренние классы без имени. Поэтому им приходится реализовывать какой либо интерфейс или расширять какой либо класс.
Выглядит это примерно так:
Код

Interface i = new Interface()
{
        public void method1()
        {
               //Реализация метода.
        }
        //Остальные методы.
}

Где Interface - некий интерфейс.
Наверное я не ошибусь, если скажу что основная область применения таких классов - реализация интерфейсов слушателей событий.
Подробнее можешь прочитать вот http://www.javaportal.ru/java/articles/inner.html.
Хотя некоторые люди считают, что использование анонимных внутренних классов - не очень хорошая практика.

Автор: batigoal 13.4.2006, 20:32
Цитата(garm @ 13.4.2006, 20:39 Найти цитируемый пост)
Хотя некоторые люди считают, что использование анонимных внутренних классов - не очень хорошая практика.

Поясню - они несколько ухудшают читабельность. Но зато позволяют избавиться от явного создания кучи мелких вспомогательных классов.

И еще одна небольшая добавка: при компиляции класса MainClass, содержащего анонимный внутренний класс, у тебя получится два class-файла: MainClass.class (основной) и MainClass$1.class (такое имя будет присвоено анонимному классу).

Автор: ALKS 13.4.2006, 22:24
Цитата(Lamer George @ 13.4.2006, 20:32)
Цитата(garm @  13.4.2006,  20:39 Найти цитируемый пост)
Хотя некоторые люди считают, что использование анонимных внутренних классов - не очень хорошая практика.

Поясню - они несколько ухудшают читабельность. Но зато позволяют избавиться от явного создания кучи мелких вспомогательных классов.

И еще одна небольшая добавка: при компиляции класса MainClass, содержащего анонимный внутренний класс, у тебя получится два class-файла: MainClass.class (основной) и MainClass$1.class (такое имя будет присвоено анонимному классу).

Я не согласен с тем что эта техника ухудшает читабельность. Я очень хорошо помню этот довод во временя споров Pascal vs C. {} по сравнению с begin end ухудшает читабельность. a?b:c по сравнению с полноценным if a then b else c ухудшает читабельность. не правда. стандартый синтаксис не может ухудшать читабельность. просто людей по-началу смущают не знакомые и не типичные синтаксические конструкции. но когда вы 100 раз в течении 8 часов примените a?b:c оно уже не будет вам казаться нечетабельным. оно будет пониматься влет на уровне подсознания. и с анономными внутринними классами тоже самое. когда начнеш активно применять этот синтаксис и привыкниш к нему он больше не будет резать глаз.

А для чего оно нужно? Для того чтоб не тратить силы на полноценное "оформление" относительно не больших и что самое главное однократно или почти однократно применяемых классов.
"Мелкий" тут не довод потому что меокий класс может быть применен в 200 местах по коду. тут прелесть именно в том что если вам вот именно тут один раз в жизни нужно использовтаь объект этого класса то... смысла тратить силы на его полноценное оформление? Особенно красота раскрываеться если у вас есть для примера некий интерфейс и 40 реализаций этого интерфейса но каждая конкретная реализация применяеться буквально единожды. вот в таких вот случаях анонимные внутренние классы просто спасают.

В java API есть много примеров грамотного использования этой идеи. классический пример это метод public File[] listFiles(FileFilter filter) класса java.io.File

Автор: Sherst 14.4.2006, 09:16
Расширяю анонимным классом обычный класс Test:

Код

class Test {
    public void dom (){
        System.out.println("In Test...");
    }
}


public class Main {        
    Main() {        
    }
  
    public Test getCls() {
        return new Test() {
           public void dom() {
               System.out.println("Reload");
           } 
           public void lop(){   //Здесь я добавил новый метод
               System.out.println("Lop...");
           }
        };
    }
    //
    public static void main(String[] args) {        
        Main g = new Main();
        Test v = g.getCls();  //доступно только v.dom()
    }    
}


Как теперь в main методе вызвать метод анонимного класса - lop() ?

Автор: LSD 14.4.2006, 09:59
Цитата(Sherst @ 14.4.2006, 10:16 Найти цитируемый пост)
Как теперь в main методе вызвать метод анонимного класса - lop() ?

Никак. Только через рефлексию, или объявить метод lop() в классе Test.

Автор: Sherst 14.4.2006, 18:05
Кому интересно, привожу пример вызова метода посредством использования рефлексии:

Код

package javaapplication7;
import java.lang.reflect.*;

class Test {
    public void dom (){
        System.out.println("In Test...");
    }
}

public class Main {        
    Main() {        
    }

    
    public Test getCls() {
        return new Test() {
           public void dom() {
               System.out.println("Reload");
           } 
           public void lop(){
               System.out.println("Lop...");
           }
        };
    }
    //
    public static void main(String[] args) {        
        Main g = new Main();        
        Method[] m = g.getCls().getClass().getDeclaredMethods();
        
        //public void javaapplication7.Main$2.lop() -полное наименование метода внутреннего анонимного класса, расширяющего Test
        for (int i=0; i < m.length; i++){
            if (m[i].toString().equals("public void javaapplication7.Main$2.lop()")) {
                try {
                    m[i].invoke(g.getCls(), null);
                } 
                catch(java.lang.IllegalAccessException ex){                    
                }
                catch(java.lang.reflect.InvocationTargetException er){                    
                }
            }                                    
        }
             
    }
}    

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)