いよいよ、抽象クラスとインターフェイスに突入、ポリモフィズム(多態性)に関わってくるところなのでしっかり理解したいところです。
抽象クラスの役割
継承のために親クラスを作ろうとすると、ある問題にぶち当たります。
問題その1. メソッドの内容
親クラスとして、Characterクラスを作成しようとすると、attack( )メソッドの内容が決められない問題に直面します。子クラスによってattack( )メソッドの内容は変わってくるはずですが、Characterクラスを作成の段階では、どんな子クラスが作られるか分からないためです。
問題その2.オーバーライドし忘れるのでは?
そんなん、子クラスで親クラスのメソッドをオーバーライドすれば全く問題ナッシィングでしょ。でも、もしかしたら子クラス側でオーバーライドし忘れるかも。
問題その3.親クラスをnewされる
親クラスは、子クラスの継承元として使って欲しいと思っていたとしても他の人が誤ってnew演算子でインスタンス化してしまうかもしれません。
そこで、抽象クラスの出番です。抽象クラスを使うことで、この問題をすべて解決してくれます。
解決その1.親クラスでabstractメソッドが使える
解決その2.子クラスでオーバーライドの強制
親クラスでabstractメソッドを指定することで、子クラスでメソッドのオーバーライドを強制できます。
解決その3.abstractクラスはインスタンス化が禁止されている
インターフェイス
定数と抽象メソッドしか記述できないという、インターフェイス。
使いどころは?
クリーニングのチェーン店の例がとても分かりやすかったです。
public interface CleaningService { Shirt washShirt(Shirt s); Towl washTowl(Towl t); Coat washCoat(Coat c); }
public class Shirt { }
public class Towl { }
public class Coat { }
public class TokyoCleaning implements CleaningService { private String ownerName; private String address; private int phone; public Shirt washShirt(Shirt s) { System.out.println("大型選択機10分"); System.out.println("業務用乾燥機30分"); System.out.println("スチームアイロン20分"); return s; } public Towl washTowl(Towl t) { return t; } public Coat washCoat(Coat c) { return c; } }
public class KyotoCleaning implements CleaningService { private String ownerName; private String address; private int phone; public Shirt washShirt(Shirt s) { System.out.println("洗濯板10時間"); System.out.println("物干しざお1日"); System.out.println("足で踏む2時間"); return s; } public Towl washTowl(Towl t) { return t; } public Coat washCoat(Coat c) { return c; } }
複数の子クラスで共通のメソッドを実装させられ、且つ子クラスそれぞれでメソッドの処理内容を変えることができます。
あと、インターフェースは多重継承が許されています。
クラスが複数インターフェイスを継承する場合
public class MickyMouse implements Human, Mouse, Character { }
public interface Person extends Pinapple { }
クラス同士の継承と同じく、インターフェース同士の継承もextendsになるようです。
extends、implementsの両方を使う場合
public class IOTA extends BitCoin implements P2P, Tangle, M2M { }
今回はこのへんで。