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 Κλάσεις ]]| |