Java: クラス群の設計ーabstract class, interface を使った継承と実装の組合わせの可能性
プログラムを設計していると、いろいろなクラスを作成することになる。このクラス群をどのように作成するかを考えてみたいと思います。今、特に、具体的問題があるわけではないので、とりあえず、どのような可能性があるかを検討したいと思います。
洗い出した幾つかのクラスは似ていることが多く共通部分があることが多い。その共通部分をクラス継承の親クラス、またそれぞれのクラスを子クラスと考える。また、クラスのメソッドを整理しまとめ、インターフェースとし、それに入れるべきメソッドをアブストラクトメソッドとして用意するとする。
以下はそれらの可能性を探るプログラムコードです。
interface inter1{ void show1(); void show2(); } interface inter2{ void show3(); void show4(); } interface inter3{ void show5(); void show6(); } interface inter4{ void show7(); void show8(); } abstract class Abst_Class1 implements inter1 { private int num1; Abst_Class1(int n){this.num1=n;} public void show1(){ System.out.println("show1 num1=" + num1 ); } public abstract void show2(); } class Class1 extends Abst_Class1 { private String s1; Class1(int n, String s){ super(n); this.s1 = s; } public void show2(){ show1(); System.out.println("show2 s1="+s1); } } class Class2 extends Abst_Class1 { private String s2; Class2(int n, String s){ super(n); this.s2 = s; } public void show2(){ show1(); System.out.println("show2 s2="+s2); } } abstract class Abst_Class2 implements inter2 { private int num2; Abst_Class2(int n){this.num2=n;} public void show3(){ System.out.println("show3 num2=" + num2 ); } public abstract void show4(); } class Class3 extends Abst_Class2 { private String s3; Class3(int n, String s){ super(n); this.s3 = s; } public void show4(){ show3(); System.out.println("show4 s3="+s3); } } class Class4 extends Abst_Class2 { private String s4; Class4(int n, String s){ super(n); this.s4 = s; } public void show4(){ show3(); System.out.println("show4 s4="+s4); } } class Class5 implements inter3{ private int num3; private String s5; Class5(int n,String s){this.num3=n;this.s5=s;} public void show5(){ System.out.println("show5 num3=" + num3); } public void show6(){ show5(); System.out.println("show6 s5="+s5); } } class SuperClass6{ protected int num4; SuperClass6(int n){this.num4=n;} } class Class6 extends SuperClass6 implements inter4{ private String s4; Class6(int n, String s){super(n);this.s4=s;} public void show7(){ System.out.println("show7 num4="+num4); } public void show8(){ show7(); System.out.println("show8 s4="+s4); } } class Class7{ private int num5; private String s5; Class7(int n,String s){this.num5=n;this.s5=s;} void show9(){ System.out.println("show9 num5=" + num5); } void show10(){ show9(); System.out.println("show10 s5="+s5); } } class Proo12_1{ public static void main(String args[]){ Class1 f1 = new Class1(1, "Tokyo"); Class2 f2 = new Class2(2, "Yokohama"); Class3 f3 = new Class3(3,"Nagoya"); Class4 f4 = new Class4(4,"Gifu"); Class5 f5 = new Class5(5,"Osaka"); Class6 f6 = new Class6(6,"Fukuoka"); Class7 f7 = new Class7(7,"Kumamoto"); f1.show2(); f2.show2(); f3.show4(); f4.show4(); f5.show6(); f6.show8(); f7.show10(); } } /* 出力 show1 num1=1 show2 s1=Tokyo show1 num1=2 show2 s2=Yokohama show3 num2=3 show4 s3=Nagoya show3 num2=4 show4 s4=Gifu show5 num3=5 show6 s5=Osaka show7 num4=6 show8 s4=Fukuoka show9 num5=7 show10 s5=Kumamoto */
1.Class1からClass4
これらはインターフェースを実装したabstract classを経て作成したクラスです。それぞれのabstract classはそこで実装したメソッドとフィールドを持ち、子クラス(Class1からClass4)はそこで実装したメソッドと追加したフィールドを持っています。このようにすると、二段階の実装ができることになります。早くから仕様が明らかになったものを先に実装するということです。フィールドはすべてprivate にして保護しています。
2.Class5
このクラスはinter3の二つのabstract メソッドを実装しています。abstractメソッドは同じ名前で別のクラスに別機能のメソッドとして実装することができるので、show5, show6はこの名前で別のクラスに実装してもよい。
3.Class6
これは単に継承と実装を同時に行う例です。まず、SuperClass6を作成しておいて、それを継承しinter4を実装しています。SuperClass6はnum4を設定するアクセスメソッドを持っていないので、privateにできず、やむを得ず、num4をprotectedにしています。
4.Class7
このクラスは抽象クラスやインターフェースを使わないクラスです。