Il semble que je ne comprenne pas très bien deux OOP concepts. Pouvez-vous expliquer ce que abstraction et polymorphisme sont, de préférence avec des exemples réels et du code?
Je vous remercie.
Imaginez une classe de fraction:
class fraction:
int denominator
int numerator
Maintenant, deux objets de cela:
fraction(obj1): denominator=-1 numerator=-1
fraction(obj2): denominator=1 numerator=1
Les deux objets ont la valeur 1: (1/1) == (-1)/(-1)
. Vous ne vous attendriez pas à ce qu'ils se comportent différemment de l'extérieur. C'est de l'abstraction. Vous résumez les données que votre objet contient dans une vue logique, même en coulisse, il y a autre chose. Théoriquement, vous avez une relation d'équivalence, avec différents groupes d'équivalence:
[1]=(1, 1), (-1, -1), (5, 5), ...
[2]=(2, 4), (-2, -4), ...
...
Et il existe une fonction d'abstraction qui abstrait les détails internes vers l'extérieur:
f((1, 1)) = [1]
f((-1, -1)) = [1]
Il mappe des valeurs concrete aux valeurs abstraites d'un objet. Vous faites cela en écrivant par exemple un mappage de constructeur (-1, -1) sur (1, 1) et en écrivant une fonction equals pour votre classe.
Imaginez un stylo et deux classes dérivées:
class pen:
void draw(int x, int y)
class pen_thin extends pen:
void draw(int x, int y) { color(x, y) = green; }
class pen_thick extends pen:
void draw(int x, int y) { color(x, y) = green;
color(x, y+1) = green; }
and two objects:
pen_thin(p1)
pen_thick(p2)
Les deux stylos peuvent dessiner. votre "stylo" général ne peut pas se dessiner. C'est juste une interface pour pen_thin, pen_thick et beaucoup d'autres stylos. Vous dites: obj1.draw (1, 0); et si obj1 est un stylo épais ou fin n'a pas d'importance pour vous en tant qu'utilisateur, ni pour le compilateur au moment de la compilation. L'appel se comporte polymorphe. C'est polymorphisme dynamique (se produit au moment de l'exécution) et c'est ce que les gens veulent dire. Polymorphisme statique se produit lors de la compilation:
class colorizer:
void colorize(shirt s)
void colorize(pants p)
Cela s'appelle une surcharge. Vous appelez obj.colorize(something)
. Si vous appelez cela avec une référence de chemise, la version prenant une chemise sera appelée. Et si vous appelez cela avec une référence de pantalon, il appellera la version pantalon. Le choix effectué ici est au moment de la compilation .
Ces deux sont parmi les caractéristiques les plus importantes du paradigme orienté objet.
L'orientation des objets modélise le logiciel en tant qu'objets du monde réel. Cependant, il serait trop difficile (et inutile) de modéliser TOUTES les propriétés d’un client ou toutes les propriétés d’un employé.
En listant uniquement les attributs intéressants d'un objet, OO peut utiliser efficacement cet objet pour un domaine spécifique. C'est de l'abstraction.
Par exemple, un employé d'un système RH peut avoir des attributs très différents d'un librairie en ligne. Nous résumons les détails à faire est utile.
Les objets peuvent se comporter différemment selon le "type" tout en conservant la même interface.
Que cela veut-il dire?
Par exemple, un système de boutique en ligne peut avoir deux sous-classes d’employés.
A) Employés internes.
B) les entrepreneurs
Et une méthode pour calculer la remise pour les achats internes
La réduction d'un employé interne est calculée comme suit: 10% + 2% pour chaque année travaillée dans l'entreprise + 2% pour chaque enfant .. mmhh
La remise d'un entrepreneur est de 10%
Le code suivant pour calculer le montant à payer:
public Amount getAmountToPay( Product product, Employee internalCustomer ) {
Amount amount = product.getPrice();
amount.applyDiscount( internalCustomer.getDiscount() );
return amount;
}
Produirait des résultats différents pour les deux types différents d’employés.
class Employee {
public int getDiscount();
}
class InternalEmployee extends Employee {
public int getDiscount() {
return 10 + 2 * getWorkedYears() + 2 * getNumberOfChilds();
}
}
class Contractor extends Employee {
public int getDiscount() {
return 10;
}
}
C'est le polymorphisme en action. Au lieu d'avoir quelque chose comme
Amount amount = product.getPrice();
if( employee.isContractor() ) {
amount.applyDiscount( 10 );
} else if( employee.isSomthingElse() ) {
amount.applyDiscount( 10 * 2 * getYrs() + 2 * getChilds() );
} else if ( employee.contidions, condigions, conditions ) {
amount.applyDiscount( getSomeStrageRuleHere() );
}
Nous laissons le moteur d'exécution choisir lequel calculer. Est-ce que le programme se comporte différemment selon le type:
Amount amount = product.getPrice();
amount.applyDiscount( internalCustomer.getDiscount() );
return amount;
A propos, dans cet exemple, le "montant" est une abstraction d'un concept de la vie réelle, qui pourrait également être représenté par un double ou un entier, mais peut-être que nous aurons des méthodes d'interestion qui seraient meilleures si elles étaient définies dans leur propre classe.
J'espère que ça aide.
L'abstraction et le polymorphisme sont des concepts critiques nullement limités à OO. Ajoutant à la confusion, le mot "abstraction" est utilisé de plusieurs manières. Voici un aide-mémoire rapide avec un exemple:
Abstraction de données signifie dissimulation d’informations . Ce qui est généralement caché est la représentation d'une structure de données. Exemple: j'implémente des ensembles, mais je ne vous dis pas si un ensemble est représenté sous forme de liste, d'arborescence binaire équilibrée ou d'arborescence binaire non équilibrée. Fait bien, Je peux changer de représentation sans casser votre code .
Polymorphisme signifie réutilisation avec différents types . Donc, avec mon exemple, vous pouvez créer des ensembles de numéros de sécurité sociale, des ensembles de noms complets ou des ensembles de crevettes, le tout en utilisant le même code.
Vous pouvez évidemment définir une classe à la fois abstraite et polymorphe.
Le polymorphisme est encore plus déroutant car il existe deux manières de mettre en œuvre le polymorphisme . Dans polymorphism paramétrique , vous pouvez réutiliser le jeu avec les valeurs de any type, ou peut être n'importe quel type satisfaisant une contrainte. Les exemples les plus évidents sont modèles C++ ; si vous écrivez
class Set <T> { ... }
Alors T
est le type des objets contenus dans l’ensemble (la notation <T>
indique ce qu’on appelle un "paramètre de type", c’est-à-dire ce qui le rend parametric polymorphism).
Dans polymorphisme de sous-type , vous ne pouvez réutiliser des ensembles qu'avec des objets dont les types sont des sous-types d'un type particulier. Par exemple, vous pourrez peut-être créer des ensembles uniquement d'objets proposant une méthode inférieure ou égale à. Dans un vrai langage orienté objet comme Smalltalk ou Ruby, qui propose ce que l'on appelle duck typing (les théoriciens pointy appellent parfois cela sous-typage comportemental ), la présence de la méthode est suffisante . Dans un langage tel que Java ou C++, où fusionne le sous-type avec l'héritage , votre utilisation du polymorphisme peut être limitée aux sous-classes d'une classe particulière . (Java complique encore le problème en utilisant une forme de sous-typage sur les classes et une autre sur les interfaces.)
Enfin, les vieux pets comme moi parlent de abstraction procédurale , ce qui signifie simplement être capable de prendre un tas d’énoncés qui sont fréquemment utilisés ensemble et de les insérer dans une procédure ou une méthode que vous pourrez ensuite réutiliser. Ce n'est probablement pas lié à votre question.
Alors, vous sentez-vous mieux d'être confus?
L'abstraction fait référence à l'acte de représenter des caractéristiques essentielles sans inclure les détails ou les explications de l'arrière-plan. Les classes utilisent le concept d'abstraction et sont définies comme une liste d'attributs abstraits.
Un exemple d'abstraction logicielle est la méthode Object.equals(Object o)
de Java. Vous savez qu'il comparera cet objet à celui transmis en tant que paramètre, mais vous ne savez pas, vous n'avez pas besoin de savoir exactement comment il sera implémenté (à moins que vous ne soyez l'implémenteur de la classe).
Polymorphisme signifie la capacité de prendre plus d’une forme. Une méthode peut avoir différents comportements dans différentes instances. Le comportement dépend des types de données utilisés dans l'opération.
L'un des exemples classiques de polymorphisme utilise un arbre d'héritage basé sur la classe Animal. Tous les animaux ont une méthode makeNoise()
, mais les classes Dog et Cat l'implémentent différemment. Cela vous permet de faire référence à n'importe quel chien ou chat utilisant un type de référence Animal.
Animal a = new Dog();
Animal b = new Cat();
Maintenant, vous pouvez appeler makeNoise()
sur l'une ou l'autre instance Animal et savoir qu'elle fera le bruit approprié. Ceci est particulièrement utile si vous avez une collection d'animaux et que vous ne savez pas au moment de l'exécution quel type correspond à chacun d'eux.
Les deux termes sont fortement utilisés dans la programmation orientée objet, mais ils ne sont pas spécifiquement limités à ce contexte.
L'abstraction est une généralisation de quelque chose d'autre; un pas de plus en perspective. Une hiérarchie, par exemple, peut être vue comme une abstraction de la structure organisationnelle d’une entreprise. Généralement, il est utilisé dans le contexte des éléments situés en dessous (tels que leurs types de base). L'abrégé consiste à écrire moins de code de nature plus générale, de manière à pouvoir l'exécuter pour un plus grand ensemble de problèmes. Une feuille de calcul, par exemple, est une abstraction qui permet un type spécifique de stockage d'informations. Plus?
Le polymorphisme est aussi une généralisation, mais qui se produit dans un contexte d'exécution. Un tas de types d'objets différents sont polymorphes s'il existe un moyen d'y accéder où ils ne peuvent pas être distingués les uns des autres. Autrement dit, tous les objets ont la même apparence et la même sensation, même s'ils ne le sont pas. Le but de ceci est de réduire considérablement le code; vous pouvez écrire une solution généralisée pour éviter d'écrire toutes les permutations différentes pour chaque type différent. Si vous écrivez une bibliothèque graphique, vous préférez écrire du code abstrait pour gérer les «formes», puis écrire du code pour chaque type différent, tel que des cercles, des carrés, etc.
Ce sont deux termes centrés autour des propriétés du code qui permettront aux programmeurs de faire plus avec moins. Moins de code contient moins de bogues, est plus stable et plus facile à gérer. L’alternative consiste à utiliser la "force brute" pour extraire des millions et des millions de lignes de code très spécifique (et très fragile). Plus de code est difficile à corriger, et beaucoup plus difficile à maintenir à jour.
Paul.
réponse courte: l'abstraction est conceptuelle , le polymorphisme est comportemental
L'abstraction et le polymorphisme sont de nature similaire avec un but différent.
Par ex.
Un permis de conduire : vous recevez un permis mentionnant la catégorie de véhicules que vous êtes autorisé à conduire. La licence mentionne la classe de véhicule autorisée par l’autorité mais elle ne définit ni ne mentionne la voiture ou la marque spécifique que vous devez conduire. C'est l'abstraction.
here Licence est une Classe abstraite et sa méthode, les véhicules autorisés est sa Méthode abstraite .
Or, ici, le polymorphisme est une façon différente dont une licence est attribuée par une autorité à des personnes différentes, certaines sont délivrées pour des véhicules légers, d'autres pour des véhicules lourds et d'autres pour des véhicules utilitaires, selon des exigences différentes. Ici, Licence est une classe de base , et d'autres types de licences sont ses classes enfants, obéissant également à la relation est-une relation . Licence commerciale est une licence.
Ainsi, l’abstraction est une directive générale donnant l’indépendance d’implémentation aux classes suivantes, tandis que Polymorphism est une approche différentielle qui outrepasse les méthodes/règles définies par la classe parente.
P.S: a récemment commencé à apprendre Java La réponse est basée sur mon observation, corrigez-moi si je me trompe.
L'abstraction et le polymorphisme au fond font presque le même travail en programmation.
prenons une voiture par exemple ..
que ce soit une mini-fourgonnette Ford, une Ferrari exotique, un SUV Land-Rover ou une berline BMW, ils suivent tous le modèle de base d'une voiture, à savoir un moteur, un volant, une boîte de vitesses, des phares, des indicateurs et la liste continue. Ce qui les différencie, c’est que leurs implémentations spécifiques sont telles que Ferrari pourrait avoir un moteur plus puissant qu’un mini-fourgonnette, un suv pourrait avoir une boîte de vitesses différente d’où une voiture (la Superclasse ici) a été mise en oeuvre par sous-classes suv, mini-van, exotic) Il s’agit de polymorphisme , idée de base héritée ou implémentée en ajoutant une autre spécification. un véhicule à 4 roues (superclasse) mis en œuvre sous différentes formes (sous-classes)
Maintenant, Abstraction , par définition, il s’agit de cacher les détails et de faire voir à l’utilisateur ce qui lui est demandé.
Prenons à nouveau l’exemple de la voiture. Vous utilisez des engins, mais vous ne connaissez pas exactement le mécanisme de fonctionnement de ces engins. Ils changent de vitesse, etc.
Passons maintenant au codage de la partie.
Les classes abstraites sont des classes incomplètes et pour qu'une classe soit abstraite, comme son nom l'indique, une méthode incomplète doit être complétée par la sous-classe héritant de la super-classe. S'ils ne terminent pas la méthode abstraite, ils resteront également incomplets. .
abstract class car {
abstract void gear();
}
class sedan extends car {
public void gear()
{
//complete the method
}
}
de plus, vous ne pouvez pas créer d'objets de classes abstraites car la classe n'est pas complète. Pourtant, ces classes abstraites peuvent avoir des méthodes statiques, des arguments, des méthodes concrètes MAIS pour qu’elles soient abstraites, elles ont besoin d’une méthode abstraite. Donc, une superclasse abstraite de base est implémentée dans d’autres sous-classes où elle est complétée En examinant la déclaration de méthode, nous pouvons estimer ce que fait exactement la méthode, ce qu’elle va renvoyer. Mais nous ne savons pas exactement comment la méthode abstraite sera implémentée.
En utilisant des classes abstraites ou des interfaces, nous pouvons obtenir une abstraction en Java. Comme nous savons tous que les classes abstraites, les interfaces contiennent des méthodes abstraites.
Nous pouvons seulement estimer leur fonctionnement. Nous apprenons comment ils fonctionnent une fois que nous avons fourni l'implémentation de la méthode dans les classes qui implémentent la classe abstraite ou l'interface correspondante.
HENCE, abstrait aide donc fondamentalement le polymorphisme.
En termes simples, l'abstraction est conceptuelle et Poly est comportementale. Pour obtenir une abstraction en POO, vous avez besoin de Poly.
L'abstraction dans la programmation orientée objet est un concept ou un modèle de conception qui, dit-on, permet une meilleure isolation, couplant de manière lâche ainsi la testabilité, la réutilisabilité et l'extensibilité. Pour tout atteindre, nous avons besoin de poly, héritage/extension et etc.