Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java泛型方法继承和重写规则_Java_Inheritance_Overriding_Abstract Class_Generic Method - Fatal编程技术网

Java泛型方法继承和重写规则

Java泛型方法继承和重写规则,java,inheritance,overriding,abstract-class,generic-method,Java,Inheritance,Overriding,Abstract Class,Generic Method,我有一个抽象类,它有一个泛型方法,我想通过用泛型参数替换特定类型来重写泛型方法。因此,在伪代码中,我有以下内容: public abstract class GetAndParse { public SomeClass var; public abstract <T extends AnotherClass> void getAndParse(T... args); } public class Implementor extends GetAndParse { //

我有一个抽象类,它有一个泛型方法,我想通过用泛型参数替换特定类型来重写泛型方法。因此,在伪代码中,我有以下内容:

public abstract class GetAndParse {
  public SomeClass var;

  public abstract <T extends AnotherClass> void getAndParse(T... args);
}

public class Implementor extends GetAndParse {
  // some field declarations

  // some method declarations

  @Override
  public <SpecificClass> void getAndParse(SpecificClass... args) {
    // method body making use of args
  }
}
公共抽象类GetAndParse{
公共类变量;
公共抽象void getAndParse(T…args);
}
公共类实现器扩展了GetAndParse{
//一些字段声明
//一些方法声明
@凌驾
公共void getAndParse(SpecificClass…参数){
//使用args的方法体
}
}
但出于某种原因我不能这么做?我是否犯了某种语法错误,或者这种继承和重写是不允许的?具体地说,我得到了一个关于
@Override
的错误,因为eclipse IDE不断提醒我实现
getAndParse


下面是我希望上面代码的工作方式。在我的代码中的其他地方,有一个方法需要实现
GetAndParse
的对象实例,这特别意味着它们有一个
GetAndParse
方法可以使用。当我在该实例上调用
getAndParse
时,编译器会检查我是否以正确的方式使用了
T
的特定实例,因此特别是
T
应该扩展
另一个类
,它应该是
SpecificClass
否,它无效。如果具有
GetAndParse
引用的人使用扩展另一个类的另一个类调用它,会发生什么情况

当有人引用GetAndParse类型并试图调用GetAndParse方法时,这就变得毫无意义了。如果猫和狗扩展到另一个类。我应该可以用猫或狗来调用GetAndParse#GetAndParse。但是实现试图限制它,使其不那么兼容

您看到这个问题是因为Java泛型中的“擦除”概念。 Java使用“擦除”来支持向后兼容性。i、 不使用泛型的Java代码

擦除过程:
编译器将首先进行类型检查,然后尽可能删除(擦除)所有类型参数,并在必要时插入类型转换

例如:

public abstract <T extends AnotherClass> void getAndParse(T paramAnotherClass);
在类“Implementor.java”中

代码

public <SpecificClass> void getAndParse(T paramAnotherClass)
编译器将发现您没有正确实现抽象方法。 抽象方法和实现方法之间存在类型不匹配。这就是您看到错误的原因

更多细节可以在这里找到。
我们这里有两个不同的方法,每个方法都有各自的类型参数

public abstract <T extends AnotherClass> void getAndParse(Args... args);
这是一个方法,其类型参数名为
SpecificClass
,以
对象
为边界(这意味着每个类型都可以作为类型参数)。你真的想要这个吗

类型参数是否在
Args
中使用?我想问题就在那里


意义

public abstract <T extends AnotherClass> void getAndParse(T... args);
现在,
getAndParse
方法实现了父类的方法。

您不能覆盖到特定的类型T,因为实际上(如果您愿意,在字节码级别)只有一个方法
getAndParse
,因为类型擦除(参见其他答案):

对于每种类型的T,使用相同的方法

你可以超载(我认为):

但这与(1)ant的方法没有区别,它不会被泛型代码调用:

T x = whatever;
object.getAndParse(x); // Calls (1) even if T is derived from SpecificClass

静态方法无法覆盖

class Vehicle{
static void park(int location){
    System.out.println("Vehicle parking..");
}}

class Car extends  Vehicle{
@Override //error
void park(int location) { //error
    System.out.println("Car Parking..");
}}
class Vehicle{
private void park(int location){
    System.out.println("Vehicle parking..");
}
void callPark(){
    park(100);
}}

class Car extends  Vehicle{
//@Override
void park(int location) {
    System.out.println("Car Parking..");
}}

class Demo {
public static void main(String[] args) {
    Vehicle v1=new Car();
   v1.callPark();
}}
class Vehicle{
final void park(int location){
    System.out.println("Vehicle parking..");
}}

class Car extends  Vehicle{
//@Override
void park(int location) { //error
    System.out.println("Car Parking..");
}}
私有方法无法覆盖

class Vehicle{
static void park(int location){
    System.out.println("Vehicle parking..");
}}

class Car extends  Vehicle{
@Override //error
void park(int location) { //error
    System.out.println("Car Parking..");
}}
class Vehicle{
private void park(int location){
    System.out.println("Vehicle parking..");
}
void callPark(){
    park(100);
}}

class Car extends  Vehicle{
//@Override
void park(int location) {
    System.out.println("Car Parking..");
}}

class Demo {
public static void main(String[] args) {
    Vehicle v1=new Car();
   v1.callPark();
}}
class Vehicle{
final void park(int location){
    System.out.println("Vehicle parking..");
}}

class Car extends  Vehicle{
//@Override
void park(int location) { //error
    System.out.println("Car Parking..");
}}
最终方法无法覆盖

class Vehicle{
static void park(int location){
    System.out.println("Vehicle parking..");
}}

class Car extends  Vehicle{
@Override //error
void park(int location) { //error
    System.out.println("Car Parking..");
}}
class Vehicle{
private void park(int location){
    System.out.println("Vehicle parking..");
}
void callPark(){
    park(100);
}}

class Car extends  Vehicle{
//@Override
void park(int location) {
    System.out.println("Car Parking..");
}}

class Demo {
public static void main(String[] args) {
    Vehicle v1=new Car();
   v1.callPark();
}}
class Vehicle{
final void park(int location){
    System.out.println("Vehicle parking..");
}}

class Car extends  Vehicle{
//@Override
void park(int location) { //error
    System.out.println("Car Parking..");
}}

伪代码太抽象,需要更多信息使用
公共抽象void getAndParse(Args…Args)毫无意义。类型参数的用途是什么?编译器应该如何确定它的实际值以及应该在哪里使用它?你能给我们一个完整的例子,它实际上是可编译的(除了有问题的错误),并产生你提到的错误吗?@maaartinus:你是对的,我已经更改了方法以特定地使用泛型类型。我不明白为什么这是一个问题。我有一个扩展
GetAndParse
的实现程序,它将
T
的类型修复为
SpecficClass
,编译器会检查该类型以确保扩展
另一个类
,然后在我的代码中,当我有
implementor
的实例时,调用类型不匹配的
GetAndParse
SpecificClass
我应该会得到一个错误。@davidk01:GetAndParse提供的契约说,对于扩展另一个类的任何类型,实现它的每个人都必须这样做。给定
GetAndParse foo=new Implementor()
您必须能够为另一个类的任何扩展调用
foo.getAndParse
——如果编译器没有强制执行此操作,您也可以使用Object,泛型的要点是确保编译时类型安全I不需要类型参数。我希望编译器检查并确保
SpecificClass
是另一个类的扩展。这就是您不想做的原因,如果我以您不喜欢的方式构建它,我向您道歉。编译时泛型无法为您强制执行。编译器如何知道在运行时会有什么子类?完全有可能实现者是由工厂接口返回的,并且来自您甚至没有编译的另一个库!在编译时无法检查类型参数的缩小是否安全。您的答案的意思是否更具描述性?我猜你列出了覆盖不起作用的方式。但是你能介绍一下为什么这和这个问题有关吗?请把你的答案写得更好。