Конструкторы во внутренних классах (реализующие интерфейсы) - PullRequest
21 голосов
/ 15 июня 2010

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

JButton b = new JButton(new AbstractAction() {

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


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

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

Ответы [ 4 ]

35 голосов
/ 15 июня 2010

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

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");
    }
}); 
9 голосов
/ 15 июня 2010

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

JButton b = new JButton(new AbstractAction() {

    {
        // Do whatever initialisation you want here.
    }

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

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

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

private class MyAction extends AbstractAction {

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

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

then:

JButton b = new JButton(new MyAction());
4 голосов
/ 15 июня 2010

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

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

1 голос
/ 30 ноября 2015

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

...