講義メモ(最終回)

・p.259「1つのインターフェイスを複数のクラスで実装する」から

提出フォロー:アレンジ演習:p.257 interface01.cs

・IMyInterfaceインターフェイスを実装するYourClassを追加し、MainメソッドでMyClassと同様に扱えることを試そう

作成例

//アレンジ演習:p.257 interface01.cs
using System;
interface IMyInterface { //インターフェイスの定義
    void show(string str); //抽象メソッド
    int xprop { get; set; } //抽象プロパティ
    int this[int i] { get; set; } //抽象インデクサ
}
class MyClass : IMyInterface { //インターフェイスを実装したクラス①
    int i; 
    int[] arr = new int[10]; 
    public void show(string str) { //抽象メソッドのオーバーライド①
        Console.WriteLine(str);
    }
    public int xprop { //抽象プロパティのオーバーライド①
        get { return i; } set { i = value; }
    }
    public int this[int index] { //抽象インデクサのオーバーライド①
        get { return arr[index]; } set { arr[index] = value; }
    }       
}
class YourClass : IMyInterface { //【以下追加】インターフェイスを実装したクラス② ※上記と同一内容
    int i; 
    int[] arr = new int[10]; 
    public void show(string str) { //抽象メソッドのオーバーライド②
        Console.WriteLine(str);
    }
    public int xprop { //抽象プロパティのオーバーライド②
        get { return i; } set { i = value; }
    }
    public int this[int index] { //抽象インデクサのオーバーライド②
        get { return arr[index]; } set { arr[index] = value; }
    }       
}
class interface01 {
    public static void Main() {
        MyClass mc = new MyClass(); //インターフェイスを実装したクラス①のインスタンスを生成
        mc.show("Test Interface"); //抽象メソッドのオーバーライド①を呼ぶ
        mc.xprop = 100; //抽象プロパティ(set)のオーバーライド①を呼ぶ
        Console.WriteLine("mc.xprop = {0}", mc.xprop); //抽象プロパティ(get)のオーバーライド①を呼ぶ
        for (int i = 0; i < 10; i++) {
            mc[i] = i * 2; //抽象インデクサ(set)のオーバーライド①を呼ぶ
        }
        for (int i = 0; i < 10; i++) {
            Console.WriteLine("mc[{0}] = {1}", i, mc[i]); //抽象インデクサ(get)のオーバーライド①を呼ぶ
        }
        //【以下追加】上記のクラス名、変数名を替えたもので同一内容
        YourClass md = new YourClass(); //インターフェイスを実装したクラス②のインスタンスを生成
        md.show("Test Interface 2"); //抽象メソッドのオーバーライド②を呼ぶ
        md.xprop = 100; //抽象プロパティ(set)のオーバーライド②を呼ぶ
        Console.WriteLine("md.xprop = {0}", md.xprop); //抽象プロパティ(get)のオーバーライド②を呼ぶ
        for (int i = 0; i < 10; i++) {
            md[i] = i * 2; //抽象インデクサ(set)のオーバーライド②を呼ぶ
        }
        for (int i = 0; i < 10; i++) {
            Console.WriteLine("md[{0}] = {1}", i, md[i]); //抽象インデクサ(get)のオーバーライド②を呼ぶ
        }       
    }
}

p.259 1つのインターフェイスを複数のクラスで実装する

・1つのインターフェイスを複数のクラスで実装でき、抽象メンバ(メソッド、プロパティ、インデクサ)をそれぞれにおいてオーバーライドする

アレンジ演習 p.257 interface02.cs

・IMyInterfaceインターフェイスに、以下の抽象プロパティを追加し、各クラスでオーバーライドしよう
  int xprop { get; set; }
・オーバーライドの内容は自由


作成例

//アレンジ演習 p.257 interface02.cs
using System;
interface IMyInterface { //インターフェイスの定義
    void show(string str); //抽象メソッド
    int xprop { get; set; } //【追加】抽象プロパティ
}
class MyClass : IMyInterface { //インターフェイスを実装するクラス①
    int x; //【追加】
    public void show(string s) {
        Console.WriteLine(s);
    }
    public int xprop { //【追加】抽象プロパティのオーバーライド①
        get { return x; }  set { x = value; } 
    } 
}
class YourClass : IMyInterface { //インターフェイスを実装するクラス②
    int y; //【追加】
    public void show(string x) {
        Console.WriteLine("{0}が入力されました", x);
    }
    public int xprop { //【追加】抽象プロパティのオーバーライド②
        get { return y; }  set { y = value; } 
    } 
}
class interface02 {
    public static void Main() {
        MyClass mc = new MyClass(); // インターフェイスを実装するクラス①から生成
        YourClass yc = new YourClass(); // インターフェイスを実装するクラス②から生成
        mc.show("abc"); //①でオーバーライドしているメソッドを呼ぶ
        yc.show("abc"); //②でオーバーライドしているメソッドを呼ぶ
        //【以下追加】
        mc.xprop = 10; //①でオーバーライドしているプロパティのsetを呼ぶ
        Console.WriteLine(mc.xprop); //①でオーバーライドしているプロパティのgetを呼ぶ
        yc.xprop = 30; //②でオーバーライドしているプロパティのsetを呼ぶ
        Console.WriteLine(yc.xprop); //②でオーバーライドしているプロパティのgetを呼ぶ
    }
}

p.260 1つのインターフェイスを複数のクラスで実装する:インターフェイスを型とする参照変数

・インターフェイスも、抽象クラスもインスタンスを生成することはできない
・しかし、インターフェイスや、抽象クラスを型とする参照変数は宣言できる
・この参照変数に、インターフェイスを実装するオブジェクトや、派生クラスのオブジェクトを代入することで、参照をコピーすることができる
・よって、インターフェイスを実装する複数のクラスに対して、オーバーライドしているメンバを同じ形式で呼び出すことができる

アレンジ演習:p.261 interface03.cs

・インターフェイスIMyInterfaceを型とする配列iaを生成しよう
・そして、変数p、mを格納して、配列の要素経由でCalcメソッドを実行してみよう

作成例

//アレンジ演習:p.261 interface03.cs
using System;
interface IMyInterface { //インターフェイスの定義
    int calc(int x, int y); //抽象メソッド
}
class Plus : IMyInterface { //インターフェイスを実装するクラス①
    public int calc(int a, int b) { //抽象メソッドのオーバーライド①
        return a + b; //和を返す
    }
}
class Minus : IMyInterface { //インターフェイスを実装するクラス①
    public int calc(int a, int b) { //抽象メソッドのオーバーライド②
        return a - b; //差を返す
    }
}
class interface03 {
    public static void Main()    {
        IMyInterface im; //インターフェイスを型とする参照変数の宣言のみ
        Plus p = new Plus(); //インターフェイスを実装するクラス①
        Minus m = new Minus(); //インターフェイスを実装するクラス②
        im = p; //インターフェイスを型とする参照変数にクラス①のオブジェクトを代入
        Console.WriteLine("im.calc = {0}", im.calc(3, 5)); //参照変数経由でメソッド①を実行
        im = m; //インターフェイスを型とする参照変数にクラス②のオブジェクトを代入
        Console.WriteLine("im.calc = {0}", im.calc(3, 5)); //参照変数経由でメソッド①を実行
        //【以下追加】インターフェイスを型とする配列に上記を格納
        IMyInterface[] ia = {p, m};
        foreach (var i in ia) { //全要素について繰返す
            Console.WriteLine("i[].calc = {0}", i.calc(3, 5)); //
        }
     }
}

p.263 複数のインターフェイスを実装する

・クラスが複数のクラスを継承することはできない
・しかし、複数のインターフェイスを実装することはできる

p.263【正誤】interface04.cs

・010行:「: IFirst」はインターフェイスの継承にあたるが、ここでは不要

アレンジ演習:p.263 interface04.cs

・IFirstインターフェースのみを実装するYourClassを追加し、Show(int)メソッドを適当にオーバーライドする
・YourClassのオブジェクトycを生成し、IFirstインターフェースを型とする配列に、mcと共に格納できるか確認しよう

作成例

//アレンジ演習:p.263 interface04.cs
using System;
interface IFirst { //インターフェース①
    void show(int x); //抽象メソッド①
}
interface ISecond { //インターフェース②
    void show(int x, int y); //抽象メソッド②
}
class MyClass : IFirst, ISecond { //インターフェース①②を実装するクラス①
    public void show(int x) { //抽象メソッド①のオーバーライド
        Console.WriteLine("x = {0}", x);
    }
    public void show(int x, int y) { //抽象メソッド②のオーバーライド
        Console.WriteLine("x = {0}, y = {1}", x, y);
    }
}
class YourClass : IFirst { //【以下追加】インターフェース①のみを実装するクラス②
    public void show(int x) { //抽象メソッド①のオーバーライド
        Console.WriteLine("x = {0}", x);
    }
}
class interface04 {
    public static void Main() {
        MyClass mc = new MyClass();
        mc.show(2); //抽象メソッド①のオーバーライドを呼ぶ
        mc.show(1, 3); //抽象メソッド②のオーバーライドを呼ぶ
        //【以下追加】
        YourClass yc = new YourClass();
        IFirst[] ifa = {mc, yc}; //インターフェイス①を型とする配列に格納
        foreach (var w in ifa) { //この配列の全要素について繰返す
            w.show(100); //抽象メソッド①のオーバーライドを呼ぶ
        }
    }
}

p.263 複数のインターフェイスを実装する:同じシグニチャのメソッドが含まれている場合

・同じシグニチャのメソッドが含まれている場合、その両方をオーバーライドする必要がある
・そこで、識別するために「戻り値型 インターフェイス名.メソッド名(){…}」として記述する
・この時、publicは不要(記述するとエラーになる)
・呼び出す側では、インターフェイス型の参照変数を用いることで、どちらかを識別できる

p.264【正誤】interface05.cs

・005行:「public」は不要
・010行:「public」は不要

アレンジ演習:p.264 interface05.cs

・インターフェイス型の参照変数を用いずに「mc.Show(5);」と呼び出すとどうなるか確認しよう

作成例

//p.264 interface05.cs
using System;
interface IMas { //インターフェイス①
    void show(int i); //抽象メソッド①
}
interface IDa { //インターフェース②
    void show(int i); //抽象メソッド②(※①と同じシグニチャ)
}
class MyClass : IMas, IDa { //インターフェース①②を実装するクラス
    void IMas.show(int i) { //インターフェイス①の抽象メソッド①のオーバーライド
        Console.WriteLine("iは{0}です", i);
    }
    void IDa.show(int i) { //インターフェイス②の抽象メソッド②のオーバーライド
        Console.WriteLine("iは{0}だ", i);
    }
}
class interface05 {
    public static void Main() {
        IMas im; //インターフェイス①型の参照変数の宣言
        IDa id; //インターフェイス②型の参照変数の宣言
        MyClass mc = new MyClass(); //インターフェース①②を実装するクラスのオブジェクト生成
        im = mc; //インターフェイス①型の参照変数に代入すれば
        im.show(5); //インターフェイス①の抽象メソッド①のオーバーライドが実行
        id = mc; //インターフェイス②型の参照変数に代入すれば
        id.show(5); //インターフェイス②の抽象メソッド②のオーバーライドが実行
        //mc.show(5); //文法エラーになる
    }
}

コメントを残す

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