インタフェースに関する問題です。
1.インタフェースの作成
次のアウトプットとソースコードに整合するようにインタフェース、IPhone,IBrouser,ICamera,IMusicPlayerを作りなさい。
SmartPhoneクラスは各々のインタフェースの抽象メソッドをオーバーライドしているものとします。
<アウトプット>
| 音楽を再生する Webを見る 電話を受ける 電話をかける 写真を撮影する 写真を表示する  | 
<ソースコード>
package p12;
class SmartPhone implements IPhone, IBrouser, ICamera, IMusicPlayer {
    public void brouseWeb() {
        System.out.println("Webを見る");
    }
    public void showPictures() {
        System.out.println("写真を表示する");
    }
    public void takePicture() {
        System.out.println("写真を撮影する");
    }
    public void callPhone() {
        System.out.println("電話をかける");
    }
    public void recievePhone() {
        System.out.println("電話を受ける");
    }
    public void playMusic() {
        System.out.println("音楽を再生する");
    }
}
public class Q01 {
    public static void main(String[] args) {
        SmartPhone sp = new SmartPhone();
        sp.playMusic();
        sp.brouseWeb();
        sp.recievePhone();
        sp.callPhone();
        sp.takePicture();
        sp.showPictures();
    }
}2.オリジナルクラスの作成
IPhoneをimplementsしたMyPhoneクラス、
IBrouserをimplementsしたMyBrouserクラス、
ICameraをimplementsしたMyCameraクラス、
IMusicPlayerをimplementsしたMyMusicPlayerクラスをそれぞれ作りなさい
3.Comparableインタフェースの実装
以下のクラスを作成しなさい。
スーパークラス abstract Figure
役割:図形を表現する抽象クラス。 java.lang.Comparableインタフェースを実装する。
フィールド
| フィールド名 | アクセス修飾子 | 型 | 役割 | 
| area | protected | double | 図形の面積を保持する(面積は少数第2位四捨五入1位表示) | 
メソッド
| メソッド名 | アクセス修飾子 | 戻り値の型 | 役割 | 
| compareTo(Object o) | public | int | Comparableインタフェースの同名メソッドの実装(オーバーライド) | 
サブクラス1 Rectangle extends Figure
役割:図形の一種である四角形を表現する。
フィールド
| フィールド名 | アクセス修飾子 | 型 | 役割 | 
| x | private | double | 四角形の横幅を保持する | 
| y | private | double | 四角形の縦幅を保持する | 
コンストラクタ
役割:全てのフィールドを適切に初期化する
メソッド
| メソッド名 | アクセス修飾子 | 戻り値の型 | 役割 | 
| toString() | public | String | Rectangle{area=xx.x}という文字列表現を返す。(オーバーライド) | 
サブクラス2 Circle extends Figure
役割:図形の一種である円を表現する。
フィールド
| フィールド名 | アクセス修飾子 | 型 | 役割 | 
| r | private | double | 円の半径を保持する | 
コンストラクタ
役割:全てのフィールドを適切に初期化する
メソッド
| メソッド名 | アクセス修飾子 | 戻り値の型 | 役割 | 
| toString() | public | String | Circle{area=xx.x}という文字列表現を返す。(オーバーライド) | 
<テストクラスの例>
package p12;
public class Q03 {
    public static void main(String[] args) {
        Figure[] fg = new Figure[2];
        fg[0] = new Rectangle(7.0, 10.0);
        fg[1] = new Circle(5.0);
        if (fg[0].compareTo(fg[1]) > 0) {
            System.out.println(fg[0] + "のほうが" + fg[1] + "より大きいです。");
        } else if (fg[0].compareTo(fg[1]) == 0) {
            System.out.println("同じ大きさです。");
        } else {
            System.out.println(fg[1] + "のほうが" + fg[0] + "より大きいです。");
        }
    }
}<結果の例>
| Circle{area=78.5}のほうがRectangle{area=70.0}より大きいです。 | 
4.委譲を使って依存性を無くす(Dependency Injection)
依存性の注入(DI)とは、オブジェクト指向プログラミングの設計パターンの1つで、オブジェクトの依存関係を外部から注入します。
DIを使用すると、クラスが必要とする依存関係を外部で定義し、クラス自体がそれを作成する責任を負わなくて済むため、いくつかのメリットがあります。
例えば、下記の例ではオブジェクトが必要とする依存関係を簡単に切り替えることができるようにしています。そうすることで、コードの再利用性が向上し、より柔軟なアプリケーションを作成することができています。
MyOs version2を搭載したMyPad、MyMac、MyPhoneがある。(以下、各機器と略す)
各機器のクラスは以下の通りである。(各自クラス図を書いて確認して欲しい)
package p12;
public class MyOsV2 {
    public void startMyOs() {
        System.out.println("MyOs version2を起動します。");
    }
}package p12;
public class MyPad {
    MyOsV2 os = new MyOsV2();
    public void doAsMyPad() {
        os.startMyOs();
        System.out.println("MyPad特有の機能を実行.");
    }
}package p12;
public class MyMac {
    MyOsV2 os = new MyOsV2();
    public void doAsMyMac() {
        os.startMyOs();
        System.out.println("MyMac特有の機能を実行..");
    }
}package p12;
public class MyPhone {
    MyOsV2 os = new MyOsV2();
    public void doAsMyPhone() {
        os.startMyOs();
        System.out.println("MyPhone特有の機能を実行...");
    }
}以下は、上記クラスのテストクラスである。
package p12;
public class Q04 {
    public static void main(String[] args) {
        new MyPad().doAsMyPad();
        new MyMac().doAsMyMac();
        new MyPhone().doAsMyPhone();
    }
}このとき、OSをバージョンアップして以下のMyOsV3にしたい。
package p12;
class MyOsV3{
    public void startMyOs() {
        System.out.println("MyOs version3を起動します。");
    }
}しかし、今のままでは、OSと各機器が密結合してしまっており、OSを替えるにはそれぞれの機器のコードを修正する必要がある。
そこで、以下のクラス図を参考に、依存性を無くしてほしい。
つまり、OSのバージョンが3,4,5と上がったとしても各機器のクラスを変更する必要がないようにしてほしいのである。
<Q04Answerのソースコード>
package p12ans;
public class Q04Answer {
    public static void main(String[] args) {
        new MyPad(new MyOsV2()).doAsMyPad();
        new MyMac(new MyOsV2()).doAsMyMac();
        new MyPhone(new MyOsV2()).doAsMyPhone();
        System.out.println("\nニュースです。MyOsのバージョン3がリリースされました。\n");
        new MyPad(new MyOsV3()).doAsMyPad();
        new MyMac(new MyOsV3()).doAsMyMac();
        new MyPhone(new MyOsV3()).doAsMyPhone();
    }
}<結果>
|  MyOs version2を起動します。 MyPad特有の機能を実行. MyOs version2を起動します。 MyMac特有の機能を実行.. MyOs version2を起動します。 MyPhone特有の機能を実行… ニュースです。MyOsのバージョン3がリリースされました。 MyOs version3を起動します。 MyPad特有の機能を実行. MyOs version3を起動します。 MyMac特有の機能を実行.. MyOs version3を起動します。 MyPhone特有の機能を実行…  | 
5.オリジナルインタフェースの作成
あなたの理想の機能を抽象メソッドとして持つインタフェース達を作成しなさい。
インタフェース名は自由とします。
あなたの理想のインタフェース達をimplementsした理想のクラスを作成しなさい。