假设我有MyInterface接口和2个实现MyInterface的类A,B
我声明了两个对象:MyInterface a = new A()
和MyInterface b = new B()
当我尝试传递给函数时 - 函数doSomething(A a){}
我收到错误。
这是我的代码:
public interface MyInterface {}
public class A implements MyInterface{}
public class B implements MyInterface{}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
test(b);
}
public static void test(A a){
System.out.println("A");
}
public static void test(B b){
System.out.println("B");
}
}
我的问题是我从某个组件界面获取了各种类,我需要为每个类编写函数。
所以一种方法是获取接口并检查它是哪种类型。 (A的例子)
我想知道其他人如何处理这个问题?
THX
答案 0 :(得分:5)
你能不能在每个类实现的接口上有一个方法?或者你没有控制界面?
这将提供多态性并避免定义任何外部方法。我相信这是一个接口的意图,它允许客户端以非特定类型的方式处理实现它的所有类。
如果无法添加到界面,那么最好使用适当的方法引入第二个界面。如果您无法编辑接口或类,则需要一个以接口作为参数的方法,然后检查具体类。然而,这应该是最后的手段,而是颠覆界面的使用,并将方法与所有实现联系起来。
答案 1 :(得分:3)
听起来你是在追求这样的事情:
public static void test(MyInterface obj){
if(obj instanceof A) {
A tmp = (A)obj;
} else if(obj instanceof B) {
B tmp = (B)obj;
} else {
//handle error condition
}
}
但请注意,这是非常糟糕的形式,表明您的设计出现了严重错误。如果你没有接口的控制,那么,正如marcj所建议的那样,添加第二个接口可能就好了。请注意,您可以在保持二进制兼容性的同时执行此操作。
答案 2 :(得分:2)
我不清楚你究竟在问什么,但问题是你没有一个采用MyInterface类型参数的方法。我不知道Java中的确切语法是什么,但你可以做一些像if(b是B){test(b as B)}但我不会。如果您需要它是通用的,那么使用MyInterface类型作为变量类型,否则使用B作为变量类型。你打败了使用界面的目的。
答案 3 :(得分:1)
我认为访客design pattern会帮助你。基本的想法是让你的类(A和B)自己调用适当的方法,而不是你试图决定调用哪个方法。作为一名C#人,我希望我的Java能够运作:
public interface Visitable {
void accept(Tester tester)
}
public interface MyInterface implements Visitable {
}
public class A implements MyInterface{
public void accept(Tester tester){
tester.test(this);
}
}
public class B implements MyInterface{
public void accept(Tester tester){
tester.test(this);
}
}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
a.accept(this);
b.accept(this);
}
public void test(A a){
System.out.println("A");
}
public void test(B b){
System.out.println("B");
}
}
答案 4 :(得分:1)
我不确定我是否完全理解这个问题,但似乎有一种方法可以将test()方法移到子类中:
public interface MyInterface {
public void test();
}
public class A implements MyInterface{
public void test() {
System.out.println("A");
}
}
public class B implements MyInterface{
public void test() {
System.out.println("B");
}
}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
b.test();
}
}
您可以类似地使用toString()方法并打印出结果。但是,如果你的要求不可能,我无法从这个问题中说出来。
答案 5 :(得分:1)
在一个.java文件中只使用一个公共类/接口,否则会抛出错误。并使用对象名称调用对象..您仅在Teater类中声明了两个方法,然后声明类A,B的目的是什么。
答案 6 :(得分:0)
我通常使用抽象类来解决这个问题,如下所示:
public abstract class Parent {}
public class A extends Parent {...}
public class B extends Parent {...}
允许您将Parent对象传递给带有A或B的函数。
答案 7 :(得分:0)
您有3个选项:
visit(Visitor)
,其中Visitor
类包含许多访问每个子类的方法。if-else
中使用test(MyInterface)
进行检查ATester
,BTester
等,所有这些都实现了具有方法ITester
的接口test(MyInterface)
。然后在ATester
中,在执行操作之前检查类型是否等于A.然后,您的主Tester类可以拥有一组这些测试人员,并将每个MyInterface
实例传递到链中,直到它到达可以处理它的ITester
。这基本上是将if-else
块从2转变为单独的类。就个人而言,在大多数情况下我会选择2。 Java缺乏真正的面向对象。处理它!提出各种各样的方法通常只会导致难以理解的代码。
答案 8 :(得分:0)
听起来你需要a)通过在MyInterface上放置方法并在A和B中实现或b)Composite和Visitor设计模式的某种组合来利用多态性。我开始a)并且当事情变得笨拙时前往b)。
我对访客的广泛想法:
答案 9 :(得分:0)
public interface MyInterface {}
public class A implements MyInterface{}
public class B implements MyInterface{}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
test(b); // this is wrong
}
public static void test(A a){
System.out.println("A");
}
public static void test(B b){
System.out.println("B");
}
}
您正在尝试将MyInterface
引用变量引用的对象传递给使用其子类型为test(B b)
的参数定义的方法。编译器在这里抱怨,因为MyInterface
引用变量可以引用任何MyInterface
子类型的对象,但不一定是B
的对象。如果允许,则可能存在运行时错误Java的。举个例子,让你的概念更清晰。我修改了类B
的代码并添加了一个方法。
public class B implements MyInterface {
public void onlyBCanInvokeThis() {}
}
现在只需更改test(B b)
方法,如下所示:
public static void test(B b){
b.onlyBCanInvokeThis();
System.out.println("B");
}
如果编译器允许,此代码将在运行时爆炸:
MyInterface a = new A();
// since a is of type A. invoking onlyBCanInvokeThis()
// inside test() method on a will throw exception.
test(a);
为防止这种情况,编译器不允许使用超类引用的此类方法调用技术。
我不确定你想要实现什么,但似乎你想要实现运行时多态性。为此,您需要在MyInterface
中声明一个方法,并在每个子类中实现它。这样,对方法的调用将在运行时根据对象类型而不是引用类型进行解析。
public interface MyInterface {
public void test();
}
public class A implements MyInterface{
public void test() {
System.out.println("A");
}
}
public class B implements MyInterface{
public void test() {
System.out.println("B");
}
}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
b.test(); // calls B's implementation of test()
}
}