Question

J'ai une classe abstraite qui a une méthode générique et je veux remplacer la méthode générique en remplaçant les types de spécifiques pour le paramètre générique. Donc, en pseudo-code, je donne les résultats suivants:

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
  }
}

Mais pour une raison que je ne suis pas autorisé à le faire? Est-ce que je fais une sorte d'erreur de syntaxe ou est ce genre d'héritage et en remplaçant pas le droit? Plus précisément, je reçois une erreur au sujet @Override parce que l'IDE Eclipse ne cesse de me rappeler de mettre en œuvre getAndParse.

Voici comment je veux que le code ci-dessus au travail. Ailleurs dans mon code il y a une méthode qui attend des instances d'objets qui mettent en œuvre GetAndParse qui spécifiquement signifie qu'ils ont une méthode de getAndParse que je peux utiliser. Quand j'appelle getAndParse sur cette instance le compilateur vérifie pour voir si j'ai utilisé des instances spécifiques de T de la bonne façon, donc en particulier T devrait étendre AnotherClass et il devrait être SpecificClass.

Était-ce utile?

La solution

Ce que nous avons ici est deux méthodes différentes avec des paramètres de type individuels chacun.

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

Ceci est une méthode avec un paramètre de type nommé T, et délimitée par AnotherClass, qui signifie que chaque sous-type de AnotherClass est autorisée en tant que paramètre de type.

public <SpecificClass> void getAndParse(Args... args)

Ceci est un procédé avec un type paramètre SpecificClass nommé, délimitée par Object (ce qui signifie chaque type est autorisée en tant que paramètre de type). Voulez-vous vraiment?

Le paramètre de type utilisé à l'intérieur Args? Je pense que le problème serait là.


Le sens de

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

est que l'appelant de la méthode peut décider avec quel type paramètre qu'il veut appeler la méthode, aussi longtemps que cela est une sous-type de AnotherClass. Cela signifie que l'effet du procédé peut être appelé avec un objet de type AnotherClass.

Depuis l'appelant peut décider du type de paramètre, vous ne pouvez pas dans une sous-classe affinez le type de paramètre à SpecificClass -. Ce ne serait pas une mise en œuvre de la méthode, mais une autre méthode avec le même nom (surcharge)

Peut-être que vous voulez quelque chose comme ceci:

public abstract class GetAndParse<T extends AnotherClass> {
  public SomeClass var;

  public abstract void getAndParse(T... args);
}

public class Implementor extends GetAndParse<SpecificClass> {
  // some field declarations

  // some method declarations

  @Override
  public void getAndParse(SpecificClass... args) {
    // method body making use of args
  }
}

Maintenant la méthode de getAndParse implémente la méthode classe parente.

Autres conseils

Vous voyez ce problème en raison du concept appelé « Erasure » en Java Generics. Java utilise « l'effacement » pour soutenir la compatibilité ascendante. i.e. code Java qui n'a pas utilisé les médicaments génériques.

Erasure Procédure: Le compilateur va d'abord faire une vérification de type et il va supprimer (effacer) tout autant que possible, les paramètres de type et aussi insérer typecasting où jamais nécessaire.

exemple:

public abstract <T extends AnotherClass> void getAndParse(T paramAnotherClass);

deviendra

public abstract void getAndParse(AnotherClass paramAnotherClass);

Dans la classe "Implementor.java",

Le code

public <SpecificClass> void getAndParse(T paramAnotherClass)

deviendra

public void getAndParse(SpecificClass paramAnotherClass){  }

le compilateur verra que vous ne l'avez pas correctement mis en œuvre la méthode abstraite. Il y a une incompatibilité de type entre la méthode abstraite et la méthode mise en œuvre. Voilà pourquoi vous voyez l'erreur.

Plus de détails peuvent être trouvés ici. http://today.java.net/pub/a /today/2003/12/02/explorations.html

Non, ce n'est pas valide. Que se passerait-il si quelqu'un avec une référence GetAndParse appelée avec un autre class extension AnotherClass?

Cela devient un non-sens quand quelqu'un a une référence au type GetAndParse et tente d'appeler la méthode getAndParse. Si étendre chien et chat AnotherClass. Je pense pouvoir appeler GetAndParse # getAndParse soit avec un chat ou un chien. Mais la mise en œuvre a essayé de limiter et de le rendre moins compatible!

Vous ne pouvez pas override à T de type spécifique, car il est en fait (au niveau de bytecode si vous le souhaitez) qu'une seule méthode getAndParse en raison de l'effacement de type (voir autre réponse):

public abstract void getAndParse(AnotherClass... args); // (1)

Pour chaque type de T, la même méthode est utilisée.

Vous pouvez surcharge (je pense):

public void getAndParse(SpecificClass... args); // (2)

mais ce ne sera pas une méthode différente de (1) ant il pas être appelé par code générique:

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

Static method can't override

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..");
}}

Private method can't override

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();
}}

Final method can't override

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..");
}}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top