講義メモ(最終回)後半

p.266 インターフェイスの継承

・クラスと同様にインターフェイスが継承が可能
・継承される側を基本インターフェイス、する側を派生インターフェイスと呼ぶ
・クラスと同様に継承できるインターフェイスは1つのみで、派生インターフェイスの継承は可能

アレンジ演習:p.266 interface06.cs

・派生インターフェイスIInterface2を継承するIInterface3を追加できることを確認しよう
 ※中身は自由

作成例

//アレンジ演習:p.266 interface06.cs
using System;
interface IInterface1 { //基本インターフェイス①
    void setdatano(int n); //抽象メソッド①
    void setdata(double data, int i); //抽象メソッド②
    double calcsum(); //抽象メソッド③
}
interface IInterface2 : IInterface1 { //派生インターフェイス②
    //ここに void setdatano(int n); //抽象メソッド①があるとみなされる
    //ここに void setdata(double data, int i); //抽象メソッド②があるとみなされる
    //ここに double calcsum(); //抽象メソッド③があるとみなされる
    double calcaverage(); //抽象メソッド④
}
interface IInterface3 : IInterface2 { //【以下追加】派生の派生インターフェイス③
    //ここに void setdatano(int n); //抽象メソッド①があるとみなされる
    //ここに void setdata(double data, int i); //抽象メソッド②があるとみなされる
    //ここに double calcsum(); //抽象メソッド③があるとみなされる
    //ここに double calcaverage(); //抽象メソッド④があるとみなされる
    double calcmax(); //抽象メソッド⑤
}
class MyClass : IInterface3 { //【変更】派生の派生インターフェイス③を実装するクラス
    double[] data;
    bool bOK = false; //OKフラグ(false:準備前)
    public void setdatano(int n) { //抽象メソッド①のオーバーライド
        data = new double[n]; //配列を生成
        bOK = true; //OKフラグを準備済にする
    }
    public void setdata(double d, int i) { //抽象メソッド②のオーバーライド
        if (!bOK) { //OKフラグが準備前?
            Console.WriteLine("配列の準備ができていません");
            return;
        }
        data[i] = d;
    }
    public double calcsum() { //抽象メソッド③のオーバーライド
        if (!bOK) { //OKフラグが準備前?
            Console.WriteLine("配列の準備ができていません");
            return -1.0; //値を返す必要があるので、ダミーの値を返す
        }
        double sum = 0.0; //合計用
        for (int i = 0; i < data.Length; i++) { //全要素について繰返す
            sum += data[i]; //合計に足し込む
        }
        return sum; //合計を返す
    }
    public double calcaverage() { //抽象メソッド④のオーバーライド
        double sum = calcsum(); //合計値を得る
        return sum / data.Length; //件数で割って平均値を得て返す
    }
    public double calcmax() { //【以下追加】抽象メソッド⑤のオーバーライド
        if (!bOK) { //OKフラグが準備前?
            Console.WriteLine("配列の準備ができていません");
            return -1.0; //値を返す必要があるので、ダミーの値を返す
        }
        double max = -1.0; //最大値用(※仮に正の数限定とする)
        for (int i = 0; i < data.Length; i++) { //全要素について繰返す
            max = (max > data[i]) ? max : data[i]; //最大値を更新
        }
        return max; //最大値を返す
    }
}
class interface06 {
    public static void Main() {
        MyClass mc = new MyClass(); //派生インターフェイス②を実装するクラス
        int nNo;
        while (true) { //無限ループ
            Console.Write("データ数---");
            string strno = Console.ReadLine();
            nNo = Int32.Parse(strno);
            mc.setdatano(nNo); //データ数の分の配列を生成
            for (int i = 0; i < nNo; i++) { //データ数の分だけ繰返す
                Console.Write("data[{0}] = ", i);
                string strdata = Console.ReadLine();
                mc.setdata(double.Parse(strdata), i); //配列に格納
            }
            Console.WriteLine("合計 = {0}", mc.calcsum());
            Console.WriteLine("平均 = {0}", mc.calcaverage());
            Console.WriteLine("最大 = {0}", mc.calcmax()); //【追加】
            Console.WriteLine();
            Console.Write("続けますか(Y/N)---");
            string yn = Console.ReadLine();
            if (yn == "N" || yn == "n") {
                break;
            }
        }
    }
}

p.270 インターフェイスの継承:同じシグニチャの抽象メンバがある場合

・派生インターフェイスにおいて、基本インターフェイスと同じシグニチャの抽象メンバがある場合、名前の隠ぺいが起こる
・この場合、newキーワードを追記して、名前の隠ぺいであることを明示すると良い

アレンジ演習:p.270 interface07.cs

・派生インターフェイスIMyInterface2を継承するIMyInterface3を追加しよう
・この中で、Show2()メソッドの名前の隠ぺいができることを試そう

作成例

//アレンジ演習:p.270 interface07.cs
using System;
interface IMyInterface { //基本インターフェイス①
    void show1(); //抽象メソッド①
    void show2(); //抽象メソッド②
}
interface IMyInterface2 : IMyInterface { //派生インターフェイス②
    //ここに「void show1(); //抽象メソッド①」があるとみなされるが隠ぺいされる
    new void show1(); //抽象メソッド①の名前の隠ぺい
    //ここに「void show2(); //抽象メソッド②」があるとみなされる
    void show3(); //抽象メソッド③
}
interface IMyInterface3 : IMyInterface2 { //【以下追加】派生の派生インターフェイス③
    //ここに「void show1(); //抽象メソッド①」があるとみなされるが隠ぺいされる
    //ここに「new void show1(); //抽象メソッド①の名前の隠ぺいがあるとみなされる
    //ここに「void show2(); //抽象メソッド②」があるとみなされるが隠ぺいされる
    new void show2(); //抽象メソッド②の名前の隠ぺい
    //ここに「void show3(); //抽象メソッド③」があるとみなされる
}
class MyClass : IMyInterface3 { //【変更】派生の派生インターフェイス③を実装するクラス
    public void show1() { //抽象メソッド①の名前の隠ぺいのオーバーライド
        Console.WriteLine("show1");
    }
    public void show2() { //【コメントのみ変更】抽象メソッド②の名前の隠ぺいのオーバーライド
        Console.WriteLine("show2");
    }
    public void show3() { //抽象メソッド③のオーバーライド
        Console.WriteLine("show3");
    }
}
class interface07 {
    public static void Main() {
        MyClass mc = new MyClass();
        mc.show1(); //抽象メソッド①の名前の隠ぺいのオーバーライドを呼ぶ
        mc.show2(); //【コメントのみ変更】抽象メソッド②の名前の隠ぺいのオーバーライドを呼ぶ
        mc.show3(); //抽象メソッド③のオーバーライドを呼ぶ
    }
}

p.266 インターフェイスの継承:名前の隠ぺい時に隠ぺいされたメソッドをオーバーライドする

・複数のインターフェイスを実装する時に、同じシグニチャのメソッドが含まれている場合と同様に
 「インターフェイス名.メソッド名」と記述すれば、名前の隠ぺい時に隠ぺいされたメソッドをオーバーライドすることができる
・そして、利用時にインターフェイスを型とする参照変数を経由することで識別が可能

アレンジ演習:p.272 interface08.cs

・派生インターフェイスI2を継承するI3を追加しよう
・この中で、Show2()メソッドの名前の隠ぺいを行う
・MyClassクラスは派生の派生インターフェイスI3を実装するようにしよう

作成例

//アレンジ演習:p.272 interface08.cs
using System;
interface I1 { //基本インターフェイス①
    void show1(); //抽象メソッド①
    void show2(); //抽象メソッド②
}
interface I2 : I1 { //派生インターフェイス②
    new void show1(); //抽象メソッド①の名前の隠ぺい
}
interface I3 : I2 { //【追加】派生の派生インターフェイス③
    new void show2(); //抽象メソッド②の名前の隠ぺい
}
class MyClass : I3 { //【変更】派生の派生インターフェイス②を実装するクラス
    void I1.show1() { //隠ぺいされた基本インターフェイス①の抽象メソッド①のオーバーライド
        Console.WriteLine("I1.show1");
    }
    void I2.show1() { //隠ぺいした派生インターフェイス②の抽象メソッド①のオーバーライド
        Console.WriteLine("I2.show1");
    }
    void I1.show2() { //【変更】基本インターフェイス①の抽象メソッド②のオーバーライド
        Console.WriteLine("I1.show2");
    }
    void I3.show2() { //【追加】隠ぺいした派生の派生インターフェイス③の抽象メソッド②のオーバーライド
        Console.WriteLine("I3.show2");
    }
}
class interface08 {
    public static void Main() {
        MyClass mc = new MyClass();
        I1 i1; //基本インターフェイス①を型とする参照変数
        I2 i2; //派生インターフェイス②を型とする参照変数
        //mc.show2(); //【削除】基本インターフェイス①の抽象メソッド②のオーバーライドを呼ぶ
        i1 = mc; //基本インターフェイス①を型とする参照変数を経由することで
        i1.show1(); //隠ぺいされた基本インターフェイス①の抽象メソッド①のオーバーライドを呼ぶ
        i2 = mc; //派生インターフェイス②を型とする参照変数を経由することで
        i2.show1(); //隠ぺいした派生インターフェイス②の抽象メソッド①のオーバーライドを呼ぶ
        i2.show2(); //派生インターフェイス②の抽象メソッド②のオーバーライドを呼ぶ事も可能
        //【以下追加】
        I3 i3; //派生の派生インターフェイス③を型とする参照変数
        i3 = mc; //派生の派生インターフェイス②を型とする参照変数を経由することで
        i3.show2(); //派生の派生インターフェイス③の抽象メソッド②のオーバーライドを呼ぶ事も可能
    }
}

p.274 練習問題 ex1001.cs ヒント

・インターフェイス名を MyInterface とする
・これを実装するクラスを MyClass とする
・文字数を返すには「return str.Length;」で良い
・ex1001クラスにMainメソッドをおいて、MyClassのオブジェクトを生成してCountメソッドを試せば良い

作成例

//p.274 練習問題 ex1001.cs
using System;
interface MyInterface { //インターフェイス
    int Count(string str); //抽象メソッド
}
class MyClass : MyInterface { //インターフェイスを実装するクラス
    public int Count(string str) { //抽象メソッドのオーバーライド
        return str.Length; //引数で受け取った文字列の文字数を返す
    }
}
class ex1001 {
    public static void Main() {
        MyClass mc = new MyClass(); //インターフェイスを実装するクラスのオブジェクトを生成
        Console.WriteLine(mc.Count("Hello")); //抽象メソッドのオーバーライドを呼ぶ
    }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です