Edited at

インターフェースをnewする違和感が解決した

More than 3 years have passed since last update.

いまさらですが、すっきりしたので。

Androidのプログラムを書いていて、以下のコードに疑問をもっていた。

button.setOnClickListener(new View.OnClickListener() {...});

ん...?インターフェースをnewするの?

と思って、ずっとモヤモヤしてたけど、ちょっと調べたら解決した。

例えば、Javaの入門書などで「インターフェースはインスタンス化できない」ふむふむ...なるほど...。と素直に勉強した人にとっては、以下のようなコードに戸惑うでしょう。


public class Person {
public static void main( String args[] ) {
Greet greet = new Greet() {
public void sayHello(){
System.out.println("こんにちわ!");
}
};
greet.sayHello();
}
}

interface Greet {
public void sayHello();
}

あれ...?インターフェースをnewしてるじゃん!...と。

本来はこう書きますよね↓


public class Person {
public static void main( String args[] ) {
Encount greet = new Greet();
greet.sayHello();
}
}

class Greet implements Encount {
@Override public void sayHello(){
System.out.println("こんにちわ!");
}
}

interface Encount {
public void sayHello();
}

実は、最初の不思議なコードは匿名クラスをnewしているんです。

匿名クラスとは、名前を持たないクラス。その場限りで、宣言と同時にオブジェクトの生成を行う。


匿名クラス[無名クラス]とは


なので、見た目的にインターフェースをnewしているように見えて、

実は、インターフェースを継承した名前の無いクラスをnewしていただけ。だったのです。

種明かしをされるとなんてことは無いんですが、僕みたいにJavaほとんどやらずにいきなりAndroidの開発を始めた者は、Javaの文法でたまに悩まされます。年末年始にでもちゃんとJava勉強しないとなぁ...。

おわり。