• ベストアンサー

【アクセス修飾子】アクセス修飾子無しのクラスにpublicなメソッド

アクセス修飾子無しのクラスのメソッドにpublicを付ける意味がわかりません。 class MyClass {  public void method() {} } 例えばこのようなクラスがあったとします。 このクラスはアクセス修飾子無しで他のパッケージからはアクセス出来ない為、メソッドにpublicを付ける意味は無いと思うのですが、付けてもコンパイルは通ります。 何故なんだろう、と考えてみたのですが、例えばpublicなメソッドを持つpublicなクラスを継承し、そのメソッドをオーバーライドした時にメソッドにpublicを付けざるを得ない、あるいは、インターフェイス(暗黙的にメソッドにpublicが付く)を実装したときにメソッドにpublicを付けざるを得ない等、そういう場合に対応するための『遊び』みたいなものなのでしょうか? 御教授よろしくお願いします。

  • Java
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • bgbg
  • ベストアンサー率53% (94/175)
回答No.1

> 例えばpublicなメソッドを持つpublicなクラスを継承し、そのメソッドをオーバーライドした時にメソッドにpublicを付けざるを得ない、あるいは、インターフェイス(暗黙的にメソッドにpublicが付く)を実装したときにメソッドにpublicを付けざるを得ない等、そういう場合に対応するための『遊び』みたいなものなのでしょうか? 『遊び』ではなく、実際にそのような形で外部のクラスに内部クラスのメソッド等を使わせるような場合に使用します。 例えば、java.util.zip.ZipFile#getInputStreamはInputStreamクラスを返しますが、実装では場合によりInputStreamクラスを継承した内部クラス(内部クラスなのでpublicは付いていない。private)を返します。 readメソッドはオーバーライドされ、独自の実装が加えられていますが、アクセス修飾子はpublicであるため、外部パッケージのクラスからもアクセスすることができます(通常のInputStreamと同じようにreadが出来る)。 詳しくは実際にソースを見て下さい。

kousai
質問者

お礼

こちらに書くべきでした。 重ねて、ありがとうございました。

kousai
質問者

補足

 理解出来ました。  クラスがprivateでも、そのメソッドに全くアクセス出来ない訳ではないんですね。  つまり、privateな内部クラスのオブジェクトをクラス内で生成し、それをスーパークラスの型の参照変数に入れ、getメソッドのような形でパッケージの外に渡せば、そのprivateな内部クラスのpublicなメソッドが(スーパークラスのメソッドをオーバーライドしたもの限定で)使えますね。  使いたいメソッドがオーバーライドされたものであることがポイントかなと思いました。    具体的な例をありがとうございました。

その他の回答 (1)

  • auty
  • ベストアンサー率58% (284/486)
回答No.2

確かにオーバーライドにより機能は変わるでしょうが、 「遊び」というよりご指摘のように、 ・ メソッドの名前は必ず残したい、 ・ つまりこのクラスのサブクラスである限りは、必ずその名前を使えるように強制したい。 と言う事ではないでしょうか。 もしパブリックにしないと、サブクラスとして公開したときに そのメソッドを使えなく出来ますね。

kousai
質問者

お礼

なるほど、サブクラスの方も考えてみるべきでした。(スーパークラスのことだけ考えていました。) まだ混乱しているのですが、もう少しじっくり考えてみます。 ご回答ありがとうございました。

関連するQ&A

  • C# メソッドのアクセス修飾子について

    以下のような宣言の仕方は可能でしょうか? class Test { public void method() { } } classのデフォルトのアクセス修飾子はinternalになるかと思うのですが、その場合メソッドの修飾子にpublicが指定できるのかという質問です。

  • アクセス修飾子の指定相手と、そのスコープとの関係性。

    アクセス修飾子の指定相手と、そのスコープとの関係性。 Java初心者であるため、変なことを言うかもしれませんが、宜しくお願い致します。 クラスや、メンバにアクセス修飾子は付けられますが、 その修飾のしかたの組み合わせによって、 アクセスできるスコープが色々と場合分けされると思うのですが、 このあたりは、どう考えたら良いのでしょうか? 例えば、 //(1) public class MyClass1 {  private int n1; } //↑クラス自体は、どこからでも使用可能だが、 //フィールドn1はMyClass1内部からのみ使用可能。 //(2) private class MyClass2{  public int n2; } //↑ん~、なんだこりゃ~??(こんな書き方はない??) //------------------------------ //(3) public interface MyInterface{  int n3 = 3; } //↑インターフェース自体も、そのフィールド(定数)n3も、どこからでも使用可能! //(4) interface MyInterface{  int n4 = 4; } //↑インターフェース自体も、そのフィールド(定数)n4も、 //同じパッケージ内からのみ使用可能! //(5) abstract interface MyInterface{  int n5 = 5;  void mymethod();  //自動的にpublic abstract指定になるのですよね…?  abstract mymethod2();  //publicだけ、自動指定される扱い、といった感じで…。 } //↑なんじゃこりゃー!わかりませんっ! //もし仮に、このインターフェースにメソッドを書かないとエラーが出ます? //というか、インターフェースにabstractキーワードを指定できる意味がよく分かりません。 //------------------------------ (1)~(2)がクラス編、(3)~(5)がインターフェース編。 特に(2)、(5)について、どなたかアドバイスして下さい。

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

    「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」は正しい? はじめまして。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
  • StratsのActionクラスのexecuteメソッドは何故abstructじゃないの?

    StratsのActionクラスのexecuteメソッドは何故abstructではないのでしょうか? Actionクラスを実装するのであれば必ずexecuteを実装すると思います。 なので必ずexecuteメソッドをオーバーライドすると思います。 既に実装してあっても意味がないのではないかと感じました。

    • ベストアンサー
    • Java
  • 継承・実装の関係で悩んでいます。

    継承・実装の関係について悩んでいます。 ここでは、アクセス制御を考えずに、インスタンスかstaticかabstract(ここではabstract final staticやabstract classのこと)の違いで、どう継承するのか考えています。 // 継承 はメソッドのオーバーライドのことを考えます。(オーバーロードは考えない) クラスAからクラスBでオーバーライドしたメソッドは、 クラスCでさらにオーバーライドできるのでしょうか? クラスCが クラスBのクラスAからオーバーライドしたメソッド をクラスBのメソッドとして見たときに、オーバーライドすることは可能なのでしょうか? クラスA │ インスタンスフィールドA │ staticフィールドA │ │ クラスA() { } │ │ インスタンスメソッドA () { } │ staticメソッドB() { } ↓ クラスB extends クラスA │ インスタンスフィールドA // 継承 │ インスタンスフィールドB │ staticフィールドB │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ インスタンスメソッドA () { } // 継承 │ │ インスタンスメソッドB () { } │ staticメソッドB () { } ↓ クラスC extends クラスB implements インタフェースD, ... ↑ インスタンスフィールドA // クラスBのフィールドを継承 │ インスタンスフィールドB // クラスBのフィールドを継承 │ インスタンスフィールドC │ staticフィールドC │ │ サブクラス2() { } │ │ インスタンスメソッドA () { } // クラスBのメソッドを継承 │ インスタンスメソッドB () { } // クラスBのメソッドを継承 │ インスタンスメソッドD () { } // インタフェースDのメソッドを実装 │ インスタンスメソッドE () { } // インタフェースDのメソッドを実装 │ │ │ インスタンスメソッドC () { } │ staticメソッドC() { } │ interface インタフェースD extends インタフェースE ↑ │ staticフィールドD // public static final │ │ インスタンスメソッドD() { } // public abstract │ インスタンスメソッドE() { } // 継承 │ interface インタフェースE staticフィールドE // public static final インスタンスメソッドE() { } // public abstract

    • ベストアンサー
    • Java
  • クラス修飾子やアクセス修飾子を省略したパッケージ・プライベートは同じフォルダの下層フォルダにも公開するのですか?

     クラス修飾子やアクセス修飾子を省略したパッケージ・プライベートは同じフォルダの下層フォルダにも公開するのですか?  publicなどのクラス修飾子やアクセス修飾子を省略すると、同じフォルダ内のクラスにだけ公開されているパッケージ・プライベートなクラスなど(変数、メソッドとかのメンバを含む)になる、とのことですが、これは同じフォルダだけでなく同じフォルダの下層フォルダにも公開するのですか?  フォルダはパッケージのことです。 Windowsユーザーに分かりやすい言い方で記述しました。  よろしくお願いいたします。

    • ベストアンサー
    • Java
  • 親クラスのメソッドを別のパッケージの子クラスでオーバーライドするときについて

    早速ではございますが、質問をさせていただきます。 親クラスのパッケージとは異なるパッケージに子クラスが あるとき、子クラスが親クラスのメソッドをオーバーライ ドするときに、親クラスのメソッドのアクセス修飾子を publicかprotectedにしなければコンパイルエラーになり ます。それはなぜなのでしょうか? どうかご教授のほどよろしくお願いします。

    • ベストアンサー
    • Java
  • 抽象メソッド、抽象クラス

    C#を勉強しております。Javaにも同じ機能がありC#のカテゴリーがない為こちらで質問させていただきます。抽象メソッドや抽象クラスを使う利点に関してです。 これらを使う利点を調べたところオーバーライドさせられると書いてありました。オーバーライドしないと 実装がないのでエラーになると書いてありました。その点は理解できたのですが何故基本クラスで実体のない定義をする利点がよくわかりません。それなら最初から派生クラスの方にメソッドを定義すればいいのではという考えになりました。 抽象メソッドとして実体のない定義を行う利点なるものを教えてください。 よろしくお願いします。

  • 継承したメソッドのドキュメンテーションコメント

    C#の開発を始めて日が浅いため、現場におけるお作法がわかりません。 現場におけるクラス・インターフェースを継承したメソッドのドキュメンテーションコメントの付け方に関する一般論についてお教えいただきたいです。 ※基底クラス、及びインターフェースの抽象メソッドにはドキュメンテーションコメントの記述がある物とします。 ※普段はJavaを使っている為、そこから引用している書いている部分があります。ご容赦下さい。 ・抽象クラスにおけるインターフェースから継承した抽象メソッド(実装しない場合) Javaとは違い、抽象クラスであってもインターフェースが持つの抽象メソッドを無視する事はできず、 public abstract修飾子を付けて抽象メソッドを定義してやる必要があるようなのですが、 この場合、ドキュメンテーションコメントは省略すべきでしょうか? それとも、何かしら記述するべきなのでしょうか?(Javaで言うところの@inheritDoc等・・・そのような物があるかはわかりませんが) ・新たに実装を行う場合(抽象メソッドの実装等) 省略すべきでしょうか? ・既存の実装を拡張し、変更の影響は微小かつメソッド内のみで完結し、概要やその他のメソッドの責任において表記すべき内容に変化が無い場合 省略すべきでしょうか? ・既存の実装を拡張し、想定される例外の追加等、メソッド外にも影響を及ぼす大きな変更が入った場合 新たに完全なドキュメンテーションコメントを作成するべきでしょうか? それとも差分以外は新たに作成すべきではないのでしょうか? 一般論と言っても規模や進め方によって様々だとは思いますが、 通念的に「心がけていくべき事」等あれば、是非お教え下さい。 最後に、この質問の趣旨からは外れるのですが、一つ追加で別の質問をさせてください。 私は何故抽象クラスがインターフェースの抽象メソッドを無視できないかがわかっておりません。 (インターフェース-インターフェース、抽象クラス-抽象クラスは無視できるのに) 敢えて明示的に定義を強要させている以上、何か理由あっての事だと思いますが、 それがわからず悶々村々としながら作業しております。 その理由をお教えいただけませんでしょうか。 宜しくお願い致します。

  • 抽象クラスのオブジェクトを生成できない理由は?

    ・抽象クラスは、なぜ(オーバーライドしないと)オブジェクトを生成できないのでしょうか? ・インタフェースみたいに、抽象メソッドしか宣言することができないなら話は分かるのですが… ・抽象メソッドでない普通のメソッドを実装できるのなら、オブジェクトを生成してくれても良いと思うのですが… ・そういう問題ではない?

    • ベストアンサー
    • Java

専門家に質問してみよう