【Java言語】オブジェクト指向プログラミングの疑問

Java言語を勉強中です。使用法は理解出来たのですが、以下の用途がわかりません。

質問1: protected修飾子の使い方について
 カプセル化を緩めたいのはどんなときでしょうか?
 サブクラスからアクセス可能にするメリットは何でしょうか?

質問2: メソッドのオーバーライドについて
 スーパークラスでメソッドだけ定義し、サブクラスでメソッドをオーバーライドする場合があるようですが、スーパークラスのメソッド定義はなんのためにあるのでしょうか?

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/05/26 20:05:00

ベストアンサー

id:a-kuma3 No.1

回答回数4974ベストアンサー獲得回数2154

質問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 パターンなんかは、スーパークラスで抽象メソッドを定義しているのが肝ですよね。

他1件のコメントを見る
id:a-kuma3

一方、公開範囲の決め方はとても難しそうです。
何か、決め方や指針のようなものはあるのでしょうか?

これは、人によっていろいろ意見が分かれそう。

ぼくは、公開範囲(スコープ)は、それだけを決めるものでは無くて、結果として決まるものだと思ってます。
コードを書く前に、クラス設計をします。
クラス図やコラボレーション図、シーケンス図が出来上がります。
それぞれのクラス間を線で結んだところ(クラス図の集約などは除く)は、public です。
それ以外は、デフォルトで private にして、設計を詳細にしていく過程で、protect にしたり、
public にするようにしてます。

一旦、緩いスコープにしてしまうと、厳しい(狭い)スコープにするのは、いろいろ面倒なので、
最初、厳しくしておいて、必要に応じて緩めていく、という感じです。

それ以外では、デザインパターンを使うところは、スコープも決まってるので、あまり悩みません。

2012/05/26 17:32:45
id:kananaskismoon

再び、ありがとうございます。
とても参考になりました。おかげ様で次のステップが見えてきました。
ひと通り用法を覚えたら、次は設計とデザインパターンに進みたいと思います。
適した書籍やサイトがありましたら、コメントいただければ幸いです。
(もちろん、どなたの推薦でも大歓迎です!)

疑問点も解決したので、質問を終了します。

2012/05/26 20:04:48
  • id:a-kuma3
    >適した書籍やサイトがありましたら、コメントいただければ幸いです。
    どちらも古くて恐縮なんですが、この二つは(ぼくの中では)鉄板です。

    「オブジェクト指向方法論OMT モデル化と設計」
    http://www.amazon.co.jp/dp/4810185273/

    「オブジェクト指向における再利用のためのデザインパターン」
    http://www.amazon.co.jp/dp/4797311126/

    デザインパターンの方は、いろんなサイトに載ってます。
    著者たちを称して GoF (Gang Of Four) というのですが、それをキーワードにして探すと、たくさんみつかります。

    http://www.techscore.com/tech/DesignPattern/index.html
    ここが最高、というわけでは無いんですが、原著のパターンに忠実なのと、
    サンプルが java で書かれているんで、紹介しておきます。
  • id:kananaskismoon
    ありがとうございます!
    挙げていただいたところにじっくり目を通します!

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません