Statická a dynamická väzba v Jave

1. Úvod

Polymorfizmus umožňuje objektu mať viac podôb - keď metóda vykazuje polymorfizmus, musí kompilátor namapovať názov metódy na konečnú implementáciu.

Ak je mapované v čase kompilácie, je to statická alebo skorá väzba.

Ak sa to vyrieši za behu, je to známe ako dynamická alebo neskorá väzba.

2. Porozumenie prostredníctvom kódexu

Keď podtrieda rozširuje nadtriedu, môže znovu implementovať metódy definované v nej. Toto sa nazýva prepísanie metódy.

Vytvorme napríklad nadtriedu Zviera:

verejná trieda Animal {static Logger logger = LoggerFactory.getLogger (Animal.class); public void makeNoise () {logger.info ("všeobecný hluk zvierat"); } public void makeNoise (celočíselné opakovania) {while (opakovania! = 0) {logger.info ("odpočítavanie generického hluku zvierat" + opakovania); opakovania - = 1; }}}

A podtrieda pes:

public class Dog extends Animal {static Logger logger = LoggerFactory.getLogger (Dog.class); @Override public void makeNoise () {logger.info ("haf haf!"); }}

Pri preťažení metódy, ako je Robit hluk() z Zviera triedy, kompilátor vyrieši metódu a jej kód v čase kompilácie. Toto je príklad statického viazania.

Ak však priradíme objekt typu pes na referenciu typu Zviera, kompilátor vyrieši mapovanie funkčného kódu za behu programu. Toto je dynamická väzba.

Aby sme pochopili, ako to funguje, napíšme malý útržok kódu, ktorý zavolá triedy a ich metódy:

Zvieracie zviera = nové zviera (); // volanie metód zvieracieho objektu animal.makeNoise (); animal.makeNoise (3); // priradenie objektu psa k referencii typu Zviera Zviera pesAnimal = new Dog (); dogAnimal.makeNoise (); Výstup z vyššie uvedeného kódu bude:
com.baeldung.binding.Animal - generický hluk zvierat com.baeldung.binding.Animal - odpočítavanie generického hluku zvierat 3 com.baeldung.binding.Animal - odpočítavanie generického hluku zvierat 2 com.baeldung.binding.Animal - odpočítavanie generického zvuku zvierat 1 com.baeldung.binding.Dog - haf haf!

Teraz vytvorme triedu:

trieda AnimalActivity {public static void eat (Zvieracie zviera) {System.out.println ("Zviera žerie"); } public static void eat (Pes pes) {System.out.println ("Pes je jedlo"); }}

Pridajme tieto riadky do hlavnej triedy:

AnimalActivity.eat (dogAnimal);

Výstup by bol:

com.baeldung.binding.AnimalActivity - Zviera žerie

Tento príklad ukazuje, že statická funkcia prechádza statickou väzbou.

Dôvod je ten, že podtriedy nemôžu prepísať statické metódy. Ak by podtrieda implementovala rovnakú metódu, skryla by metódu nadtriedy. Podobne, ak je metóda konečná alebo súkromná, JVM urobí statickú väzbu.

Metóda statického viazania nie je spojená s konkrétnym objektom, ale je skôr vyvolaná Typ (trieda v Jave). Vykonanie takejto metódy je o niečo rýchlejšie.

Akákoľvek iná metóda je v predvolenom nastavení automaticky virtuálnou metódou v prostredí Java. JVM takéto metódy rieši za behu a toto je dynamické viazanie.

Presná implementácia závisí od JVM, ale vyžadoval by prístup podobný C ++, kde JVM vyhľadá virtuálnu tabuľku a rozhodne, ktorý objekt bude metódu volať.

3. Záver

Väzba je neoddeliteľnou súčasťou jazyka, ktorý implementuje polymorfizmus, je dôležité pochopiť dôsledky statickej aj dynamickej väzby, aby ste sa uistili, že sa naše aplikácie správajú tak, ako chceme.

S týmto pochopením však dokážeme efektívne využiť dedičnosť tried aj preťaženie metód.

Ako vždy, kód je k dispozícii na GitHub.