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")); //抽象メソッドのオーバーライドを呼ぶ
}
}