まず、親クラス。
class ParentClass { // 仮想または抽象メンバーには、private を指定できません。 private /* virtual */ void func1() { Console.WriteLine("Parent private func1"); } protected virtual void func2() { Console.WriteLine("Parent protected func2"); } public virtual void func3() { Console.WriteLine("Parent public func3"); } public virtual void call() { this.func1(); this.func2(); this.func3(); } }
private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。
他と違い、この時点でエラーが発生。仮想関数を private にできないらしい。
子クラス1 は public に変更。
class Child1Class : ParentClass { // オーバーライドする適切なメソッドが見つかりませんでした。 public /* override */ void func1() { Console.WriteLine("Child1 private -> public func1"); } // 'protected' 継承メンバー 'ConsoleApplication1.ParentClass.func2()' をオーバーライドするときに、アクセス修飾子を変更できません。 public /* override */ new void func2() { Console.WriteLine("Child1 protected -> public func2"); } public override void func3() { Console.WriteLine("Child1 public func3"); } }
func1 は親クラスを virtual 宣言していないためオーバーライド出来ず、コンパイルエラーとなる。
func2 はアクセス修飾子が変更できない旨のエラーがでる。PHP や Java と違い緩い方向にも変更できない。
func1, func2 共に override を外すと、コンパイルは通る。
func2 は override を外しただけでは、override か new を付けろと警告が出る。
子クラス2 は protected に変更。
class Child2Class : ParentClass { // オーバーライドする適切なメソッドが見つかりませんでした。 protected /* override */ void func1() { Console.WriteLine("Child2 private -> protected func1"); } protected override void func2() { Console.WriteLine("Child2 protected func2"); } // 'public' 継承メンバー 'ConsoleApplication1.ParentClass.func3()' をオーバーライドするときに、アクセス修飾子を変更できません。 protected /* override */ new void func3() { Console.WriteLine("Child2 public -> protected func3"); } }
func1 は同じようにエラー。
func3 はアクセス修飾子の変更によるエラー。
子クラス3 は private に変更。
class Child3Class : ParentClass { // 仮想または抽象メンバーには、private を指定できません。 private /* override */ void func1() { Console.WriteLine("Child3 private func1"); } // 仮想または抽象メンバーには、private を指定できません。 private /* override */ new void func2() { Console.WriteLine("Child3 protected -> private func2"); } // 仮想または抽象メンバーには、private を指定できません。 private /* override */ new void func3() { Console.WriteLine("Child3 public -> private func3"); } }
func1 は同じようにエラー。
func2, func3 もアクセス修飾子によるエラーとなる。
実行してみると、
ParentClass p = new ParentClass(); p.call(); Console.WriteLine("----------"); Child1Class c1 = new Child1Class(); c1.call(); Console.WriteLine("----------"); Child2Class c2 = new Child2Class(); c2.call(); Console.WriteLine("----------"); Child3Class c3 = new Child3Class(); c3.call();
結果は、
Parent private func1 Parent protected func2 Parent public func3 ---------- Parent private func1 Parent protected func2 Child1 public func3 ---------- Parent private func1 Child2 protected func2 Parent public func3 ---------- Parent private func1 Parent protected func2 Parent public func3
ほとんどオーバーライド出来ないため、PHP や Java とは異なる結果になった。
private, public -> protected -> private 方向は勿論、protected -> public の変更もできないようだ。