いまサーブレットをやっています。

Java言語仕様では、

「インターフェースの定義には、メソッドの定義を書いてはいけない」
(メソッドの定義はそのインターフェースをimplementsしたクラスのなかで
オーバーライドする)

ということになってますよね?

…でも、

APIリファレンスを読むと、
インターフェースHttpServletRequestのメソッドgetParameterには、
「リクエストパラメータの値をString型として返す」と書かれています。

↑これって上記のJava言語仕様と矛盾してませんか?
まるでどこかでgetParameterメソッドの定義がなされているかのようです。

これってどういうことでしょう?
考えれば考えるほど、訳わかりません。とっても混乱中です(-_-)

このQ&Aに関連する最新のQ&A

A 回答 (3件)

ああ、余計に説明しすぎている気がするわけですね。

もっと抽象的に
「getParameterはなんだかわからないけどとにかくString型を
返す」
だったらわかるのに、と?
実際、implementsするクラスでは、getParameterとしてランダム
な文字列やらあなたの名前やらを返すメソッドを定義してもJava
言語仕様としては間違いではありません。

でもそれじゃあ意味のある名前をメソッドにつけるのも無駄になり
ませんか?「get1」「get2」でもいいような。

あるクラスがインタフェースをimplementsするというのは、
そのクラスが宣言されたメソッドをすべて完備していて、
そのインタフェースの役割を演じることができる、ということを
約束するものです。逆に漏れがあればコンパイラが怒ってくれると。
ですからドキュメントとして各メソッドの役目をある程度解説する
のは、インタフェースの本来の意図を伝えるものとして意味がある
ことです。

比喩としては、「高級アパートというのはバス、トイレ、洗面台を
完備していなければならない」という法律の細則に「バスは体を
洗浄したり湯船で体を暖めるサービスを提供する」とあるのを、
実際にアパートを建築する業者が「そりゃ具体的に説明しすぎて
ないか?まるでどこかにもうあるアパートのことを言ってるみたい
じゃないか」と文句を言っているのに近いです。実際はシャワーだけ
とか、庭の片隅においてあるドラム缶だって立派な「バス」じゃない
か、と。極端な話、ダンボール箱と洗面器だけでトイレと洗面台と
称しても、法律的には違反じゃないけど、人道的にいかがなものか。

「リクエストパラメータの値を返す」でも、十分抽象的ではあります。
実際にはパラメータをこっそりどこかのファイルにログとして
吐き出しておいてから返してもいいし、データベースにためておいて
一番古いものを検索して返してもいい。まずいパラメータの値は
検閲するような仕組みでもいい。要は、それをimplementsした
クラスが、getParameterを「リクエストパラメータの値を
返すメソッド」として使えればいいわけです。それくらいは説明
してくれないと、利用者としては不便です。
    • good
    • 0
この回答へのお礼

Headさんは専門家の方だけあって、さすがに文章も論理的ですね。
それゆえ頭の悪い僕としては、
Headさんの文章を一度読んだだけでは理解できませんでした。(-_-)??
でももう大丈夫です。
ちゃんと理解できました。(^ー^)


3度も投稿してくださって本当にありがとございます。
とても役に立ちました。

お礼日時:2001/05/28 12:28

そうそう、実際にソースが見られたらいいんですが、HttpServletRequest


のgetParameterのところは、
String getParameter();
としか書いてないと思いますよ。
    • good
    • 0

ああ、それは「宣言」と「定義(実装)」を混同してしまっている


のですね。用語の問題だと思いますよ。
インタフェースでは、メソッドの定義、すなわちその中身の
処理について実装を定義することはできません。(if (...) {...}みた
いに)
しかし、どういう名前のメソッドで引き数としてどういう型の
値を受けて、どういう型の値を返すか、を宣言することはできます。
というかそれが目的です。

インタフェースHttpServletRequestを実装するクラスは、
Stringクラスの値を返すgetParameterメソッドを定義しなければ
ならない、とインタフェースでは「宣言」されていることを
表しています。

この回答への補足

どうやら、こちらの言葉不足で誤解を与えてしまったようです。

「インターフェースの定義には、メソッドの定義を書いてはいけない」の部分を以下のように訂正します。

「インターフェースの宣言には、メソッドの処理内容を定義してはいけない」

つまり僕が知りたいのは、インターフェース宣言ではメソッドの処理内容を定義してはいけないはずなのに、APIリファレンスを見るとそのメソッドの処理内容というか機能みたいなのが書かれてあるのでおかしいのではないか、ということなんです。
どうぞご存知でしたら教えてください。

補足日時:2001/05/27 10:02
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qjava言語 こんにちは。 java言語をまだ習ってなく先生からこれをそのまま打ち込めって言われたん

java言語

こんにちは。
java言語をまだ習ってなく先生からこれをそのまま打ち込めって言われたんですが、一行目がどうしてもエラーが出てしまいどうすればいいのがわからないです。
よろしくお願いします

Aベストアンサー

これ、androidstudio かな?
javaの初心者が触るIDEではないと思いますが⚪⚪⚪⚪
いきなりandroid開発なんですか? 無謀だと思います。

IDEではパッケージ名は普通手で入力したりしません。
まず、パッケージを作り、その下にJavaファイルを作れば
勝手にpackage文が挿入されます。

パッケージ名はjavaファイルのフォルダ名なので
javaファイルを作成するフォルダで決まってしまいます。

Q静的メソッドとインスタンスメソッドを定義する方法

簡単な、カウンタクラスからのインスタンス作成とその利用のテストを行いました。

テストとして作成した以下の内容のファイルをブラウザ(IEやFireFox)で開くと、期待した結果は返りますが、(Windowsで処理待ちを示す)砂時計マークがいつまで経っても消えません。

どこかで永続ループでもしているのでしょうか。

どこに問題があるのか、また、こういった問題のデバッグのコツを教えて下さい。
よろしくお願いします。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<HTML>
<HEAD>
<TITLE>教えて!goo</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="javascript">

<SCRIPT TYPE="text/javascript">
function Counter(initialCount) {
this.count = initialCount;
}

Counter.prototype = {
count : 0,
increment : function() {
this.count += 1;
},
decrement : function() {
this.count -= 1;
}
}

Counter.newInstance = function(initialCount) {
return new Counter(initialCount);
}

var counter;

function testCounter() {
counter = Counter.newInstance(100);
counter.increment();
document.write(counter.count);
}

</SCRIPT>

</HEAD>

<BODY ONLOAD="testCounter()">
</BODY>
</HTML>

簡単な、カウンタクラスからのインスタンス作成とその利用のテストを行いました。

テストとして作成した以下の内容のファイルをブラウザ(IEやFireFox)で開くと、期待した結果は返りますが、(Windowsで処理待ちを示す)砂時計マークがいつまで経っても消えません。

どこかで永続ループでもしているのでしょうか。

どこに問題があるのか、また、こういった問題のデバッグのコツを教えて下さい。
よろしくお願いします。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4...続きを読む

Aベストアンサー

writeで書き込んだ後はcloseしてください。

Qオーバーライドしたvalidateメソッドの結果をダイアログに表示する

オーバーライドしたvalidateメソッドの結果をダイアログに表示する方法

質問させてください。

strutsのvalidateメソッドをオーバーライドして入力フォームの値をチェックするようにしました。
このvalidateメソッドの結果をダイアログに表示するにはどのようにすれば良いでしょうか?

validation.xmlとオーバーライド前のvalidateメソッドを使用する場合は、JavaScriptを使用すれば可能のようですが、オーバーライドした関数には対応していないようです。(参考http://www.itmedia.co.jp/enterprise/0311/28/epn02_15.html)

どなたかお知恵をお貸しください。
よろしくお願いします。

Aベストアンサー

validateメソッドは、サーバ処理なのでvalidateの結果をダイアログに表示するJavaScriptを作れば解決できます。

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

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


はじめまして。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のインタフェースに関する質問です。

私はこれまで、インタフェースを使うときは、インタフェースを実装してクラスを宣言し、そのクラス、またはサブクラスでインタフェースがもつすべての抽象メソッドを定義する、と理解していました。

しかし、下の例をみてください。抽象メソッドの定義を、インタフェースの実装の以前で与えています。問題無くコンパイルでき、実行できます。実行結果も以下の通りで...続きを読む

Aベストアンサー

> インタフェース型の変数を用いた場合の、メソッドの宣言の見つけ方は、メソッドのオーバーライドの場合とは別物なのでしょうか?

JavaプログラムをJavaバイトコードにコンパイルすると普通のインスタンスメソッドの呼び出しはinvokevirtualに、インタフェース経由のメソッド呼び出しはinvokeinterfaceになります。しかし、これらのバイトコードが実行時にメソッドを探し出す手順は同じです。

interface I { void m(); }
class B extends A { ~ }
class C extends B implements I { ~ }
class D extends C { ~ }
というクラス階層があったとして、
I obj = new D();
obj.m();
というメソッド呼び出しがあった場合、
・Dにm()の定義があればそれを呼ぶ
・DになければC→B→Aとクラス階層を順にさかのぼってm()の定義を探す
となります。
インタフェースだからと言って特別な事はしていないし、Iで宣言されているメソッドの実体がAにあっても問題ないことが分かると思います。

> インタフェース型の変数を用いた場合の、メソッドの宣言の見つけ方は、メソッドのオーバーライドの場合とは別物なのでしょうか?

JavaプログラムをJavaバイトコードにコンパイルすると普通のインスタンスメソッドの呼び出しはinvokevirtualに、インタフェース経由のメソッド呼び出しはinvokeinterfaceになります。しかし、これらのバイトコードが実行時にメソッドを探し出す手順は同じです。

interface I { void m(); }
class B extends A { ~ }
class C extends B implements I { ~ }
class D extends C { ...続きを読む

Q親クラスのメソッドを別のパッケージの子クラスでオーバーライドするときについて

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

Aベストアンサー

……できれば、質問し直す時は分けて下さいね。いつまでたっても収束しませんから。


質問1への回答
 この場合、Mainと親クラスの関係だけが問題となります。
 親クラスのメソッドfunc()を、別パッケージのMainがアクセスできるのは、前の私の回答を順に当てはめればpublicしか無い事に気づくはずです。
 子クラスのオーバーライドの有無は関係ありません。Mainはインスタンスが親であれ子であれ、親クラスのクラス定義に従ってfunc()を読んでいるだけです。

質問2への回答
 それが多態性というものです。Oya.foo()はあくまでOya.func()を読んでいるに過ぎません。それがabstractで、実は実態がないものだとか、そういうのは関係ありません。なぜなら、実際にfoo()がfunc()を呼び出している時点で、なんらかのインスタンスが生成されている筈で、そのインスタンス生成の条件はクラスやメソッドがabstractでない事だからです。
 そうやって、「実態がある」と保証されたインスタンスのfunc()を呼んだ際には、オーバーライドによって実際のインスタンスを定義する子クラスkoのfunc()が呼び出されます。

……できれば、質問し直す時は分けて下さいね。いつまでたっても収束しませんから。


質問1への回答
 この場合、Mainと親クラスの関係だけが問題となります。
 親クラスのメソッドfunc()を、別パッケージのMainがアクセスできるのは、前の私の回答を順に当てはめればpublicしか無い事に気づくはずです。
 子クラスのオーバーライドの有無は関係ありません。Mainはインスタンスが親であれ子であれ、親クラスのクラス定義に従ってfunc()を読んでいるだけです。

質問2への回答
 それが多態性というも...続きを読む


このカテゴリの人気Q&Aランキング

おすすめ情報