• ベストアンサー

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(); //この使い方もエラー } } -------------------------------

  • Java
  • 回答数6
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

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を見ていただければわかりやすいかもしまれません。

solarin
質問者

お礼

回答ありがとうございます。 おっしゃる通りで、私がprotectedの動作を勘違いしていました。

その他の回答 (5)

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.6

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)
回答No.5

> 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:
http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html
solarin
質問者

お礼

回答ありがとうございます。 URLのページを見て納得しました。

回答No.3

申し訳ないです。 間違ったこと書きました。私の回答は忘れてください。

回答No.2

サンプルソースではMain2とMainは別パッケージですよね。 protectedはパッケージが違うとアクセスできません。 【サブクラスからであればアクセスできる】 という考え方以前に、 【同一パッケージである】 でないとprotectedにはアクセスできません。パッケージが違うものにアクセスするためにはそれがpublicでなくてはいけません。 参考URLを見ていただければわかりやすいかと思います。 ですので、No1の方が提示しているようにsuperのコンストラクタを呼んでもエラーになります。 ちなみに、No1の方が、Objectクラスのコンストラクタを呼び出す必要があります、とおっしゃっていますが、これは必要条件ではなく、実装しなくても問題ありません。設計上で考える問題になります。(コンストラクタ中で親のコンストラクタを呼ぶべきか。独自の処理をするべきか。もしく処理をしないのか。。。と。)

参考URL:
http://www.javaroad.jp/java_class7.htm
  • Leigong
  • ベストアンサー率66% (2/3)
回答No.1

コンストラクタの実装に問題があります。 Javaでは、すべてのオブジェクトはObjectクラスを継承します。 このため、Objectクラスのコンストラクタを呼び出す必要があります。 例) protected Main2(int i){ super(); } この例を試してみてください。 これでもエラーが出る場合、エラーメッセージも書き込んでいただいたほうがよろしいかと思います。

solarin
質問者

お礼

回答ありがとうございます。 上記のコードを試しましたが、結果は同じエラーでした。 エラーの内容は The constructor Main2(int) is not visible です。

関連するQ&A

  • あれ?

    すいません。 長い間、 疑問に思ってたことがあるんですけれども、 (1) import javax.swing.*; class Sample {  public static void main (String args[])  {   ........   Aメソッド()  } } (2) import javax.swing.*; class Sample extends aiueo {   public static void main (String args[])  {   ........   Aメソッド()  } } (3) class Sample extends aiueo {  public static void main (String args[])  {    ........   Aメソッド()  } } の違いが、 考えれば考えるほどわからなくなってきました。 パッケージと継承の関係について、 どうやら理解できていないみたいです。 どなたか分かりやすく教えてください。 よろしくお願いします。 (注) Aメソッドはaiueoクラスのメソッドとし、 aiueoクラスはjavax.swingパッケージに入っているものとします。

    • ベストアンサー
    • Java
  • protectedなのにアクセスできないのは何故 その2

    PHP初心者というより、 これはプログラム初心者と言うべきでしょうか。 もう1度同じ内容の質問をします。 それだけ物凄く困っています。 どうか手助けをお願い致します。 まず、ソースコードを見て下さい。 <?php //スーパークラスfooの定義 class foo { //xはprotected protected $x = 10; //yはprivate private $y = 10; } //サブクラスhogeの定義 class hoge extends foo { public function getX(){ return $this->x; } public function getY() { return $this->y; } } $o = new hoge(); echo "x = ".$o->getX()."(メソッド経由)\n"; echo "y = ".$o->getY()."(メソッド経由)\n"; echo "y = ".$o->y."(直接参照)\n"; echo "x= ".$o->x."(直接参照)\n"; var_dump($o); ?> これだと echo "x= ".$o->x."(直接参照)\n"; の部分がエラーになるんですよね。 $oはhogeクラスでfooクラスのサブクラスですよね。 なので、 echo "x= ".$o->x."(直接参照)\n"; これが何故エラーになるのか分かりません。 ここで確認ですが、$oはhogeのインスタンスではあるが、fooのサブクラスhogeとは別物である。 この解釈でいいんでしょうか。 どうぞ宜しくお願い致します。

    • ベストアンサー
    • PHP
  • protectedについて

    メソッドの前につけるprotectedについてなんですが 具体的にどこまでアクセスを許可するのでしょうか? 調べたところサブクラスと同じクラス内はいけるようですが 同じパッケージ内ではだめなのでしょうか?

    • ベストアンサー
    • Java
  • クラスの継承、メソッドのオーバーライド

    ↓の問題が全然わかりません。 問題:サブクラスのsiki2にax2+bx+c=0(b2-4ac>0)とコンストラクタ を定義して、スーパークラスのsiki1にax+b=0とコンストラクタを定義し、解を求めるkaiメソッドを定義する という問題です。途中のプログラムを↓に書きました。 スーパークラス class houteisiki1{ private int kai; private int a; private int b; private int x; //コンストラクタ houteisiki1(int s, int d, int e, int f){ solve=s; a=d; b=e; x=f; } //kaiメソッド kai=(a*x)+b; } サブクラス class houteisiki2 extends houteisiki1{ static int kai(int a, int b, int c, int x){ kai=(a*x*x)+(b*x)+c; if((b*b)+(-4*a*c)>0){ return kai; }else{ println("エラー"); } } } テストクラス class test{ public static void main(string[] args){ ここまで作りましたが、解らなくなりましたので教えてください。 まだ、JAVAを勉強して日が浅いので解りやすく教えてください。

    • ベストアンサー
    • Java
  • protectedなのにアクセスできないのは何故

    PHP初心者というより、 これはプログラム初心者と言うべきでしょうか。 まず、ソースコードを見て下さい。 <?php //スーパークラスfooの定義 class foo { //xはprotected protected $x = 10; //yはprivate private $y = 10; } //サブクラスhogeの定義 class hoge extends foo { public function getX(){ return $this->x; } public function getY() { return $this->y; } } $o = new hoge(); echo "x = ".$o->getX()."(メソッド経由)\n"; echo "y = ".$o->getY()."(メソッド経由)\n"; echo "y = ".$o->y."(直接参照)\n"; echo "x= ".$o->x."(直接参照)\n"; var_dump($o); ?> これだと echo "x= ".$o->x."(直接参照)\n"; の部分がエラーになるんですよね。 $oはhogeクラスでfooクラスのサブクラスですよね。 なので、 echo "x= ".$o->x."(直接参照)\n"; これが何故エラーになるのか分かりません。 厚かましいとは存じますが、低レベルな質問なんですけど、 オブジェクト指向のプログラムを学ぶ上で基本的な部分なので、 バカにでも分かる回答を宜しくお願い致したいと思う次第です。

    • ベストアンサー
    • PHP
  • スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラム

    スーパークラスからサブクラスのメソッドを使おうとする、以下のプログラムでつまずいています。 Aを継承したB、Cクラスのインスタンスを作成し、スーパークラスであるA型の配列asにまとめます。 それからループでas[i]にはいっている各インスタンスのメソッドを使いたいのですが、 スーパークラスAにmethod()がないためコンパイルできません、Aにmethod()を作るとA.method()が実行されます。 BとCを同じ配列に保存し、かつそれぞれのmethod()を実行したい場合どのようにしたら良いのでしょうか。 ご教授ください、どうぞよろしくお願いします。 class Main{ private B b; private C c; private A[] as = new A[2]; void mainMethod(){ as[0] = b = new B(); as[1] = c = new C(); for(int i=0; i<3; i++){ as[i].method(); } } } class A{} class B extends A{ void method(){ System.out.print("It is B"); } } class C extends A{ void method(){ System.out.print("It is C"); } }

  • メソッドのオーバーライド(java)

    class A3{ void hello(){ System.out.println("A3"); } void hello(int i){ System.out.println("A3"+i); } } class B3 extends A3{ void hello(){ System.out.println("B3"); } } class C3 extends B3{ void hello(String s){ System.out.println("C3"+s); } } class MethodOverriding3{ public static void main(String args[]){ A3 obj = new C3(); obj.hello(); } } 上のプログラムを実行すると"B3"と表示されまが、どうしてクラスBのメソッドが実行されるのでしょうか? クラスAのメソッドが無視される仕組みがわかりません。 また、クラスMethodOverriding3でobj.hello("abc")としてコンパイルすると mo.java:25: シンボルを見つけられません。 シンボル: メソッド hello(java.lang.String) 場所 : A3 の クラス obj.hello("abc");   ^ エラー 1 個 とエラーが出ます。 どうしてでしょうか? 誰か教えてください、お願いします。

    • ベストアンサー
    • Java
  • C++ protectedにアクセス不可

    C++でお聞きしたいことがあります。 初心者ですのでご容赦ください。 //基本クラス class a1 { protected: a1(); }; //派生クラス class a2 :public a1 { protected: a2():a1(){}; //継承先以外から作成されたくない int t; }; class a3 : public a2 //a2を継承 { public: a3(); ~a3(); private: a2* a; //a2のポインタを持つ }; a3::a3() { t = 3; a = new a2; //コンストラクタの中でnew } a3::~a3() { delete a; //終わったらdelete } int main(void) { a3 a; return 0; } というソースでa3はa2を継承しています。 ですのでa2のprotectedメンバtにアクセスできるはず。 ここまではいいのですが、 a2のコンストラクタもa3でアクセスでき無いのでしょうか? a3のコンストラクタでnewしようとすると error C2248: 'a2::a2' : protected メンバ (クラス 'a2' で宣言されている)にアクセスできません。 a2::a2' の宣言を確認してください。 というエラーが発生します。 やりたいのはa2のような基本クラスが6つほどあり、 a2のメンバ変数が多いので コンストラクタの引数で指定されたものだけ コンストラクタないでnewしたいのです。 なぜ、できないのか? どうすればnewできるようになるのか…。 非常にお手数ですが、 どなたかご回答いただけませんでしょうか? 長文になりましたが、宜しくお願いいたします。

  • 「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」

    「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」は正しい? はじめまして。Javaのインタフェースに関する質問です。 私はこれまで、インタフェースを使うときは、インタフェースを実装してクラスを宣言し、そのクラス、またはサブクラスでインタフェースがもつすべての抽象メソッドを定義する、と理解していました。 しかし、下の例をみてください。抽象メソッドの定義を、インタフェースの実装の以前で与えています。問題無くコンパイルでき、実行できます。実行結果も以下の通りです。 インタフェースの抽象メソッドへの定義の与え方やその実行のされ方は、メソッドのオーバーライドと同様と思っていましたので、下記のコードでは「クラスBが抽象クラスではありません」や、「インタフェースの抽象メソッドがオーバーライドされていません」などの文法エラーがでると思っていました。 そこで、質問です。 インタフェースが持つ抽象メソッドの定義を与える場所について、または、これに関する説明のあるページなど、何かご存知でしたら教えてください。 ★コード★ interface X{   void show(); } class A{   public void show(){     System.out.println("A");   } } class B extends A implements X{ } public class Main{   public static void main(String[] args){     X x=new B();     x.show();   } } ★実行結果★ >java Main A ★Java環境★ java 1.6.0_21 javac 1.6.0_16

    • ベストアンサー
    • Java
  • オーバーライドの必要性

    まだまだJavaを勉強している途中なのですが、下記のサンプルコードでオーバーライド(メソッドをオーバーロードすることをオーバーライドというのでしょうか…!?)のの必要性がよく分からなくなってしまったので質問させて頂きました。 /* sample.java */ abstract class super_class{  void write(){} } class CLASS1 extends super_class{  void write(){ System.out.println("CLASS1"); } } class CLASS2 extends super_class{  void write(){ System.out.println("CLASS2"); } } class sample{  public static void main(String args[]){   super_class obj = new CLASS2();   obj.write();   obj = new CLASS1();   obj.write();  } } 以上のコードを実行した場合 CLASS2 CLASS1 と表示されるのは多少なりとも勉強して分かったつもりでした…。 しかし、あくまでサンプルであるために特に意味がないことでもオーバーライドの説明をしているのだろうという風に考えてしまったのですが、 結局は、 スーパークラスとサブクラスに同じシグネチャのメソッドがあった場合、各サブクラスのメソッドが実行される と言うことは、スーパークラスのwrite()メソッドは何をしているのでしょうか? 多様性はJavaでも大切なものであるとのことなので質問させて頂きました。 なるべくわかりやすく説明して頂きたいと思います。 どうかお答えをお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう