• 締切済み

Javaのアクセス修飾子は4つで足りる?

Javaに、アクセス修飾子ってあるじゃん。デフォルトも含めて4つだけですけど、これで事足りますか?もう1つ加えて5つにすると、使いやすいかなと個人的に思うのですが。 何を追加したいかというと、「同パッケージ内のサブクラスのみアクセス可」です。何か名前をつけるなら familyです。サブクラスは同パッケージに作ることもあれば別パッケージに作ることもあって、2通り考えられるます。そのうち前者を、スーパークラスと血縁関係のある家族のように特別扱いします。家族の絆があればアクセス可としよう、そんな感じです。 現状の4つは (厳しい) 1.private 2.デフォルト 3.protected 4.public (緩い) 追加するfamilyは、1と2の間に位置します。 privateだと自クラスのみ、家族も排除。 デフォルトだと、同パッケージ内ならサブクラス(家族)に加えそれ以外のクラスもアクセス可、別パッケージからはサブクラスでも排除です。 familyに需要あると思うのですが、ドーかしら? 例えば、同パッケージ内にガンダムclassと鉄腕アトムclassとドラえもんclassを作ります。いずれもロボットですから、その共通点を抽出したロボットclassを作っておいて、後からそれをextendsで継承し、差分だけプログラミングします。こういうとき、カプセル化とかbeanの方針でロボットclassのフィールドにはprivateを付けたいところですが、それ付けちゃうと継承するときにsetterもgetterも機能しません。 かといって、privateをデフォルトやprotectedに変えると、緩すぎだと思う。familyがちょうど良いと思う。

みんなの回答

  • shiren2
  • ベストアンサー率47% (139/295)
回答No.4

補足についてですが、基本的に、 親クラスの全サブクラスに共通する機能でない限り、 親クラスに実装すべきではありません。 今回のようなケースだと、親クラスが子クラスの仕様に依存する形になってしまいます。 (子クラスは当然、親クラスに依存するが、親クラスも子クラス次第で次々と変更される…) 改善案としては、中間クラスを一つ設けるのもいいですが、 補助クラスを作って、必要なクラスは任意で参照するのもいいです。 補助関数は厳密にはメソッドではないということも、覚えておくとクラス設計の際に役立つと思います。 こんなところでしょうか。

five_163
質問者

補足

ロボットなら、自分の値段の半額をコッソリ計算できる。ガンダム、鉄腕アトム、色々なロボットがあるけど、全ロボットで半額計算機能を共通にしたい。 だから、スーパークラスにprivate int thinkHalf()を書きました。 このprivateがクセ者で、サブクラスには継承されない。かといって、それより1つ下のアクセス修飾のデフォルトにすると、同パッケージ内ならアクセスできちゃう(緩めすぎ)。だから、privateとデフォルトの間のfamilyを考えました。 補助クラスとか補助関数は初耳です。調べておきます。だけど、難しそう。familyの方が良いと思う。

  • shiren2
  • ベストアンサー率47% (139/295)
回答No.3

何か勘違いしているかもしれませんが…。 ロボットクラスにgetterとsetterを付けてprivateなフィールドにアクセス、 サブクラスからはsuperで親クラスのgetter/setterを呼びだせば済む話では。 そもそも子クラス如何で親クラスの機能が制限されると、isaの関係にならないです。

five_163
質問者

補足

微妙な例ですが、下にプログラム例を示します。thinkHalf()を機密処理にしたいのですが、tecパッケージ内サブクラスでは共有したいのです。 package tec; abstract class Robot{ private int price; public int getPrice(){return this.price;} public void setPrice(int x){this.price=x;} private int thinkHalf(){return this.price/2;}//このprivateをfamilyにしたい public abstract void walk(); } class Gundom extends Robot{ private String namePilot; public void walk(){System.out.println(this.namePilot+"行きます");} public Gundom(String x){ this.namePilot=x; System.out.println(super.thinkHalf());//エラー } } public class RobotCtrl{public static void main(String[] args){ Gundom guntank=new Gundom("アムロ"); guntank.setPrice(19800); System.out.println(guntank.getPrice()); guntank.walk(); }} getter/setterについては仰る通りだと思います。 ※字下げが消えちゃう。。。

回答No.2

10年以上使ってるけど必要性を感じない。

five_163
質問者

補足

必要性を感じないだけなら、ある分には良いのかな。Javaにgotoは必要無いけど、gotoが備わっていて、念の為だそうです。 アクセス修飾子はpublic1つで十分です。 C#にはinternalっていうアクセス修飾子があるそうだよ。たぶん、無くてもどうにかなると思うけど。

回答No.1

自分はJavaの専門家でも何でもないのでその善し悪しについては知りませんが、そんなにいいと思うなら、 提案したらどうでしょうか? https://jcp.org/en/home/index これを提案文として見るとしたら、 > かといって、privateをデフォルトやprotectedに変えると、緩すぎだと思う。 というのが曖昧ですね。どう緩すぎるのでしょうか? 提案文では緩すぎることにより起きる問題を具体的な例を挙げて説明をした方が良いと思います。 また、提案文では下記のAccess Levelsに新たな軸を追加してください。 https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html 現状あるものできれいにまとまっているように見えますが、それだと表せないものがあるとおっしゃりたいわけですから。 プログラミング言語の機能を提案する場合、いかにも実プログラムでありそうな例を挙げ、その機能のメリット、デメリットを見せてデメリットをカバーするだけの十分なメリットがあることを説得する必要があります。質問文を見る限り、実アプリケーションに近い例もなく、説明も不足しており、十分なメリットがあると判断することはできませんでした。

関連するQ&A

専門家に質問してみよう