読者です 読者をやめる 読者になる 読者になる

A Clockwork …

~雑記メモ~

finalの重要性

新しく作ったクラス、メソッド、変数、継承したクラスはどう定義していますか。

修飾子って重要だと最近知らされました。
個人的に作成しているプログラムなんかは、求めていた動きができたらいいかな程度で設計してコード書くと思うんですけど、チームだとそうもいかないです。

チームが大きくなると、クラスの関係が絡み合って理解が難しくもなります。

そのためにも、クラス/オブジェクトの責務をきちんと明確に記述するようにしましょう。


話しがそれましたが、これ以上"継承やオーバーライドを想定していない"ことを示すためにもfinalやstaticをしっかりと記述しよう。

オブジェクト指向の欠点として、継承ができてしまうことが欠点としてあります。
具体的な例としては次の例を見てみましょう。

鳥クラス

public class Bird {
	int wing = 2;
	boolean fly = true;
}

ペンギンクラス

public class Penguin extends Bird {
	boolean fly = false;
	boolean swim = true;
}

鳩クラス

public class Pigeon extends Penguin {

}

実装がミスしそうなのが理解できますか?
このままでは、鳩クラスはflyができないが、swimができるクラスになっています。
原因は、鳥クラスをペンギンが継承しており、そのペンギンクラスを鳩クラスが継承しています。
スーパークラスの鳥クラスが持っていた状態をペンギンクラスが大きく変えたことに気が付かずに、同じ鳥だからとペンギンクラスを継承して鳩クラスを作ってしまっています。

この場合は、ペンギンクラスと鳩クラスはこのようにコードすべきです。

public final class Penguin extends Bird {
	boolean fly = false;
	boolean swim = true;
}
public final class Pigeon extends Bird {
}

ペンギンクラスはそれが特殊な振る舞いや状態に変化していることを理解し、継承されるのを防ぐべきです。
鳩クラスはペンギンからでなく、直接継承すべき鳥クラスから継承するべきで、さらに同様に継承されるのを防ぐべきです。

これにより、正しい親子関係のクラスがかけると思います。
こちらのほうが、理解もしやすいと思います。

今回は変数で説明しましたが、同様にメソッドでもfinalの重要性が言えます。
同様に考えて設計/実装してください。

本日は以上です。