・p.228「名前の隠ぺい」から
p.228 名前の隠ぺい
・隠ぺいは「おおい隠す=元を残して上に定義を乗せる」イメージ ・派生クラスで基本クラスと同一のメンバ名を記述できる仕掛け ・この時、newキーワードを前置することで「隠ぺいしている」ことを明示する ※ C#のバージョンによってはnewを記述しなくても隠ぺいできる場合があるが、明示したほうが良い
p.338 inheritance03
//p.338 inheritance03
using System;
class Base { //基本クラス
public int x = 10;
public void BaseMethod() {
Console.WriteLine("Baseクラスです");
}
}
class Derived : Base { //派生クラス
new public int x = 20; //データメンバの名前の隠ぺい
new public void BaseMethod() { //メソッドの名前の隠ぺい
Console.WriteLine("Derivedクラスです");
}
}
class inheritance03 {
public static void Main() {
Derived d = new Derived(); //派生クラスのインスタンスを生成
Console.WriteLine("x = {0}", d.x); //派生クラスで隠ぺいしたデータメンバを利用
d.BaseMethod(); //派生クラスで隠ぺいしたメソッドを利用
}
}
アレンジ演習:p.338 inheritance03
・private指定(または無指定)のメンバの名前の隠ぺいと、protected指定のメンバの名前の隠ぺいの可否を確認しよう → どの場合も名前の隠ぺいは可能であり、派生クラスでpublic指定してあれば、外部からも利用可能
作成例
//アレンジ演習:p.338 inheritance03
using System;
class Base { //基本クラス
protected int x = 10;
protected void BaseMethod() { //メソッドの名前の隠ぺい
Console.WriteLine("Baseクラスです");
}
}
class Derived : Base { //派生クラス
new public int x = 20; //データメンバの名前の隠ぺい
new public void BaseMethod() { //メソッドの名前の隠ぺい
Console.WriteLine("Derivedクラスです");
}
}
class inheritance03 {
public static void Main() {
Derived d = new Derived(); //派生クラスのインスタンスを生成
Console.WriteLine("x = {0}", d.x); //派生クラスで隠ぺいしたデータメンバを利用
d.BaseMethod(); //派生クラスで隠ぺいしたメソッドを利用
}
}
p.229(baseキーワード)
・名前の隠ぺいは基本クラスと同じ意味のメンバに同じ名前を与えることで、似た名前のメンバの乱立を避けられる ・また「上書き」ではないので、隠ぺいの対象となった基本クラスのメンバを「base.」を前置することで利用可能
p.229 inheritance04.cs
//p.229 inheritance04.cs
using System;
class Base { //基本クラス
protected int x = 10; //隠ぺいされるデータメンバ
}
class Derived : Base { //派生クラス
new int x = 20; //名前の隠ぺいを行う指定
public void Show() {
Console.WriteLine("base.x = {0}, x = {1} ", base.x, x); //基本クラスのメンバを利用
}
}
class inheritance04 {
public static void Main() {
Derived d = new Derived(); //派生クラスのインスタンスを生成
d.Show();
}
}
p.230 メソッドのオーバーライド
・メソッドにおける名前の隠ぺいの手法の一つだが、名前の隠ぺいでは実現できない多態性(後述)が可能な仕掛け ・通常、メソッドにおいてはオーバーライドを用いることが多い。 ・名前の隠ぺいとは異なり、基本クラス側のメソッドでオーバーライドを認めることを示す「virtual」キーワードを指定する必要がある(仮想メソッドともいう) ・派生クラスではオーバーライドメソッドであることを、overrideキーワードで明示する ・オーバーライドではシグニチャに加えてアクセス修飾子を一致させる。 ※ 静的メソッドのオーバーライドは不可(名前の隠ぺいは可能)
p.231 override01.cs
//p.231 override01.cs
using System;
class MyBase { //基本クラス
public virtual void Method() { //オーバーライド可能な仮想メソッドの定義
Console.WriteLine("MyBase");
}
}
class Derived1 : MyBase { //派生クラス
public override void Method() { //オーバーライドメソッド①の定義
Console.WriteLine("Derived1");
}
}
class Derived2 : MyBase { //派生クラス
public override void Method() { //オーバーライドメソッド②の定義
Console.WriteLine("Derived2");
}
}
class override01 {
public static void Main() {
Derived1 d1 = new Derived1();
Derived2 d2 = new Derived2();
d1.Method(); //オーバーライドメソッド①
d2.Method(); //オーバーライドメソッド②
}
}
アレンジ演習:p.231 override01.cs
・MyBaseクラスとDerived1クラスにデータメンバを追加して名前の隠ぺいを行おう ・MyBaseクラスとDerived2クラスに静的メソッドを追加して名前の隠ぺいを行おう
作成例
//アレンジ演習:p.231 override01.cs
using System;
class MyBase { //基本クラス
public int n; //【追加】データメンバ(オーバーライド不可)
public virtual void Method() { //オーバーライド可能な仮想メソッドの定義
Console.WriteLine("MyBase");
}
public static void Methods() { //【追加】オーバーライド不可な静的メソッドの定義
Console.WriteLine("MyBases");
}
}
class Derived1 : MyBase { //派生クラス
new public int n; //【追加】データメンバの名前を隠ぺい
public override void Method() { //オーバーライドメソッド①の定義
Console.WriteLine("Derived1");
}
}
class Derived2 : MyBase { //派生クラス
public override void Method() { //オーバーライドメソッド②の定義
Console.WriteLine("Derived2");
}
new public void Methods() { //【追加】静的メソッドの名前の隠ぺい
Console.WriteLine("Derived2s");
}
}
class override01 {
public static void Main() {
Derived1 d1 = new Derived1();
Derived2 d2 = new Derived2();
d1.Method(); //オーバーライドメソッド①
d2.Methods(); //静的メソッドの名前の隠ぺい
}
}