我有一组类,称之为Derived1, Derived2, ..., Derived6
,每个类都是基类Base
的子类。这些类在第三方Java包中定义。
我正在写一个类,它会写出这些对象的人类可读表示。我按如下方式解决了问题:为每个String transform(Derivedi object)
和i=1,2,...,6
定义方法String transform(Base object)
。
例如,当Base obj = new Derived3(...)
和我想要计算obj
的表示时,会出现问题。表达式transform(obj)
调用带有签名String transform(Base)
的方法,该方法必须调用“正确”方法(在这种情况下是具有签名String transform(Derived3)
的方法)。
方法String transform(Base object)
委托通过if (obj instanceof Derivedi)
形式的i=1,2,...,6
形式的条件语句为每个String toReadable()
工作到适当的方法。 (如果我控制了包,我会在基类上有一个抽象方法String transform(Base)
,每个派生类都必须实现;不幸的是在这种情况下我无法控制包。)
我不喜欢这个解决方案(很容易理解为什么)。 ngOnInit(){
if(this._vehicleService.isAuth())
{
this.shownavBar=true;
this._router.navigate('/characters') //how can i get this
}
}
答案 0 :(得分:1)
您可以尝试为每个类提供变换器(包含transform(...)
的对象)。然后维护一个映射,将变换器映射到那些类(假设变换器本身是无状态的)。
示例:
class Transformer {
Class<? extends Base> getTransformableClass() { ... }
String transform( Base obj ){
//check and cast obj to the actual type then create the string
}
}
Map<Class<?>, Transformer> transformers = ...;
Transformer base = new BaseTransformer(); //the same for derived
transformers.put( base.getTransformableClass(), base );
请注意,使用CDI / Reflection可以稍微自动执行查找(即查找实现某个接口的所有类或使用某个注释进行注释)。
然后像这样使用它:
public String transform( Base obj) {
//add null checks etc.
return transformers.get(obj.getClass()).transform(obj);
}
进一步注意,在实现变换器时,泛型可能会有所帮助,但是在地图中使用它们会使一些演员表/原始类型变得必要,因为您不知道从地图中获得的实际类型,即您作为开发人员知道transformers.get( Derived1.class )
应该返回一个能够处理Derived1
个实例的转换器,但是编译器不知道这个,因此需要你处理它并进行适当的转换。
答案 1 :(得分:0)
您可以使用getSimpleName()来获取类的名称,并在名称上使用switch语句。您仍然需要在transform(Base object)
中完成此委派,但是会比几个if语句和instanceof检查更清晰。