まず、親クラス。
class ParentClass
{
  private void func1() { System.out.println("Parent private func1"); }
  protected void func2() { System.out.println("Parent protected func2"); }
  public void func3() { System.out.println("Parent public func3"); }
  public void call()
  {
    this.func1();
    this.func2();
    this.func3();
  }
}
private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。子クラス1 は public に変更。
class Child1Class extends ParentClass
{
  // メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
  // @Override
  public void func1() { System.out.println("Child1 private -> public func1"); }
  @Override
  public void func2() { System.out.println("Child1 protected -> public func2"); }
  @Override
  public void func3() { System.out.println("Child1 public func3"); }
}
func1 は private メソッドをオーバーライド出来ないため、コンパイルエラーとなる。@Override アノテーションを外すと、コンパイルは通る。
子クラス2 は protected に変更。
class Child2Class extends ParentClass
{
  // メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
  // @Override
  protected void func1() { System.out.println("Child2 private -> protected func1"); }
  @Override
  protected void func2() { System.out.println("Child2 protected func2"); }
  // Child2Class の func3() は ParentClass の func3() をオーバーライドできません。スーパークラスでの定義(public) より弱いアクセス特権を割り当てようとしました。
  // @Override
  // protected void func3() { System.out.println("Child2 public -> protected func3"); }
}
func1 は同じようにエラー。func3 は PHP と同じように、public -> private への変更でエラーとなる。func1 とは異なり、アノテーションを外しただけではエラー。定義自体を削除。
子クラス3 は private に変更。
aclass Child3Class extends ParentClass
{
  // メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません
  // @Override
  private void func1() { System.out.println("Child3 private func1"); }
  // Child3Class の func2() は ParentClass の func2() をオーバーライドできません。スーパークラスでの定義(protected) より弱いアクセス特権を割り当てようとしました。
  // @Override
  // private void func2() { System.out.println("Child3 protected -> private func2"); }
  // Child3Class の func3() は ParentClass の func3() をオーバーライドできません。スーパークラスでの定義(public) より弱いアクセス特権を割り当てようとしました。
  // @Override
  // private void func3() { System.out.println("Child3 public -> private func3"); }
}
func1 は同じようにエラー。
func2, func3 でエラーとなる。やはり、厳しい方向への変更はできないようだ。
実行してみると、
ParentClass p = new ParentClass();
p.call();
System.out.println("----------");
Child1Class c1 = new Child1Class();
c1.call();
System.out.println("----------");
Child2Class c2 = new Child2Class();
c2.call();
System.out.println("----------");
Child3Class c3 = new Child3Class();
c3.call();
結果は、Parent private func1 Parent protected func2 Parent public func3 ---------- Parent private func1 Child1 protected -> public func2 Child1 public func3 ---------- Parent private func1 Child2 protected func2 Parent public func3 ---------- Parent private func1 Parent protected func2 Parent public func3
エラー部分を削除したソース、結果共に、PHP と同じようになった。
protected -> public への変更はできるが、public -> protected -> private への変更はできない。
private はオーバーライドできない。
余談だが、コンパイルエラーとなるのはやはりいい。
 
0 件のコメント:
コメントを投稿