3秒でわかる
親クラスにあるメソッドを子クラスで定義し直すこと。呼び出し方を共通にしたまま、種類ごとに動きを変えられるようになります。
もう少し詳しく
どういうものか
オーバーライドは、親クラスがすでに持っているメソッドと同じ名前と引数で、子クラス側に別の実装を書くことです。子のインスタンスに対してそのメソッドを呼ぶと、親ではなく子の実装が動きます。変数の型が親であっても、実際に入っている中身の型で呼び先が決まります。この動的な決まり方が、ポリモーフィズムと呼ばれる仕組みの中身です。
なぜ必要か
図形を並べて描画する処理を書くとき、円か四角かを毎回 if文で判定していると、種類が増えるたびに全部の判定箇所へ手を入れることになります。共通の area を親で決め、種類ごとに子で実装し直しておけば、呼ぶ側は種類を知らずに済みます。新しい図形を足しても、呼び出し側のコードは1行も変わりません。共通の処理を親にまとめ、違うところだけを子で差し替える、という分け方が自然にできます。
具体例
class Shape {
double area() { return 0; }
String label() { return "図形の面積は " + area(); }
}
class Circle extends Shape {
private final double r;
Circle(double r) { this.r = r; }
@Override
double area() { return Math.PI * r * r; }
}
Shape s = new Circle(2);
System.out.println(s.label()); // Circle の area が呼ばれるPythonにも同じ仕組みがあり、親の実装を使いたいときは super() を経由します。
class Admin(User):
def display(self):
return "管理者 " + super().display()つまずきやすいところ
引数の数や型を変えてしまい、上書きしたつもりが別メソッドの追加になっている誤りが多く見られます。Javaでは @Override を付ければコンパイラが気づかせてくれるので、必ず付けます。もうひとつ、コンストラクタの中から上書きされうるメソッドを呼ぶと、子のフィールドがまだ初期化されていない状態で子の実装が動き、思わぬ値になります。
似た用語との違い
| 語 | 内容 |
|---|---|
| オーバーライド | 親のメソッドを子で定義し直す |
| オーバーロード | 同じ名前で引数の異なるメソッドを増やす |
| 隠蔽 | 同名のフィールドや静的メソッドで見えなくする |
覚え方
名前は同じ、中身は別、が上書きです。名前は同じ、引数が別、なら別メソッドの追加になります。