想象一下,我有一个抽象类动物的方法:
public abstract void fetch(Animal ani);
然后我有一个类,用以下内容扩展这个抽象类:
public class GoldenRetriever extends Animal {
public void fetch(GoldenRetriever pup) {
pup.paws = "I have paws";
}
}
我希望每个扩展Animal的类都有一个fetch()方法。然而,fetch方法为相关动物指定了一些独特的特征(狗的爪子、猫的爪子等)。例如,cat的fetch()将获取参数fetch(fellinecat kitty)并表示:
public void fetch(FelineCat kitty) { kitty.claws = "I have claws."; }
因此,抓取方法接受了扩展抽象类“动物”(因此是动物)的参数。我在“动物”中定义了抓取()方法,以接受任何类型“动物”的参数。对我来说,这是有意义的,因为猫和狗都是动物,但是Java说黄金寻回器未能覆盖抽象方法抓取(动物)。这是为什么?
重写另一个方法的方法必须具有完全相同的参数,否则它被称为重载。您的抓取
方法必须这样声明:
public void fetch(Animal ani)
该方法不会重写,因为参数类型不同。您必须这样声明方法:
public class GoldenRetriever extends Animal {
public void fetch(Animal pup) {
也就是说,参数类型仍然必须是动物
,即使您正在编写一个扩展动物
的类。
这是有充分理由的。假设你有其他方法
public void someMethod(Animal x)
您可以传递任何动物
作为参数,包括一个GoldenRetriever
:
GoldenRetriever gr = ...;
someMethod(gr);
假设在someMethod中,您有这样一个:
public void someMethod(Animal x) {
FelineCat kitty;
...
x.fetch(FelineCat);
由于Animal
的fetch
方法可以接受任何Animal
,编译器认为进行此调用必须是可以的,因为FelineCat
是Animal
。它无法知道x
实际上是GoldenRetriever
。如果它允许重写方法采用GoldenRetriever
参数,则会出现问题,因为该参数实际上是FelineCat
,而不是GoldenRetriever
。那么当多态地调用fetch
时,参数类型是错误的,那又怎样呢?
编译器没有办法阻止这一点,因为它没有办法知道x
的类型是什么。理论上,Java可以允许重写更改参数类型,并在运行时进行检查(如果它试图获取GoldenRetriever
来获取其他类型的动物
,可能会抛出ClassCastExctive
)。我不知道他们为什么没有,但我确信有很好的理由不这样做。
但您可以自己进行运行时检查:
public class GoldenRetriever extends Animal {
public void fetch(Animal pup) {
if (pup instanceof GoldenRetriever) {
GoldenRetriever puppy = (GoldenRetriever)pup;
// now puppy is viewed as a GoldenRetriever, and any methods or
// instance variables particular to GoldenRetrievers can be accessed
} else {
throw new WrongSpeciesException("..."); // or whatever
}
}
}
更新:以上答案假设方法签名是您真正想要的。但在Mixone的评论之后,可能是您没有试图设置涉及两种动物的操作,在这种情况下,您根本不应该拥有该参数。像这样的方法
public void fetch(GoldenRetriever pup)
假设你有一个GoldenRetriever
将与另一个GoldenRetriever
一起做某事,而你只是不想让一个GoldenRetriever
与其他种类的动物一起做。在这种情况下,我认为运行时检查是最好的方法。但如果你想要一个只对一只动物有效的手术,那你就写错了。
不确定我是否100%正确地理解了你的问题,但我想我有办法解决你的问题。下面的代码可以工作,但可能不是最优的,因为您必须始终使用泛型参数,但至少键入是正确的。
public abstract class Animal<T extends Animal> {
public abstract void fetch(T ani);
}
public class GoldenRetriever extends Animal<GoldenRetriever> {
@Override
public void fetch(GoldenRetriever ani) {
}
}
我有一个关于JPA中继承的问题,是否可以使用JOINED策略来实现这个层次结构? 这是我的代码: 在上面的层次结构之后,我尝试使用JPQL进行查询,这是查询: 此代码从主代码运行 当我运行该查询时,会抛出以下错误 导致原因:com . MySQL . JDBC . exceptions . JDBC 4 . MySQL syntaxerrorexception:未知列“employee1_。“字段
继承一个可以实现的普通超类有什么不同吗? atm我有一个名为的抽象类,我有/扩展这个。 abstractcar中的一个字段设置为"私有int容量" 但是在子类“小型汽车”中,当我输入“容量”作为构造函数中使用的变量时,它说“容量在抽象汽车中有私有访问” 我想: > 子类继承超类的所有字段和方法? 我现在该怎么进行?
我有一个抽象类,这个类是在她的子类中扩展的: < li >我在这个抽象类上实现了一个方法,并抽象了另一个方法 < li >实现的方法是每个子类对象都必须访问的通用方法。所以我决定在抽象类上实现它,避免在每个子类上实现相同的方法。 小例子: 我想听听你对这种实施方式的看法, 问候。
所以,问题是:我有一个抽象基类(),它有一个抽象成员方法()。方法返回布尔值,并应检查是否相等,但“相等”在子类中可能有不同的解释,因此我不重写或。因为它测试是否与另一个与其类型相同的对象相等,所以签名如下所示: 现在,当我试图在类中重写它时,假设“”,我不能使用作为参数的类型。我知道一般情况下这样做的原因和添加类型界限的建议,但是事情变得更加复杂,因为参数类型是它自己的类。 有没有什么平滑的方法
我有2个抽象的类操纵泛型和一个工厂与泛型。父级独立于trips对象和因式分解代码。儿子只基于trips。 Eclipse上的AbstractTripBasedPurchaseExtractor第9行出现错误:Bound mismatch:类型TRIP_PURCHASE不是bounded参数的有效替代品 类型的 此处:extends AbstractPurchaseExtractor“ 在son类上
问题是: 我有一个叫做Schema的基类,它是抽象的,它是一个未生成的类。我有两个从Schema继承生成的JAXB类:FixedWidthSchema和DelimitedSchema。 我使用外部绑定(xjb)文件来指定XSD和Java类之间的映射。 在基类模式中,我定义了几个方法: 公共架构静态创建(Model m),它从提供的模型创建架构。 公共抽象Writer marshal(),它将当前架