我试图用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()方法。
答案 0 :(得分:19)
如果您想使用testing()
方法传递各种对象,请让每个对象实现Testable
接口:
public interface Testable
{
public void testing()
}
然后让myMethod()
获取Testable
。
public static void myMethod(Testable testable)
{
testable.testing();
}
编辑:为了澄清,实现一个接口意味着该类保证拥有该方法,但该方法可以做任何想做的事情。所以我可以有两个类testing()
方法做不同的事情。
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");
}
}
答案 1 :(得分:8)
问题是myMethod
在实际运行之前无法知道它正在获取b
对象。你知道的所有内容都可以传递String
。
将其更改为
public static void myMethod(b myObj) {
myObj.testing();
}
它应该有用。
更新问题:
编辑:我将myMethod中的参数保留为Object类型的原因是因为我希望能够传递各种对象类型,每种类型都有一个testing()方法。
正如Amanda S和其他几位人士所说,这是一个完美的界面案例。执行此操作的方法是创建一个定义testing()
方法的接口,并更改myMethod
以获取实现该接口的对象。
另一种解决方案(没有接口)将反射性地发现对象是否具有testing()
方法并调用它,但不建议这样做,并且对于这样一个简单的情况不需要。
答案 2 :(得分:6)
你所说的是鸭子打字。 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();
}
}
答案 3 :(得分:4)
您的问题是支持接口的经典论据。您希望尽可能通用,但是您希望传递的每个对象都有一个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"
}
}
答案 4 :(得分:2)
因为你传入一个Object(b继承自Object)。对象没有测试,b确实。
您可以在调用方法之前传入b或将对象强制转换为b。
EDIT 传入一个实现该方法的泛型类:您需要创建一个具有方法签名的接口,并传入接口类型而不是Object。您传入的所有对象都必须实现该接口。
答案 5 :(得分:1)
您只能访问对象所具有的引用类型可见的成员。
如果myMethod(Object myObj)
仅表示在对象中定义的成员,那么在class a
中class b
的成员将不会显示。
如果您将a.myMethod
的定义更改为public static void myMethod(b myObj)
,则可以在testing
中查看b
实例上的myMethod
方法}。
根据说明进行更新:
在这种情况下,为所有人实现定义接口可能就是你想要的。
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!!!");
}
}
答案 6 :(得分:1)
为什么java不能找到我的方法?
由于Java的设计方式。
Java是"statically typed",表示在编译期间检查对象类型。
在Java中,只有当该方法属于该类型时,才能调用方法。
由于此验证是在编译期间进行的,并且对象类型没有“testing()”方法,因此编译失败(即使在运行时对象确实具有该方法“。这主要是为了安全。
其他人描述的变通方法将要求您创建一个新类型,您可以在其中告诉编译器
“嘿,此类的实例将响应测试方法”
如果你想传递各种对象并保持它非常通用,一种方法是让这些对象实现和接口。
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中调用方法reflectively,但我不确定这是否是您需要的,因为当您这样做时代码更抽象,但这就是自动化测试框架(以及许多其他框架,如Hibernate)的实际工作方式。
我希望这有助于您澄清原因。
答案 7 :(得分:0)
如果你真的,真的想让参数尽可能保持抽象,你应该考虑反射API。这样,您可以传递任何您想要的对象并动态执行您想要的方法。您可以查看some examples。
这不是唯一的方法,但根据您的问题,它可能是一个有效的选择。
请记住,反射比直接调用方法要慢。您也可以考虑使用界面,例如Amanda的帖子。