Est-il un moyen de garantir une interface étend une classe en Java?
Supposons que j'ai la situation suivante:
public abstract class Vehicle {
public void turnOn() { ... }
}
public interface Flier {
public void fly();
}
Est-il un moyen que je peux garantir que toute classe qui implémente Flier
doit également s'étendre Vehicle
? Je ne veux pas faire Flier
une classe abstraite parce que je veux être en mesure de mélanger un peu d'autres interfaces de la même manière.
Par exemple:
//I also want to guarantee any class that implements Car must also implement Vehicle
public interface Car {
public void honk();
}
//I want the compiler to either give me an error saying
//MySpecialMachine must extend Vehicle, or implicitly make
//it a subclass of Vehicle. Either way, I want it to be
//impossible to implement Car or Flier without also being
//a subclass of Vehicle.
public class MySpecialMachine implements Car, Flier {
public void honk() { ... }
public void fly() { ... }
}
- Les Interfaces d'étendre les Interfaces. (Abstrait) Classes (partiellement) de mettre en œuvre des Interfaces et de l'étendre à d'autres classes.
- Essayez ma suggestion, tu ne peux pas compiler MySpecialMachine sans s'étend de Véhicule!
Vous devez vous connecter pour publier un commentaire.
Interfaces Java ne peut pas étendre des classes, ce qui est logique étant donné que les classes contiennent des détails de mise en œuvre qui ne peut pas être spécifié dans une interface..
La bonne façon de traiter ce problème est de séparer l'interface de l'application complètement en tournant
Vehicle
dans une interface. LeCar
e.t.c. pouvez étendre laVehicle
interface pour forcer le programmeur à mettre en œuvre les méthodes correspondantes. Si vous souhaitez partager du code entre tous lesVehicle
cas, vous pouvez ensuite utiliser (éventuellement abrégé) de la classe en tant que parent de toutes les classes doivent implémenter cette interface.Vehicle
. Tout ce qu'il faudrait faire le tourVehicle
dans une interface et déplacer les détails d'implémentation d'une classe de base abstraite si nécessaire...Vehicle
sera transformée en et interface et son code déménagé dans une autre classe de base, ouVehicle
devra mettre en place une nouvelle interface, permet de direVehicleInterface',
qui sera ensuite prolongée par toutes les autres interfaces. Le résultat final est techniquement la même chose...interface Car extends Vehicle
faire tous lesVehicle
s'étendent souventCar
ainsi?RecyclerView.Adapter
classe à partir d'Android. Je veux définir une interface pour manipuler le RecyclerView mais je veux aussi que le réalisateur de cette interface pour toujours étendreRecyclerView.Adapter
. Je ne pense pas que Java permet de le faire, mais elle le suce.Vous pourriez les réorganiser vos classes et interfaces comme ceci:
De cette façon, toutes les implémentations de
Flier
sont garantis pour mettre en œuvre les protocole d'un véhicule, à savoirIVehicle
.I*
convention doit être utilisé (qui, d'ailleurs, ne semblait jamais tout ce que Java-y pour moi), puis il doit être utilisé pour tous interfaces...I*
convention est principalement un .NET chose. Je l'ai utilisé parce que j'étais dans le besoin des dénominations différentes, mais liées àVehicle
. Nettoyage les noms pour avoir un ensemble cohérent de nommage sera certainement aider.C'est une exigence de l'étrange, mais vous pouvez accomplir quelque chose de la sorte avec les Génériques:
Si vous avez le contrôle sur la
Vehicle
classes il suffit d'extraireVehicle
comme une interface et une implémentation de base.Si vous n'avez aucun contrôle sur
Vehicle
classe, par exemple parce qu'il fait partie d'un framework que vous utilisez ou d'un tiers de la bibliothèque, il n'est pas possible de le faire en Java.La chose la plus proche que vous pouvez faire est de l'utilisation de Génériques de plusieurs caractères génériques notation.
Mais vous ne pouvez pas vraiment l'appliquer directement à la Voiture, sauf si vous faites quelque chose comme cela:
Qui est bot bizarre et ne pas appliquer l'auto fait de méthode de retour de soi, c'est juste une forte pointe/proposition.
Vous pouvez implémenter un
Car
comme ceci:on peut utiliser un
Car<?>
comme ceci:ils doivent être à la fois une syntaxe valide.
Ce que le compilateur appliquer ici, c'est que ce que vous spécifiez dans
Car<WHICH>
QUI doit à la fois d'étendreVehicle
et de mettre en œuvreCar
. Et en ajoutantself()
que vous dites pour le programmeur que leT
objet est censé être l'objet lui-même, forçant ainsi le caractère générique de l'instance pour correspondre à la classe s'il veulent être conformes à la spécification.dans Java 8, vous pouvez même définir une implémentation par défaut pour la méthode d'auto.
Je souhaite aussi qu'il y a une meilleure façon de gérer quelque chose comme ça.
Cette question montre que vous n'avez pas compris l'essence de
interface
etclass
. Oublier le béton de la syntaxe Java droit maintenant, tout ce que vous devez comprendre, c'est que: l'interface est un ensemble de protocole, qui devrait être mise en œuvre agnostique. Il ne fait aucun sens de laisser une interface d'étendre une classe(ce qui est concret de mise en œuvre).Revenir à votre question concrète, si vous voulez vous assurer qu'un
Flier
est toujours une sorte deVehicle
, il suffit de modifier ce dernier à uninterface
et laissez ancien étend(Il est logique d'étendre un protocole de l'autre protocole). Après cela, vous pouvez créer n'importe quel classe(abstraite ou concrète) qui implémenteVehicle
ouFlier
.Vehicle
est une classe (même si elle devrait être une interface).Maintenant: Chaque fois que vous le souhaitez à mettre en œuvre à partir de "Tract" vous devez s'étend de Véhicule !
(parce que le Véhicule peut mettre en œuvre implementMe).
C'est délicat, mais fonctionne très bien.
Submarine
classe au sein de ce nouveau paquet? Ensuite, ils pourraient mettre en œuvreHiddenOne
directement, sans passer parVehicle
...