javaがメソッドを見つけられないのはなぜですか?
質問
私は、Javaで何かに心を包み込もうとしています。オブジェクトを別のクラスのメソッドに渡すとき、そのオブジェクトクラスに固有のメソッドを呼び出すことはできませんか?
以下の例のようなコンパイルできない理由コードは何ですか?
ありがとうございます
class a {
public static void myMethod(Object myObj) {
myObj.testing();
}
}
class b {
public void testing() {
System.out.println ("TESTING!!!");
}
}
class c {
public static void main (String[] args) {
b myB = new b();
a.myMethod(myB);
}
}
編集:myMethodのパラメーターをObject型として残した理由は、testing()メソッドを持つさまざまなオブジェクト型を渡すことができるようにするためです。
解決
testing()
メソッドを使用してさまざまなオブジェクトを渡したい場合、各オブジェクトに Testable
インターフェースを実装させます:
public interface Testable
{
public void testing()
}
次に、 myMethod()
で Testable
を取得します。
public static void myMethod(Testable testable)
{
testable.testing();
}
編集:明確にするために、インターフェースを実装すると、クラスにメソッドがあることが保証されますが、メソッドは必要なことを何でも行うことができます。したがって、 testing()
メソッドが異なることを行う2つのクラスを持つことができます。
public class AClass implements Testable
{
public void testing()
{
System.out.println("Hello world");
}
}
public class BClass implements Testable
{
public void testing()
{
System.out.println("Hello underworld");
}
}
他のヒント
問題は、実際に実行されるまで myMethod
が b
オブジェクトを取得していることを認識できないことです。知っている限り、 String
を渡すことができます。
変更して
public static void myMethod(b myObj) {
myObj.testing();
}
これで動作するはずです。
質問の更新:
編集:myMethodのパラメーターをObject型として残した理由は、testing()メソッドを持つさまざまなオブジェクト型を渡すことができるようにするためです。
Amanda Sと他のいくつかの人が言ったように、これはインターフェースの完璧な例です。これを行う方法は、 testing()
メソッドを定義するインターフェイスを作成し、そのインターフェイスを実装するオブジェクトを取得するように myMethod
を変更することです。
代替の解決策(インターフェイスなし)は、オブジェクトに testing()
メソッドがあるかどうかを反射的に検出して呼び出すことですが、これは推奨されておらず、このような単純なケースには必要ありません。
あなたが話しているのは、アヒルのタイピングです。 Javaにはアヒルの入力はありません。
したがって、 testing()
メソッドを持つすべてのクラスが実装するインターフェースを定義する必要があります。
e.g:
public interface Testable
{
public void testing()
}
class B implements Testable
{
public void testing() {
System.out.println ("TESTING!!!");
}
}
class A {
public static void myMethod(Testable myObj) {
myObj.testing();
}
}
あなたの問題は、インターフェースを支持する古典的な議論です。できるだけ汎用的にしたいが、渡すすべてのオブジェクトにtesting()メソッドを持たせたい。私は次のラインに沿って何かを提案します:
public interface Testable
{
public void testing();
}
public class A
{
public static void myMethod(Testable myObj)
{
myObj.testing();
}
}
public class B implements Testable
{
public void testing()
{
System.out.println("This is class B");
}
}
public class C implements Testable
{
public void testing()
{
System.out.println("This is class C");
}
}
public class Test
{
public static void main (String[] args)
{
B myB = new B();
C myC = new C();
A.myMethod(myB); // "This is class B"
A.myMethod(myC); // "This is class C"
}
}
オブジェクトを渡すため(bはオブジェクトから継承します)。オブジェクトにはテストがありません。bにはあります。
bを渡すか、メソッドを呼び出す前にオブジェクトをbにキャストできます。
編集 そのメソッドを実装するジェネリッククラスを渡すには、メソッドシグネチャを持つインターフェイスを作成し、Objectではなくインターフェイスタイプを渡します。渡すすべてのオブジェクトは、インターフェースを実装する必要があります。
オブジェクトへの参照の種類に対して表示されているメンバーにのみアクセスできます。
myMethod(Object myObj)
の場合、これはObjectで定義されたメンバーのみを意味するため、 class a
では class b
のメンバー>は表示されません。
a.myMethod
の定義を public static void myMethod(b myObj)
に変更した場合、 testing
myMethod
での b
のインスタンスのcode>メソッド。
説明に基づいた更新:
その場合、それらすべてを実装するためのインターフェースを定義することは、おそらくあなたが望むものです。
public interface Testable {
public void testing();
}
public class a {
public static void myMethod(Testable myObj) {
myObj.testing();
}
}
public class b implements Testable {
public void testing () {
System.out.println("TESTING!!!");
}
}
Javaがメソッドを見つけられないのはなぜですか?
Javaの設計方法のため。
Javaは"静的に型付けされた" です。これは、オブジェクトタイプが中にチェックされることを意味しますコンパイル。
Javaでは、メソッドがそのタイプに属する場合にのみメソッドを呼び出すことができます。
この検証はコンパイル中に行われ、Object型には" testing()"がないため、メソッド、コンパイルは失敗します(たとえ実行時にオブジェクトにそのメソッドがあったとしても。」これは主に安全のためです。
他の人が説明する回避策では、コンパイラに伝えることができる新しい型を作成する必要があります
"ねえ、このタイプのインスタンスは テスト方法に応答します
さまざまなオブジェクトを渡し、それらを非常に汎用的に保ちたい場合、1つの方法は、それらのオブジェクトを実装およびインターフェースすることです。
public interface Testable {
public void testing();
}
class A implements Testable { // here this class commits to respond to "testing" message
public void testing() {
}
}
class B implements Testable { // B "is" testable
public void testing() {
System.out.println("Testing from b");
}
}
class C implements Testable { // C is... etc.
public void testing() {
//....
}
}
後でどこか
public void doTest( Testable object ) {
object.testing();
}
doTest( new A() );
doTest( new B() );
doTest( new C() );
" OTHER"これを行う方法は、javaで反射的にメソッドを呼び出すことです。 、しかし、それがあなたが必要とするものかどうかはわかりません、その方法でコードを実行するとはるかに抽象的ですが、それは自動化されたテストフレームワーク(およびHibernateなどの他の多くのフレームワーク)が実際に機能する方法です
これが理由を明確にするのに役立つことを願っています。
本当に、パラメーターを可能な限り抽象的に保ちたい場合は、リフレクションAPIを検討する必要があります。そのようにして、必要なオブジェクトを渡し、必要なメソッドを動的に実行できます。 いくつかの例をご覧ください。
これが唯一の方法ではありませんが、問題によっては有効な代替手段になる可能性があります。
リフレクションは、メソッドを直接呼び出すよりもはるかに遅いことに注意してください。 Amandaの投稿にあるようなインターフェースも使用することを検討してください。