J'ai le code suivant dans lequel j'ai une classe parent et son enfant. J'essaie de déterminer comment le code tire profit du polymorphisme.
class FlyingMachines {
public void fly() {
System.out.println("No implementation");
}
}
class Jet extends FlyingMachines {
public void fly() {
System.out.println("Start, Taxi, Fly");
}
public void bombardment() {
System.out.println("Throw Missile");
}
}
public class PolymorphicTest {
public static void main(String[] args) {
FlyingMachines flm = new Jet();
flm.fly();
Jet j = new Jet();
j.bombardment();
j.fly();
}
}
Quel est l'avantage du polymorphisme lorsque flm.fly()
et j.fly()
me donnent la même réponse?
regardons OO la conception d’abord, l’héritage représente une relation IS-A, en général, nous pouvons dire quelque chose comme "laissons notre FlyingMachines
voler". chaque FlyingMachines
(sous-classe) spécifique IS-A FlyingMachines
(classe mère), disons Jet
, correspond à ce "laissons notre FlyingMachines
voler", alors que nous voulons que ce vol soit réellement la fonction de vol du spécifique (sous-classe), c'est du polymorphisme prendre le contrôle.
nous faisons donc les choses de manière abstraite, avec des interfaces orientées et une classe de base, ne dépendons pas réellement de la mise en œuvre des détails, le polymorphisme fera le bon choix!
Dans votre exemple, l’utilisation du polymorphisme n’est pas extrêmement utile car vous n’avez qu’une sous-classe de FlyingMachine
. Le polymorphisme devient utile si vous avez plusieurs types de FlyingMachine
. Ensuite, vous pourriez avoir une méthode qui accepte tout type de FlyingMachine
et utilise sa méthode fly()
. Un exemple pourrait être testMaxAltitude(FlyingMachine)
.
Une autre fonctionnalité disponible uniquement avec le polymorphisme est la possibilité d'utiliser un List<FlyingMachine>
et de l'utiliser pour stocker Jet
, Kite
ou VerySmallPebbles
.
L'un des meilleurs cas d'utilisation du polymorphisme est la possibilité de faire référence à des interfaces plutôt qu'à des implémentations.
Par exemple, il est préférable d'avoir une méthode qui renvoie List<FlyingMachine>
plutôt que ArrayList<FlyingMachine>
. De cette façon, je peux changer mon implémentation dans la méthode en une variable LinkedList
ou une variable Stack
sans détruire le code qui utilise ma méthode.
La raison pour laquelle vous utilisez le polymorphisme est lorsque vous construisez des frameworks génériques qui prennent tout un tas d'objets différents avec la même interface . Lorsque vous créez un nouveau type d'objet, vous n'avez pas besoin de modifier le cadre pour l'adapter au nouveau type d'objet, tant qu'il suit les "règles" de l'objet.
Ainsi, dans votre cas, un exemple plus utile consiste à créer un type d'objet "Airport" qui accepte différents types de FlyingMachines. L’aéroport définira une fonction "AllowPlaneToLand", semblable à:
//pseudocode
void AllowPlaneToLand(FlyingMachine fm)
{
fm.LandPlane();
}
Tant que chaque type de FlyingMachine définit une méthode LandPlane appropriée, il peut se poser correctement. L’aéroport n’a besoin de rien savoir sur la FlyingMachine, sauf que pour atterrir, il doit faire appel à LandPlane sur la FlyingMachine. Ainsi, l'aéroport n'a plus besoin de changer et peut continuer à accepter de nouveaux types de FlyingMachines, qu'il s'agisse d'un handglider, d'un ovni, d'un parachute, etc.
Le polymorphisme est donc utile pour les frameworks construits autour de ces objets, qui peuvent généralement accéder à ces méthodes sans avoir à changer.
Quel est l’avantage du polymorphisme lorsque
flm.fly()
etj.fly()
donne moi la même réponse?
L'avantage est que
FlyingMachines flm = new Jet();
flm.fly();
résultats
"Start, Taxi, Fly"
au lieu de
"No implementation"
C'est du polymorphisme. Vous appelez fly()
sur un objet de type FlyingMachine
et il sait toujours qu'il s'agit en fait d'une Jet
et appelle la méthode fly()
appropriée au lieu de la méthode incorrecte générant "No implementation"
.
Cela signifie que vous pouvez écrire des méthodes qui fonctionnent avec des objets de type FlyingMachine
et les alimenter avec toutes sortes de sous-types tels que Jet
ou Helicopter
et ces méthodes feront toujours ce qui est bien, c’est-à-dire en appelant la méthode fly()
du type approprié au lieu de toujours le faire. chose, ie sortie "No implementation".
Le polymorphisme n'est pas utile dans votre exemple.
a) Cela devient utile lorsque vous avez différents types d'objets et que vous pouvez écrire des classes pouvant fonctionner avec tous ces types différents, car elles adhèrent toutes à la même API.
b) Cela devient également utile lorsque vous pouvez ajouter de nouvelles FlyingMachine
s à votre application sans modifier la logique existante.
a) et b) sont les deux faces d'une même pièce.
Laisse moi montrer comment.
import Java.util.ArrayList;
import Java.util.List;
import static Java.lang.System.out;
public class PolymorphismDemo {
public static void main(String[] args) {
List<FlyingMachine> machines = new ArrayList<FlyingMachine>();
machines.add(new FlyingMachine());
machines.add(new Jet());
machines.add(new Helicopter());
machines.add(new Jet());
new MakeThingsFly().letTheMachinesFly(machines);
}
}
class MakeThingsFly {
public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
for (FlyingMachine flyingMachine : flyingMachines) {
flyingMachine.fly();
}
}
}
class FlyingMachine {
public void fly() {
out.println("No implementation");
}
}
class Jet extends FlyingMachine {
@Override
public void fly() {
out.println("Start, taxi, fly");
}
public void bombardment() {
out.println("Fire missile");
}
}
class Helicopter extends FlyingMachine {
@Override
public void fly() {
out.println("Start vertically, hover, fly");
}
}
a) La classe MakeThingsFly
peut fonctionner avec tout ce qui est de type FlyingMachine
.
b) La méthode letTheMachinesFly
fonctionne également sans changement (!) lorsque vous ajoutez une nouvelle classe, par exemple PropellerPlane
:
public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
for (FlyingMachine flyingMachine : flyingMachines) {
flyingMachine.fly();
}
}
}
C'est le pouvoir du polymorphisme. Vous pouvez implémenter le open-closed-principe avec.
Cela n'ajoute pas grand chose si vous n'utilisez que des Jets, l'avantage viendra lorsque vous utiliserez différents FlyingMachines, par exemple. Avion
Maintenant que vous avez modifié pour inclure plus de classes, l'avantage du polymorphisme réside dans le fait que le type spécifique (et le concept d'entreprise) de l'instance que vous recevez est abstraction.
flm.fly()
et j.fly()
vous donnent la même réponse car le type de l'instance est en fait le même, c'est-à-dire Jet
, de sorte qu'ils se comportent de la même manière.
Vous pouvez voir la différence lorsque vous:
FlyingMachines flm = new FlyingMachines();
flm.fly();
Jet j = new Jet();
j.bombarment();
j.fly();
Le polymorphisme est défini comme la même signature de méthode avec un comportement différent. Comme vous pouvez le constater, FlyingMachines
et Jet
ont tous deux la méthode fly()
définie, mais la méthode est implémentée différemment, ce qui permet de se comporter différemment.
Voir Aa
Le polymorphisme (à la fois à l'exécution et à la compilation) est nécessaire en Java pour de nombreuses raisons.
La méthode est prioritaire sur un polymorphisme d'exécution et la surcharge sur un polymorphisme à la compilation.
Peu d'entre eux sont (certains d'entre eux sont déjà discutés):
Collections: supposons que vous disposiez de plusieurs types de machines volantes et que vous souhaitiez les avoir tous dans une même collection. Vous pouvez simplement définir une liste de type FlyingMachines
et les ajouter tous.
List<FlyingMachine> fmList = new ArrayList<>();
fmList.add(new new JetPlaneExtendingFlyingMachine());
fmList.add(new PassengerPlanePlaneExtendingFlyingMachine());
Ce qui précède ne peut être fait que par polymorphisme. Sinon, vous devrez maintenir deux listes distinctes.
Caste d'un type à un autre: Déclarez les objets comme:
FlyingMachine fm1 = new JetPlaneExtendingFlyingMachine();
FlyingMachine fm2 = new PassengerPlanePlaneExtendingFlyingMachine();
fm1 = fm2; //can be done
Surcharge: Pas lié au code que vous avez donné, mais la surcharge est aussi un autre type de polymorphisme appelé compile time polymorphism.
Peut avoir une seule méthode qui accepte le type FlyingMachine
et gère tous les types, c'est-à-dire les sous-classes de FlyingMachine. Ne peut être atteint qu'avec Polymorphism
.
Le polymorphisme peut également aider notre code à supprimer le "si" conditionnel destiné à produire un code de niveau de production, car le fait de supprimer des conditionnels augmentera la lisibilité du code et nous aidera à écrire de meilleurs scénarios de tests unitaires. ! (n factorielle) possibilités.
Voyons comment
si vous avez la classe FlyingMachine et qui prend une chaîne dans le constructeur définissant le type de FlyMachine comme ci-dessous
class FlyingMachine{
private type;
public FlyingMachine(String type){
this.type = type;
}
public int getFlyingSpeedInMph {
if(type.equals("Jet"))
return 600;
if(type.equals("AirPlane"))
return 300;
}
}
Nous pouvons créer deux instances de FlyingMachine en tant que
FlyingMachine jet = new FlyingMachine("Jet");
FlyingMachine airPlane = new FlyingMachine("AirPlane");
et obtenir les vitesses en utilisant
jet.fylingSpeedInMph();
airPlane.flyingSpeedInMph();
Mais si vous utilisez le polymorphisme, vous allez supprimer les conditions if en étendant la classe FlyMachine générique et en surchargeant getFlyingSpeedInMph comme ci-dessous.
class interface FlyingMachine {
public int abstract getFlyingSpeedInMph;
}
class Jet extends FlyingMachine {
@Override
public int getFlyingSpeedInMph(){
return 600;
}
}
class Airplane extends FlyingMachine {
@Override
public int getFlyingSpeedInMph(){
return 600;
}
}
Maintenant, vous pouvez obtenir les vitesses de vol ci-dessous
FlyingMachine jet = new Jet();
jet.flyingSpeed();
FlyingMachine airPlane = new AirPlane();
airPlane.flyingSpeed();
Le polymorphisme ne vous procure des avantages que si vous avez besoin de polymorphisme. Il est utilisé lorsqu'une entité de votre projet conceptuel peut être considérée comme la spécialisation d'une autre entité. L'idée principale est "spécialisation". Un grand exemple se trouve dans la taxonomie dite, appliquée par exemple aux êtres vivants. Les chiens et les humains sont tous deux des mammifères. Cela signifie que la classe Mammals regroupe toutes les entités ayant certaines propriétés et certains comportements en commun.
En outre, une ElectricCar et une DieselCar sont une spécialisation d'une voiture. Donc, les deux ont un isThereFuel (), car lorsque vous conduisez une voiture, vous vous attendez à savoir s’il ya suffisamment de carburant pour la conduire. Un autre grand concept est "attente".
C'est toujours une bonne idée de dessiner un diagramme ER (entité-relation) du domaine de votre logiciel avant de le démarrer. C'est parce que vous êtes obligé d'imaginer le type d'entités qui vont être créées et, si vous en avez la capacité, vous pouvez économiser beaucoup de code pour trouver des comportements communs entre entités. Mais la sauvegarde du code n'est pas le seul avantage d'un bon projet.
Vous voudrez peut-être découvrir ce que l’on appelle le "génie logiciel", c’est un ensemble de techniques et de concepts vous permettant d’écrire du "code propre" (il existe également un excellent livre intitulé "Code propre" largement suggéré par les programmes). .
Ici, pour ce code particulier, il n’ya pas besoin de polymorphisme.
Comprenons pourquoi et quand nous avons besoin de polymorphisme.
Supposons qu'il existe différents types de machines (comme une voiture, un scooter, une machine à laver, un moteur électrique, etc.) et que nous savons que chaque machine démarre et s'arrête. Mais la logique pour démarrer et arrêter une machine est différente pour chaque machine. Ici, chaque machine aura différentes implémentations à démarrer et à arrêter. Donc, pour fournir différentes implémentations, nous avons besoin de polymorphisme.
Ici, nous pouvons avoir une machine de classe de base avec start()
et stop()
comme méthodes et chaque type de machine peut étendre cette fonctionnalité et @Override
ces méthodes.
Ajoutons encore une classe dans ceci, cela vous aidera à comprendre l'utilisation du polymorphisme ..
class FlyingMachines {
public void fly() {
System.out.println("No implementation");
}
}
class Jet extends FlyingMachines {
public void fly() {
System.out.println("Start, Jet, Fly");
}
}
class FighterPlan extends FlyingMachines {
public void fly() {
System.out.println("Start, Fighter, Fight");
}
}
public class PolymorphicTest {
public static void main(String[] args) {
FlyingMachines flm = new Jet();
flm.fly();
FlyingMachines flm2 = new FighterPlan();
flm2.fly();
}
}
Sortie:
Start, Jet, Fly
Start, Fighter, Fight
le polymorphisme comme énoncé clairement par lui-même, un qui a cartographié pour beaucoup.
Java est un langage oops donc il doit être implémenté de manière abstraite, surchargée et surchargée.
rappelez-vous que Java n'aurait pas de spécification pour le polymorphisme à l'exécution.
il y a aussi quelques exemples de meilleur exemple.
public abstract class Human {
public abstract String getGender();
}
class Male extends Human
{
@Override
public String getGender() {
return "male";
}
}
class Female extends Human
{
@Override
public String getGender() {
return "female";
}
}
Priorité
redéfinir le comportement de la classe de base . par exemple, je veux ajouter un compte de vitesse dans la fonctionnalité existante de déplacement dans ma voiture de base.
Surcharge
peut avoir un comportement avec le même nom avec une signature différente . Par exemple, un président particulier parle clairement fort mais un autre parle seulement fort.
Le polymorphisme est nécessaire en Java parce que le concept est largement utilisé pour la mise en oeuvre de l'héritage. Il joue un rôle important en permettant aux objets ayant différentes structures internes de partager la même interface externe.