- ベストアンサー
protectedメソッドが使用できる範囲
protectedメソッド(もしくはコンストラクタ)はサブクラスからであればアクセスできると覚えていたのですが、以下のような使い方だとサブクラスから見えなくなるようです。 サブクラスでも別パッケージからは参照できないのでしょうか。 ------------------------- package sample.a; import sample.b.*; public class Main2 { public Main2() { } protected Main2(int a){ } protected void hoge(){ } } -------------------------- package sample.b; public class Main extends Main2{ public void hoge(){ Main2 m2 = new Main2(1);//ここでエラー m2.hoge(); //この使い方もエラー } } -------------------------------
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
Mo2,3のものです。改めて回答を。 サブクラスからアクセスできる、という考え方ですが、 この例でいいますと Mainクラス内で super.hoge(); は使用できます。(これがNo2の回答として間違っているところです・・・。) 【protectedメソッドはサブクラスからであればアクセスできる】という考え方に則しています。 (別パッケージからでもサブクラスから継承元クラスにアクセスしているということ) また、同様にMainに protected Main(int a){ super(a) } とそのコンストラクタ中にMain2(super)のコンストラクタを呼び出すことも可能です。 これも上記のことを言えるといえます。 しかし、 Main2 m2 = new Main2(1); で指定しているMain2と継承として宣言しているMain2との関係性とは、別のものとして考えることになります。 Mainクラスの空間から考えると、new宣言して生成したMain2は継承していること別のものとして考えることになり、またそれは別パッケージですのでprotectedであるコンストラクタにはアクセスできません。 つまりsuper.~とすれば別パッケージに属していたとしても、サブクラスから親クラスのメソッド、コンストラクタにアクセスするということを明示できるのでアクセス可能ということです。 説明が煩雑になり申し訳ありません。 No2で示した参考URLを見ていただければわかりやすいかもしまれません。
その他の回答 (5)
- hrm_mmm
- ベストアンサー率63% (292/459)
importを書く場所を間違えてるようです。 package sample.a 内のMain2では、他のpackageにあるものを使ってないので、import文は不要(質問文では省略してあるだけなら、必要だけど) package sample.bの方は、package sample.aに記述されているクラスを使いたいので、 import sample.a.Main2; が必要 importは、publicかprotectedかによらず、これから使うクラスがどこにあるのかをJVMに教えるためのものです。importされていないpackageのクラスは、すべて見えません。 よって、同じpackage内にないならば、必ずimportするか、クラス名にpackage名を省略せずに付けるかしましょう。
- dyna_1550
- ベストアンサー率34% (122/353)
> protectedメソッド(もしくはコンストラクタ)はサブクラスからであればアクセスできると覚えていたのですが、 Java言語仕様を読むと「6.6」あたりからそのことが書かれています。 上記のケースでhoge() や Main2(int) を呼ぶためには、限定名がMainかMainのサブクラスである必要があると書かれています。 以下の書き方であればアクセスできます。(Mainと同じパッケージ内のクラスも同様) Main m = new Main(); m.hoge(); Java言語仕様の翻訳を探してみると以下のページがありました。 英文よりもこちらの方がわかりやすいかもしれませんが、英文も 読んでおきたいところです。 http://www.y-adagio.com/public/standards/tr_javalang/6.doc.htm#62587
お礼
回答ありがとうございます。 URLのページを見て納得しました。
- braver_2004
- ベストアンサー率62% (20/32)
申し訳ないです。 間違ったこと書きました。私の回答は忘れてください。
- braver_2004
- ベストアンサー率62% (20/32)
サンプルソースではMain2とMainは別パッケージですよね。 protectedはパッケージが違うとアクセスできません。 【サブクラスからであればアクセスできる】 という考え方以前に、 【同一パッケージである】 でないとprotectedにはアクセスできません。パッケージが違うものにアクセスするためにはそれがpublicでなくてはいけません。 参考URLを見ていただければわかりやすいかと思います。 ですので、No1の方が提示しているようにsuperのコンストラクタを呼んでもエラーになります。 ちなみに、No1の方が、Objectクラスのコンストラクタを呼び出す必要があります、とおっしゃっていますが、これは必要条件ではなく、実装しなくても問題ありません。設計上で考える問題になります。(コンストラクタ中で親のコンストラクタを呼ぶべきか。独自の処理をするべきか。もしく処理をしないのか。。。と。)
- Leigong
- ベストアンサー率66% (2/3)
コンストラクタの実装に問題があります。 Javaでは、すべてのオブジェクトはObjectクラスを継承します。 このため、Objectクラスのコンストラクタを呼び出す必要があります。 例) protected Main2(int i){ super(); } この例を試してみてください。 これでもエラーが出る場合、エラーメッセージも書き込んでいただいたほうがよろしいかと思います。
お礼
回答ありがとうございます。 上記のコードを試しましたが、結果は同じエラーでした。 エラーの内容は The constructor Main2(int) is not visible です。
お礼
回答ありがとうございます。 おっしゃる通りで、私がprotectedの動作を勘違いしていました。