示例:
RewriteRule ^birthing-records/([^/]+)/?$ birthing-records.php?url=$1 [QSA,NC]
RewriteRule ^birthing-records/([^/]+)/([^/]+)/?$ birthing-records.php?url=$1&second=$2 [L,QSA,NC]
由于我的CityEntity属于AbstractEntity类型,为什么我不能在cityconverter中这样做?
class AbstractConverter <T> {
public abstract T convert(AbstractEntity e);
}
class CityEntity extends AbstractEntity {...}
class CityConverter extends AbstractConverter {
@Override
public CityDTO convert(CityEntity entity) {...} // why can't I do that??
}
我想解决方案就是投射,但它不是优雅的:
The method convert(CityEntity) of type CityConverter must override or implement a supertype method
答案 0 :(得分:3)
您无法减少允许的参数类型,因为您会中断Liskov substitution principle。如果在未知的convert
实施中调用AbstractConverter
(由于多态),他会猜测他总是可以通过任何AbstractEntity
实现。如果CityConverter
仅允许非常特定的子类型,则情况并非如此。
现在关于你的代码:
class AbstractConverter <T> {
public abstract T convert(AbstractEntity e);
}
这里首先让我感到惊讶的是:为什么AbstractEntity
是固定类型?如果我总是想将AbstractEntityConverter
实例转换为不同的实例,我会将转换器类命名为AbstractEntity
或类似的东西。
所以我想你真的想要这样的东西:
class AbstractConverter<F, T> {
public abstract T convert(F source);
}
F
是&#34;来自&#34;作为源的类型,T
是目标类型,将返回。因此,您可以让AbstractConverter
子类型决定他们想要转换的内容。
然后你有这个:
class CityConverter extends AbstractConverter {
}
为什么在这里使用AbstractConverter
作为raw type?不应该吗?
class CityConverter extends AbstractConverter<CityDTO> {
}
但无论如何,如果您想使用我的建议,那么还要添加源类型:
class CityConverter extends AbstractConverter<CityEntity, CityDTO> {
@Override
public CityDTO convert(CityEntity entity) {...}
}
这样可行。
答案 1 :(得分:2)
您的CityConverter extends AbstractConverter
和AbstractConverter<T>
需要实施
public abstract T convert(AbstractEntity e);
extends AbstractConverter
使用原始类型不是问题,因为在返回对象的情况下,重写方法可以更具体(因为它仍然是父类描述的类型)。
但是在派生类中你想要更具体的类型作为参数时会出现问题。
请记住派生类仍然可以在父类型之一的引用中使用,就像它可以有如下代码:
AbstractConverter ac = new CityConverter();
因此,当我们调用ac.convert(...)
时,编译器将允许我们使用任何类型的AbstractEntity
作为参数,而不仅仅CityEntity
可以制作CityConverter#convert
的代码。
这就是为什么我们在覆盖它时不能声明更具体类型的方法参数。
现在关于你的标题问题:
在这种情况下,为什么我需要演员? ......
CityEntity cityEntity = (CityEntity) entity;
您需要进行转换,因为entity
被声明为AbstractEntity
,这意味着传递的实例可能不是CityEntity
类型,因此编译器无法编译代码:
CityEntity cityEntity = entity;//error without cast
通过投射,你基本上是在说#34;我确信传递的实例将是(CityEntity)
类型,如果没有,我愿意面对后果,并准备好看看我的应用程序被ClassCastException和#34停止了;