| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| java:polymorphism [2017/03/03 13:51] – [Δυναμικός Πολυμορφισμός] gthanos | java:polymorphism [2020/03/27 13:18] (current) – [Δυναμικός Πολυμορφισμός] gthanos |
|---|
| ====== Στατικός και Δυναμικός Πολυμορφισμός ====== | ====== Στατικός και Δυναμικός Πολυμορφισμός ====== |
| |
| ===== Στατικός Πολυμορφισμός ===== | ===== Στατικός Πολυμορφισμός (a.k.a. Υπερφόρτωση Μεθόδων) ===== |
| |
| Κατά την εισαγωγή [[java:class_methods#Υπερφόρτωση (overloading) των μεθόδων μίας κλάσης | στις μεθόδους της κλάσης]] είδαμε την δυνατότητα ορισμού σε μία κλάση μεθόδων με το ίδιο όνομα αλλά με διαφορετικό αριθμό ή/και τύπους παραμέτρων. Η δυνατότητα αυτή που μας δίνει η Java και ο Αντικειμενοστραφής Προγραμματισμός γενικότερα, ονομάζεται //method overloading// και οφείλεται στο γεγονός ότι μία μέθοδος δεν ορίζεται μόνο από το όνομα της αλλά και από το σύνολο των τυπικών παραμέτρων της. Τυπικές παράμετροι και όνομα αποτελούν την //υπογραφή// (signature) της κάθε μεθόδου. | Κατά την εισαγωγή [[java:class_methods#Υπερφόρτωση (overloading) των μεθόδων μίας κλάσης | στις μεθόδους της κλάσης]] είδαμε την δυνατότητα ορισμού σε μία κλάση μεθόδων με το ίδιο όνομα αλλά με διαφορετικό αριθμό ή/και τύπους παραμέτρων. Η δυνατότητα αυτή που μας δίνει η Java και ο Αντικειμενοστραφής Προγραμματισμός γενικότερα, ονομάζεται //method overloading// και οφείλεται στο γεγονός ότι μία μέθοδος δεν ορίζεται μόνο από το όνομα της αλλά και από το σύνολο των τυπικών παραμέτρων της. Τυπικές παράμετροι και όνομα αποτελούν την //υπογραφή// (signature) της κάθε μεθόδου. |
| Ας υποθέσουμε δύο κλάσεις που η μία κληρονομεί από την άλλη και οι δύο έχουν δύο διακριτές μεθόδους με το ίδιο όνομα και τις ίδιες τυπικές παραμέτρους, δηλαδή το ίδιο //signature//. Σε αυτή την περίπτωση λέμε ότι η μέθοδος της υποκλάσης, επανα-ορίζει (//overrides//) την μέθοδο της γονικής της κλάσης. Ένα παράδειγμα είναι το παρακάτω. | Ας υποθέσουμε δύο κλάσεις που η μία κληρονομεί από την άλλη και οι δύο έχουν δύο διακριτές μεθόδους με το ίδιο όνομα και τις ίδιες τυπικές παραμέτρους, δηλαδή το ίδιο //signature//. Σε αυτή την περίπτωση λέμε ότι η μέθοδος της υποκλάσης, επανα-ορίζει (//overrides//) την μέθοδο της γονικής της κλάσης. Ένα παράδειγμα είναι το παρακάτω. |
| |
| <code java TestDog.java> | <code java Polymorphism.java> |
| class Animal { | class Animal { |
| public void signature(){ | |
| System.out.println("I am an animal."); | public void signature(){ |
| } | System.out.println("I am an animal."); |
| | } |
| } | } |
| |
| class Mammal extends Animal { | class Mammal extends Animal { |
| public void signature() { | int numberOfBabies; |
| System.out.println("I am a mammal!"); | |
| } | public Mammal(int babies) { |
| | numberOfBabies = babies; |
| | } |
| | |
| | public int getBabies() { |
| | return numberOfBabies; |
| | } |
| | |
| | public void signature() { |
| | System.out.println("I am a mammal! I birth "+numberOfBabies+" babies."); |
| | } |
| } | } |
| |
| class Dog extends Mammal { | class Dog extends Mammal { |
| | private String name; |
| public void signature() { | |
| System.out.println("I am a dog!"); | public Dog(int babies, String name) { |
| } | super(babies); |
| | this.name = name; |
| | } |
| | |
| | public String getName() { |
| | return name; |
| | } |
| | |
| | public void signature() { |
| | System.out.println("I am a dog! My name is "+name+"."); |
| | } |
| } | } |
| |
| public class TestDog { | public class Polymorphism { |
| |
| public static void main(String args[]) { | public static void main(String args[]) { |
| Animal a = new Animal(); // Animal reference and object | Animal animal = new Animal(); // Animal reference and object |
| Animal b = new Mammal(); // Animal reference but Mammal object | Animal mammal = new Mammal(3); // Animal reference but Mammal object |
| Animal c = new Dog(); // Animal reference but Dog object | Animal dog = new Dog(4, "Azor"); // Animal reference but Dog object |
| |
| a.signature(); //output: I am an animal. | animal.signature(); //output: I am an animal. |
| b.signature(); //output: I am a mammal! | mammal.signature(); //output: I am a mammal! |
| c.signature(); //output: I am a dog! | dog.signature(); //output: I am a dog! |
| } | |
| | //mammal.getBabies(); |
| | //dog.getName(); |
| | } |
| } | } |
| </code> | </code> |
| Στο παραπάνω παράδειγμα, το JVM γνωρίζει το είδος του αντικειμένου στο οποίο δείχνουν οι μεταβλητές ''a'', ''b'' και ''c'' ανεξάρτητα εάν η reference μεταβλητή είναι του τύπου της γονικής κλάσης ή της υποκλάσης. Η παραπάνω διάκριση είναι γνωστή ως δυναμικός πολυμορφισμός (//dynamic polymorphism//), διότι το ποια μέθοδος θα κληθεί αποφασίζεται κατά την εκτέλεση και όχι κατά την μεταγλώττιση. | Στο παραπάνω παράδειγμα, το JVM γνωρίζει το είδος του αντικειμένου στο οποίο δείχνουν οι μεταβλητές ''a'', ''b'' και ''c'' ανεξάρτητα εάν η reference μεταβλητή είναι του τύπου της γονικής κλάσης ή της υποκλάσης. Η παραπάνω διάκριση είναι γνωστή ως δυναμικός πολυμορφισμός (//dynamic polymorphism//), διότι το ποια μέθοδος θα κληθεί αποφασίζεται κατά την εκτέλεση και όχι κατά την μεταγλώττιση. |
| |
| |Προηγούμενο: [[ :java:super_operator | Ο τελεστής super ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[ :java:hiding_static_methods | Καλώντας στατικές μεθόδους από την γονική κλάση και την υποκλάση ]]| | |Προηγούμενο: [[ :java:super_operator | Ο τελεστής super ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[ :java:abstract_classes | Abstract Κλάσεις ]]| |