2013-08-14 7 views
5

Зачем кому-то пользоваться inner class? Та же функциональность может быть достигнута с помощью local class или subclass.Как использовать внутренний класс на практике

Пример также будет оценен.

+0

Примером может служить пользовательский 'Comparator'. –

+0

http://www.javaworld.com/javaworld/javaqa/2000-03/02-qa-innerclass.html – JNL

ответ

10

Внутренних классов может быть использован во многих функциональных случаях. Они представляют два преимущества:

  1. Внутренний класс может видеть поля внешнего класса (если он не является статическим). Это означает, что вам не нужно иметь дело с полями внешнего класса, как если бы они поступали из внешнего класса. Это означает, что ваш внутренний класс нуждается в экземпляре внешнего класса для работы. Если вы статичны, то он ведет себя как независимый класс.
  2. Внутренний класс тесно связан с его собственным классом. Так что, даже если это статично, вы знаете по его названию, что это связано с его собственным классом.

С учетом этого вы можете понять, что внутренние классы должны использоваться там, где все вместе.

Таким образом, наиболее вероятным случаем является то, что вам не нужен внутренний класс вне внешнего класса. например:

class ScreenCapture { 
    class CaptureButtonListener implements ClickListener { 
    public void onClick(ClickEvent click) { 
     //..capture 
     pressCount++; 
    } 
    } 

    Button button = new Button("capture"); 
    int pressCount = 0; 

    void addListeners() { 
    button.addClickListener(new CaptureButtonListener()); 
    } 
} 

Как вы можете видеть:

  • вы никогда не будете нуждаться в CaptureButtonListener вне ScreenCapture. Так что лучше скрыть это (и даже объявить его закрытым или защищенным).
  • Внутренний класс обращается к полю, которое не принадлежит ему: pressCount. Это возможно, потому что его экземпляр привязан к экземпляру ScreenCapture: вы не можете создать new CaptureButtonListener() в статическом методе: вы обязаны использовать его в методах экземпляра.

С другой стороны, статический внутренний класс предназначен только для организационных целей (сказать, что оба класса связаны). Я адаптируюсь предыдущий пример со статическим внутренним классом:

public class ScreenCapture { 
    public static class CaptureButtonListener implements ClickListener { 
    protected ScreenCapture controller; 
    public CaptureButtonListener(ScreenCapture controller) { 
     this.controller = controller; 
    } 

    public void onClick(ClickEvent click) { 
     //..capture 
     controller.pressCount++; 
    } 
    } 

    Button button = new Button("capture"); 
    int pressCount = 0; 

    public void captureRequested() { 
    //do capture... 
    pressCount++; 
    } 

    void addListeners() { 
    button.addClickListener(new CaptureButtonListener(this)); 
    } 
} 

Обратите внимание, что в этом случае:

  • переменная pressCount не доступна из внутреннего класса больше: вы должны указать экземпляр это принадлежит.
  • Вы можете создать экземпляр CaptureButtonListener снаружи, но вы видите непосредственно от его имени: new ScreenCapture.CaptureButtonListener(screenCaptureInstance), что это связано с классом ScreenCapture (который улучшает читаемость кода)

Теперь вы можете задаться вопросом, почему вы должны создать внутренний класс, не может получить доступ к своим полям владельца?вы правы: это не очень мудро в нашем случае, так как вы обязаны передать экземпляр ScreenCapture в конструктор (чтобы вы не могли использовать его ни с каким другим классом, кроме ScreenCapture). Это просто продемонстрировать разницу.

Следующий пример даст предыдущий весь свой смысл:

Вы можете объявить прослушивателя как общественный статический интерфейс внутри ScreenCapture

class ScreenCapture { 
    public static interface class CaptureRequestListener { 
    public void captureRequested(ClickEvent click); 
    } 
} 

Таким образом, вы могли бы передать реализации ScreenCapture «как обрабатывать запрос на захват "

Опять же, реализации интерфейса будут знать, что они реализуют что-то конкретное для ScreenCapture, поскольку они будут реализовывать

public class MyImpl implements ScreenCapture.CaptureRequestListener { 
    public void captureRequested(ClickEvent click) { 
    // I will count requests instead 
    } 
} 

Таким образом, ваш код более четкий, чем его наличие в отдельном классе для организации файлов.

Вы также можете иметь класс обработки базы (абстрактную реализацию общих задач, как внутренний класс)

Я надеюсь, что все было понятно :-) С наилучшими пожеланиями, Zied

1

Внутренние классы относятся к классу, который объявляет их, поэтому в зависимости от вашей сферы действия вы решите создать внутренний класс. Да, вы можете создать локальный класс, если область видимости локальна для метода, поэтому принятие решения зависит от области видимости.

Я бы рекомендовал читать следующее для большего понимания и знания URL

1

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

Вы также должны проверить API-интерфейсы коллекции, чтобы увидеть его использование.

Смежные вопросы