p.263 複数のインターフェイスを実装する
・1クラスで複数のクラスを継承することはできない
・1クラスで複数のインターフェイスを実装することは可能
・書式: class クラス名 : インターフェイス名①, インターフェイス名②, … {…}
・実装した全てのインターフェイスの抽象メンバのオーバライドが求められる
・例:
interface Flyable { string HowToFly(); } //飛行体を示すインターフェイス
interface Runable { string HowToRun(); } //走行体を示すインターフェイス
class Dragon : Flyable, Runable {
public string HowToFly() { return "腕力で飛ぶ"; }
public string HowToRun() { return "脚力で走る"; }
}
p.263 interface04.cs 正誤
・010行目「interface ISecond : IFirst」→「interface ISecond」
p.263 interface04.cs
//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 interface04 {
public static void Main() {
MyClass mc = new MyClass();
mc.show(2); //抽象メソッド①のオーバライドを呼ぶ
mc.show(1, 3); //抽象メソッド②のオーバライドを呼ぶ
}
}
p.263 (複数の同じシグニチャのメソッドを持つインターフェイスを実装する)
・1クラスで複数のインターフェイスを実装する時、そこに同じシグニチャのメソッドがあると1つのオーバライドで両方に当てはまり、 エラーにはならない ※テキストでは「明示して実装する必要がある」となっているがエラーになるわけではない
アレンジ演習:p.263 interface04.cs
・「void show(int x, int y); //抽象メソッド②」を「void show(int y); //抽象メソッド②」としても、同じ動作をすることを 確認せよ
作成例
//アレンジ演習:p.263 interface04.cs
using System;
interface IFirst { //インターフェイス①の定義
void show(int x); //抽象メソッド①
}
interface ISecond { //インターフェイス②の定義
void show(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 interface04 {
public static void Main() {
MyClass mc = new MyClass();
mc.show(2); //抽象メソッド①②のオーバライドを呼ぶ
mc.show(1, 3); //オーバーロードを呼ぶ
}
}
p.263 (複数の同じシグニチャのメソッドを持つインターフェイスを実装する):続き
・1クラスで複数のインターフェイスを実装する時、そこに同じシグニチャのメソッドがあると1つのオーバライドで両方に当てはまり、 どちらのインターフェイスを型とする変数を経由しても実行される
アレンジ演習:p.263 interface04.cs 続き
・MyClassの変数をインターフェイス①型に代入して抽象メソッド①のオーバライドを呼ぶ ・MyClassの変数をインターフェイス②型に代入して抽象メソッド②のオーバライドを呼ぶ ・どちらも動作をすることを確認せよ
作成例
//アレンジ演習:p.263 interface04.cs
using System;
interface IFirst { //インターフェイス①の定義
void show(int x); //抽象メソッド①
}
interface ISecond { //インターフェイス②の定義
void show(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 interface04 {
public static void Main() {
MyClass mc = new MyClass();
IFirst ifi = mc; //インターフェイス①型に代入
ifi.show(2); //抽象メソッド①のオーバライドを呼ぶ
ISecond ise = mc; //インターフェイス②型に代入
ise.show(1); //抽象メソッド②のオーバライドを呼ぶ
}
}
p.263 (複数の同じシグニチャのメソッドを持つインターフェイスを実装する):続き=テキストp.264
・1クラスで複数のインターフェイスを実装する時、そこに同じシグニチャのメソッドがあるときに、これを区別してオーバライドしたい 場合は「インターフェイス名.」を前置すると良い ・これを行ったメソッドは自動的にpublicになり、publicを指定するとエラーになるので注意
アレンジ演習:p.263 interface04.cs 続き
・抽象メソッド①のオーバライド兼②のオーバライドである「public void show(int x)」を区別してオーバライドして 動作を確認しよう ・「public void show(int x, int y)」は削除して良い
作成例
//アレンジ演習:p.263 interface04.cs
using System;
interface IFirst { //インターフェイス①の定義
void show(int x); //抽象メソッド①
}
interface ISecond { //インターフェイス②の定義
void show(int y); //抽象メソッド② ※①と同じシグニチャ
}
class MyClass : IFirst, ISecond { //インターフェイス①と②を実装するクラス
void IFirst.show(int x) { //抽象メソッド①のオーバライド
Console.WriteLine("IFirst = {0}", x);
}
void ISecond.show(int x) { //抽象メソッド②のオーバライド
Console.WriteLine("ISecond = {0}", x);
}
}
class interface04 {
public static void Main() {
MyClass mc = new MyClass();
IFirst ifi = mc; //インターフェイス①型に代入
ifi.show(1); //抽象メソッド①のオーバライドを呼ぶ
ISecond ise = mc; //インターフェイス②型に代入
ise.show(2); //抽象メソッド②のオーバライドを呼ぶ
}
}
p.264 interface05.csについて
・005行目の「public」は不要 ・010行目の「public」は不要
p.265 interface05.cs
//p.265 interface05.cs
using System;
interface IMas { //「です・ます」を示すインターフェイス①
void show(int i); //抽象メソッド①
}
interface IDa { //「だ・である」を示すインターフェイス②
void show(int i); //抽象メソッド② ※①と同じシグニチャ
}
class MyClass : IMas, IDa { //上記2インターフェイスを実装するクラス
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); //抽象メソッド②のオーバライドを実行
}
}
【補足】クラスの継承とインターフェイスの実装
・クラスの継承とインターフェイスの実装は同時に行うことができる
・ただし、基本クラスをインターフェイスよりも前に記述すること
・書式例: class 派生クラス名 : 基本クラス名, インターフェイス名①, インターフェイス名② {…}
・なお、抽象クラスの継承とインターフェイスの実装を同時に行うこともできる
・この時、同じシグニチャの抽象メソッドを持つインターフェイスを実装することも可能
アレンジ演習:p.265 interface05.cs
・抽象クラスの継承とインターフェイスの実装を同時に行うこともできることを確認しよう
作成例
//アレンジ演習:p.265 interface05.cs
using System;
interface IMas { //「です・ます」を示すインターフェイス①
void show(int i); //抽象メソッド①
}
interface IDa { //「だ・である」を示すインターフェイス②
void show(int i); //抽象メソッド② ※①と同じシグニチャ
}
abstract class Base { //【追加】抽象クラス
public abstract void show(int i); //抽象メソッド③
}
class MyClass : Base, IMas, IDa { //【変更】抽象クラスを継承し2インターフェイスを実装するクラス
void IMas.show(int i) { //抽象メソッド①のオーバライドなので「です・ます」
Console.WriteLine("iは{0}です", i);
}
void IDa.show(int i) { //抽象メソッド②のオーバライドなので「だ・である」
Console.WriteLine("iは{0}だ", i);
}
public override void 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); //【追加】インターフェイス型の変数を経由しないと抽象メソッド③のオーバライドを実行
}
}
提出:ミニ演習 mini266.cs
・「アレンジ演習:p.265 interface05.cs」からIDaインターフェイスを除外して、動作を確認しよう