* Полиморфизъм
Публикувано на 09 октомври 2009 от Филип Петров. Записано в Java.
Понятието „полиморфизъм“ идва от биологията. То описва „съществуване на морфологично различни индивиди в границите на един вид“ (wikipedia). Това например са пчелите и търтеите в пчелния кошер – те са от един вид, но имат съвсем различни функции. В обектно-ориентираното програмиране под „полиморфизъм“ се разбира същото – различни обекти (индивиди) от един и същи вид (базов клас) извършват различни дейности. Тук се разбира, че индивидите наследяват характерните черти на вида, но променят някои от неговите функционалности.
Досега се запознахме с предефинирането на методи. При тях знаем, че можем да извикваме различни методи с едно и също име. Това се наричаше „предефиниране на метод“:
public class polyexample{
public static void main(String[] args){
ClassExample c = new ClassExample(5);
int imultiplyer = 2;
double dmultiplyer = 2.5;
int x = c.multiply(imultiplyer);
double d = c.multiply(dmultiplyer);
System.out.println("x = "+x+", d = "+d);
}
}
class ClassExample{
public int x;
public ClassExample(){
x = 0;
}
public ClassExample(int x){
this.x = x;
}
public int multiply(int x){
return this.x*x;
}
public double multiply(double x){
return (double)this.x * x;
}
}
В литературата това се среща по-често просто като понятие „предефиниране на метод“ и много автори не го свързват въобще с понятието „полиморфизъм“. Въпреки, че тук нямаме конкретно обект от даден клас и нямаме наследяване, все пак можем да направим доста добра аналогия с понятието полиморфизъм. Ако приемем, че „методът“ е „вид“, а „извикването на метод с аргументи“ е „индивид“, то имаме типичното свойство на полиморфизма – различните индивиди действат по различен начин. Затова ще си позволим да въведем понятието „статичен полиморфизъм“ като синоним на „предефиниране на метод“. Също така можем да го приемем и за полиморфизъм в процедурното програмиране.
Динамичен полиморфизъм се получава тогава, когато предефинираме методи на базов клас в негов наследник. Казваме също, че по този начин променяме съществуващата реализация на метод с нова. Ето един пример – създаваме наследник и предефинираме метод print():
public class polyexample{
public static void main(String[] args){
ClassExample c = new ClassExample(5);
c.print();
SubClassExample c2 = new SubClassExample(5);
c2.print();
}
}
class ClassExample{
public int x;
public ClassExample(){
x = 0;
}
public ClassExample(int x){
this.x = x;
}
public void print(){
System.out.println(this.x);
}
}
class SubClassExample extends ClassExample{
public int y;
public SubClassExample(){
super();
y = 0;
}
public SubClassExample(int x){
super(x);
y = 0;
}
public void print(){
System.out.println(this.x+" "+this.y);
}
}
Динамично свързване на метод е третият, най-пълен тип полиморфизъм. Това е свойството на метод да върши различни неща в зависимост от обекта с който работи. Динамичното свързване на метод всъщност се свързва и с общото понятие „полиморфизъм“ в обектно-ориентираното програмиране. В известен смисъл то „надгражда“ динамичния полиморфизъм. Ето един класически пример:
public class polyexample{
public static void main(String[] args){
Animal a;
Dog kuche = new Dog("Sharo");
Cat kotka = new Cat("Pisana");
a = kuche;
a.speak();
a = kotka;
a.speak();
}
}
abstract class Animal{
public String name;
public Animal(String name){
this.name = name;
}
abstract void speak();
}
class Dog extends Animal{
public Dog(String name){
super(name);
}
public void speak(){
System.out.println("Бау, бау!");
}
}
class Cat extends Animal{
public Cat(String name){
super(name);
}
public void speak(){
System.out.println("Мяу!");
}
}
Виждате, че всеки път извиквахме метод „speak()“ чрез променливата „a“, която е от абстрактен тип „Animal“. По време на компилация не се знае точно кой метод „speak()“ ще бъде извикан – поради тази причина се казва, че имаме „динамично свързване на метод“ по време на изпълнение. Това е и пълното разбиране за понятието „полиморфизъм в обектно-ориентираното програмиране“.
Тук е мястото да вмъкнем аналогията с програмирането на C++ където имаше понятие „виртуални функции„, тоест такива, които могат да бъдат предефинирани. В Java всички методи са виртуални и могат да бъдат предефинирани. В C++ наричахме такова предефиниране като „полиморфизъм по време на изпълнение“ или както го дефинирахме тук – динамично свързване на метод.
Trackback URI | RSS за коментарите
Пусни коментар
Страници
Категории
- C/C++ (45)
- DB (36)
- Dogs (51)
- Food (8)
- History (9)
- Java (33)
- Lada (45)
- Math (104)
- Metodos (35)
- NetSec (36)
- Other (79)
- Politics (32)
- Probability (13)
- VC++.Net (1)
- XHTML/JS (25)
Нови
- Малко снимки от лятото…
- ASCII Лада Нива
- Анимация и обучение чрез забавление
- Активизиране на студентите по време на лекции
- Проблемно-ситуационно обучение