Java言語を勉強中です。使用法は理解出来たのですが、以下の用途がわかりません。
質問1: protected修飾子の使い方について
カプセル化を緩めたいのはどんなときでしょうか?
サブクラスからアクセス可能にするメリットは何でしょうか?
質問2: メソッドのオーバーライドについて
スーパークラスでメソッドだけ定義し、サブクラスでメソッドをオーバーライドする場合があるようですが、スーパークラスのメソッド定義はなんのためにあるのでしょうか?
質問1: protected修飾子の使い方について
カプセル化を緩めたいのはどんなときでしょうか?
サブクラスからアクセス可能にするメリットは何でしょうか?
カプセル化を緩めるために使うわけじゃありません。
public class Base { ... } public class DerivedA extends Base { private void foo() { ... } public void bar() { foo(); ... } } public class DerivedB extends Base { private void foo() { ... // 実は、DerivedA::foo() と同じ処理 } public void qux() { foo(); ... } }
と書くよりも、以下のように書いた方が良いですよね。
public class Base { protected void foo() { // foo は、外に見せたくない(カプセル化) ... } } public class DerivedA extends Base { public void bar() { foo(); ... } } public class DerivedB extends Base { public void qux() { foo(); ... } }
質問2: メソッドのオーバーライドについて
スーパークラスでメソッドだけ定義し、サブクラスでメソッドをオーバーライドする場合があるようですが、スーパークラスのメソッド定義はなんのためにあるのでしょうか?
例えば、こんな感じ。
public Figure { /* 抽象化された「図形」クラスでは、どうやって描画して良いか分からない */ abstract public void draw(); } public Circle extends Figure { public void draw() { // 円の書き方は、分かる ... } } public Circle extends Square { public void draw() { // 四角形の書き方は、分かる ... } } public Foo { public void bar() { List<Figure> figureList = ...; for (Figure figure : figureList) { /* どんな図形が List に入ってるか分からなくても、描画はできる */ figure.draw(); ... } } }
他にも、デザインパターンのTemplate Method パターンなんかは、スーパークラスで抽象メソッドを定義しているのが肝ですよね。
これは、人によっていろいろ意見が分かれそう。
2012/05/26 17:32:45ぼくは、公開範囲(スコープ)は、それだけを決めるものでは無くて、結果として決まるものだと思ってます。
コードを書く前に、クラス設計をします。
クラス図やコラボレーション図、シーケンス図が出来上がります。
それぞれのクラス間を線で結んだところ(クラス図の集約などは除く)は、public です。
それ以外は、デフォルトで private にして、設計を詳細にしていく過程で、protect にしたり、
public にするようにしてます。
一旦、緩いスコープにしてしまうと、厳しい(狭い)スコープにするのは、いろいろ面倒なので、
最初、厳しくしておいて、必要に応じて緩めていく、という感じです。
それ以外では、デザインパターンを使うところは、スコープも決まってるので、あまり悩みません。
再び、ありがとうございます。
2012/05/26 20:04:48とても参考になりました。おかげ様で次のステップが見えてきました。
ひと通り用法を覚えたら、次は設計とデザインパターンに進みたいと思います。
適した書籍やサイトがありましたら、コメントいただければ幸いです。
(もちろん、どなたの推薦でも大歓迎です!)
疑問点も解決したので、質問を終了します。