Конструкторы во внутренних классах (реализация интерфейсов)

Как я могу написать конструктор для внутреннего класса, который реализует интерфейс? Я знаю, что могу создать совершенно новый класс, но я полагаю, что есть способ сделать что-то по этому поводу:

JButton b = new JButton(new AbstractAction() {

    public AbstractAction() {
        super("This is a button");                        
    }


    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

Когда я вхожу в это, он не распознает метод AbstractAction как конструктор (компилятор запрашивает тип возврата). У кого-нибудь есть идея?

Ответ 1

Просто вставьте параметры после имени расширенного класса:

JButton b = new JButton(new AbstractAction("This is a button") {

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

Кроме того, вы можете использовать блок инициализации:

JButton b = new JButton(new AbstractAction() {

    {
       // Write initialization code here (as if it is inside a no-arg constructor)
       setLabel("This is a button")
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

Ответ 2

Если вам действительно нужен конструктор по какой-либо причине, вы можете использовать блок инициализации:

JButton b = new JButton(new AbstractAction() {

    {
        // Do whatever initialisation you want here.
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

Но вы не можете вызвать конструктор суперкласса оттуда. Как сказал Итай, вы можете просто передать аргумент, который вы хотите, в призыв к новому.

Лично, я бы создал для этого новый внутренний класс:

private class MyAction extends AbstractAction {

    public MyAction() {
        super("This is a button.");
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}

то

JButton b = new JButton(new MyAction());

Ответ 3

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

Это похоже на нормальное расширение/реализацию: если вы определяете class House extends Building и строите House, вы называете конструктор House, а не Building (или AbstractAction, чтобы вернуться к исходному вопросу).

Ответ 4

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