[Java] オーバーロード、継承とオーバーライドと可視性

メソッドのオーバーロード

phpのオーバーロードとは意味が全く違う(phpが特殊なだけ、アクセス不可メンバにアクセスした時に起動する特殊メソッド)

Javaのオーバーロードは 同じ識別子のメソッドでも引数の型・数・順番(仮引数の識別子は関係なし)が異なれば違う内容のメソッドを多重定義できるという意味。

public class Over {
	public static void main(String[] args) {
		Over.ride(777);
		Over.ride();
	}

	public static void ride(int n) {
		System.out.println("固定引数");
	}

	public static void ride(int... n) {
		int sum = 0;
		for (int i = 0; i < n.length; i++) {
			sum += n[i];
		}
		System.out.println("可変引数");
	}
}

結果

固定引数
可変引数

可変長引数より固定長引数をもつメソッドが優先される

クラスの継承

親クラスをスーパークラス、子クラスをサブクラスと呼ぶ。phpでも同じ用語をつかうっぽいんだけど知らなかった。
extends の使い方は php と多分同じ。多重継承はできない。

class A extends B {}
class B extends C {}
class C{}

public class D extends A, B // コンパイルエラー

メソッドの継承と可視性

↓準備

package net.fernwelt;

public class P {
	private void   pri() { System.out.println("Ppri"); }
	protected void pro() { System.out.println("Ppro"); }
	public void    pub() { System.out.println("Ppub"); }
}

継承したメソッドのコール

以下のソースでコンパイルエラーとなるのは何箇所?

package jp.fernweh;

import net.fernwelt.P;

public class C extends P {
	public static void main(String[] args) {
		C c = new C();
		c.pri();
		c.pro();
		c.pub();
		
		P p = new P();
		p.pri();
		p.pro();
		p.pub();
	}
}

3箇所だね。

メソッドのオーバーライドと可視性

以下のコードでコンパイルエラーになるのは何箇所?
その部分をコメントアウトするとどう出力される?

package jp.fernweh;

import net.fernwelt.P;

public class C extends P {

	private void   pri() { System.out.println("Cpri"); }
	protected void pro() { System.out.println("Cpro"); }
	public void    pub() { System.out.println("Cpub"); }

	public void callP() {
		super.pri();
		super.pro();
		super.pub();
	}

	public static void main(String[] args) {
		C c = new C();
		c.pri();
		c.pro();
		c.pub();
		System.out.println();

		c.callP();
		System.out.println();

		P p = new P();
		p.pri();
		p.pro();
		p.pub();
	}
}

コンパイルエラーになるのは3箇所で、
エラー部分をコメントアウトして実行すると
イカの様に出力される。

結果

Cpri
Cpro
Cpub

Ppro
Ppub

Ppub

また、PHPと同様にメソッドをオーバーライドするときに可視性を下げることはできない。

class C extends B {
	public void pri() {}
	private void pro() {} // コンパイルエラー
	protected void pub() {} // コンパイルエラー
}

class B {
	private void pri() {}
	protected void pro() {}
	public void pub() {}
}

フィールドの継承と可視性

継承したフィールドへのアクセス

以下のコードでエラーとなるのはどこ?
その部分をコメントアウトするとどのように出力される?

package net.fernwelt;

public class P {
	private String pri = "Ppri";
	protected String pro = "Ppro";
	public String pub = "Ppub";

	public void printP() {
		System.out.println(this.pri);
		System.out.println(this.pro);
		System.out.println(this.pub);
		System.out.println();
	}
}
package jp.fernweh;

import net.fernwelt.P;

public class C extends P {

	public static void main(String[] args) {
		C c = new C();
		System.out.println(c.pri);
		System.out.println(c.pro);
		System.out.println(c.pub);

		P p = new P();
		System.out.println(p.pri);
		System.out.println(p.pro);
		System.out.println(p.pub);
		System.out.println();
		
		p.printP();

		c.printC();
		c.printP();
	}

	public void printC() {
		System.out.println(this.pri);
		System.out.println(this.pro);
		System.out.println(this.pub);
		System.out.println(super.pri);
		System.out.println(super.pro);
		System.out.println(super.pub);
		System.out.println();
	}

}

5箇所でコンパイルエラーとなり、
その部分をコメントアウトすると以下のようになる

結果

Ppro
Ppub
Ppub

Ppri
Ppro
Ppub

Ppro
Ppub
Ppro
Ppub

Ppri
Ppro
Ppub
  • 別パッケージのprotected フィールドには直接アクセスできない
  • protectedフィールドは継承すればそのクラスで自由に使用できる
  • 継承したクラスのprivateフィールドはスーパークラスのメソッドを介してアクセスできる。

phpの継承とかなり違うので超混乱。phpではプロパティを継承すると親クラスのprotected, public プロパティは消滅する。そもそも継承したクラスのプロパティにアクセスするsuper()みたいなものが存在しない。phpでのプロパティ継承のイメージは遺産を受け取る感覚(なんだそれ)だけど、Javaでは親クラスのメンバにアクセスできる権利をもらえるだけな感じ?

フィールドのオーバーライドと可視性

以下のコードでコンパイルエラーとなるのはどこ?
その部分をコメントアウトするとどのように出力される?

package net.fernwelt;

public class P {
	private String pri = "Ppri";
	protected String pro = "Ppro";
	public String pub = "Ppub";
}
package jp.fernweh;

import net.fernwelt.P;

public class C extends P {

	private String pri = "Cpri";
	protected String pro = "Cpro";
	public String pub = "Cpub";

	public static void main(String[] args) {
		C c = new C();
		System.out.println(c.pri);
		System.out.println(c.pro);
		System.out.println(c.pub);

		P p = new P();
		System.out.println(p.pri);
		System.out.println(p.pro);
		System.out.println(p.pub);
		System.out.println();

		c.printC();
	}

	public void printC() {
		System.out.println(this.pri);
		System.out.println(this.pro);
		System.out.println(this.pub);
		System.out.println(super.pri);
		System.out.println(super.pro);
		System.out.println(super.pub);
	}

}

3箇所でコンパイルエラーとなり、
その部分をコメントアウトすると以下のようになる

結果

Cpri
Cpro
Cpub
Ppub

Cpri
Cpro
Cpub
Ppro
Ppub

フィールドのオーバーライドでの可視性の変更

メソッドとは違ってフィールド継承により可視性が変化しても問題ない。
まぁ基本的にはprivateフィールドを使うのであまり意識することはなさそうだけども。

関連記事

2011年3月11日 | コメント/トラックバック(0) |

カテゴリー:Java タグ:

このページの先頭へ

このエントリーをはてなブックマークに追加 にほんブログ村 IT技術ブログへ
イメージ画像