我有一个域类,它有很多子类,如下所示(B 是接口(interface)类型,B1 和 B2)实现 B 接口(interface)。
正如您在我的主类中看到的那样,它需要转换 (B1 b1 = (B1) a.getB();) 并且我们知道它可以是 B1 或 B2,所以据我所知应该没问题。
我遇到的问题是类型可以增长很多,使用 A 的人需要设置更多条件来检查 B 的实例并访问 B1 或 B2 的特定值......有什么方法可以跳过此转换,以便将来可以减少很多条件
public class TestMain
{
public static void main(String[] args)
{
A a = new A();
//this can be B1 or B2
B1 b1 = (B1) a.getB();
}
}
public class A
{
private B b;
protected B getB()
{
return b;
}
protected void setB(B b)
{
this.b = b;
}
}
public interface B
{
void test();
}
public class B1 implements B
{
@Override
public void test()
{
// TODO Auto-generated method stub
}
}
public class B2 implements B
{
@Override
public void test()
{
// TODO Auto-generated method stub
}
}
最佳答案
假设您确实需要此功能(Eran 上面的评论提出了一个很好的观点;多态性可能会满足您的大部分或全部需求),答案是泛型。它们是一个稍微高级的主题,但它们是 Java 的核心(JDK 中的所有集合类都使用它们),因此学习它们非常重要。
泛型是一种表达“某种类型”和可选的“某种类型是其他类型的子类型”的方式。后者是您想要的。
public class A<T extends B>
{
private T b;
protected T getB()
{
return b;
}
protected void setB(T b)
{
this.b = b;
}
}
<T extends B>
部分声明了 T
的通用参数, 并说它必须是 B
的子类.从那时起,您可以使用 T
好像它是 A
中的一种类型类(class)。对于此类的用户,他们必须指定哪种类型的 A
是的,编译器会自动为你做向下转型:
A<B1> a = new A<B1>();
a.set(new B1());
B1 b = a.getB();
请注意,在第二行中,如果您完成了 a.set(new B2())
这将是一个编译时错误:编译器会提示 a
参数化为 B1
, 因此你不能传递 B2
给它。在非常高的层次上,您可以想象编译器正在执行搜索和替换,替换 T
在原始类中有 B1
.如果你声明:
A<B2> a = new A<B2>();
然后搜索和替换将类似地变成 T
进入B2
.
实际上,由于称为删除的东西,事情并没有那么简单。您可以在 Java trail on generics 阅读更多内容。 ,还有许多其他可用资源。 This PDF是一个很好的中级描述。
关于java - 需要设计建议以跳过对象类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18670318/