abstractとinterface
interfaceとabstract
あれ?同じじゃね?と風呂場で思ったので調べてみた。
- interface
- abstract
とりあえずinterfaceとabstractの違いを知りたくてコード叩いてみたから載せる
interface編
interfaceは、inplementするクラスのメソッドを制限して再利用性を高めるために使うものっぽい
interfaceは型として使える
Listはインターフェース、ArrayListはそれを実装したクラス
だからinterface分かってそうな人はこう書く
List<String> list = new ArrayList<String>();
interface分かってなさそうな人はこう書くはず(Java勉強しはじめのオレ)
ArrayList<String> list = new ArrayList<String>();
ぶっちゃけArrayListしか使わないならこれでいいけど、もしかしたらLinkedList使いたくなるかもしれないし、データはデータで考えを分けたい。これだとlistのデータを扱うときArrayListに依存するから気持ち悪い。
ポリモーフィズム?
あと、オブジェクトに対する操作が限定されるので、Implementsしたクラスの使い方はどれも一緒。
なのでまとめて処理を行うとき、interfaceを使うと便利らしい
List<Hello> helloList = new ArrayList<Hello>(); helloList.add(new HelloJapan("こんにちは")); helloList.add(new HelloEu("hello")); helloList.add(new HelloOkinawa("はいさい")); for(Hello hello : helloList) { hello.sayHello(); }
ポリモーフィズムの考えが適用されている。
以下コード
/** * HelloInterface */ public interface HelloInterface { public void sayHello(); // public String message; だとダメな理由って? // 分かった、単体でインスタンス化することがあるから、その時に困るからだ public String message = "hello"; }
/** * HelloInterface実装クラス */ public class HelloInpl implements HelloInterface { // HelloInterfaceで定義されているメソッドしか実装できない @Override public void sayHello() { System.out.println("hello"); System.out.println(message); } }
/** * メインクラス */ public class Main { public static void main(String[] args) { HelloInpl hello = new HelloInpl(); hello.sayHello(); } }
Abstract編
Abstractは、Abstractメソッドを持つクラス。
継承するクラスはAbstractメソッドを必ずオーバーライドしないといけない。
なんか作りかけのクラスって感じですな
/** * HelloAbstractクラス */ public abstract class HelloAbstract { // Abstractは変数初期化しなくていいんだ… public String message; public abstract void sayHello(); }
/** * HelloAbstractの具象クラス */ public class Hello extends HelloAbstract { @Override public void sayHello() { System.out.println("hello"); } // メソッドを増やしてもOK! public void sayHelloWorld() { System.out.println("HelloWorld!!"); return; } }
public class Main extends Hello { public static void main(String[] args) { Hello hello = new Hello(); hello.sayHello(); hello.sayHelloWorld(); } }
まとめ
自由度 : Abstract >> Interface
- Interfaceは自由を制限して再利用性を上げるための物
- extendsは一つしかできない
- implementsは複数OK
- でもextendsしたクラスをextendsはできるんだよなー、多重継承禁止、でも継承したクラスの継承はOK。継承は一つづつやろうってことかな。
- Abstractクラスはインスタンス化できない
- Interfaceはインスタンス化できる。型として使う。
Abstractっていつ使うのか分かんない。
作りはしないけど、フレームワーク使うときにEclipse先輩に怒られて@overrideする感じ?
Template Methodパターンに答えがありそうな気がする、それ学ぼう。
戯言
実際作るとき、interfaceって非常に面倒くさい
パシ!と作ってリファクタリングの時に色々やる、ってやり方はまずいかなぁ
TDDがテストケースを書いてコーディングを始めるのように、interfaceを先に書いてクラス作る、とかあるのかな?