Statisk og dynamisk binding i Java

1. Introduksjon

Polymorfisme tillater et objekt å ta flere former - når en metode viser polymorfisme, må kompilatoren kartlegge navnet på metoden til den endelige implementeringen.

Hvis det er kartlagt på kompileringstidspunktet, er det en statisk eller tidlig binding.

Hvis det løses ved kjøretid, er det kjent som dynamisk eller sen binding.

2. Forstå gjennom en kode

Når en underklasse utvider en superklasse, kan den implementere metoder som er definert i den på nytt. Dette kalles en metode som overstyrer.

La oss for eksempel lage en superklasse Dyr:

offentlig klasse Animal {static Logger logger = LoggerFactory.getLogger (Animal.class); offentlig tomrom makeNoise () {logger.info ("generisk dyrestøy"); } public void makeNoise (Integer repetitions) {while (repetitions! = 0) {logger.info ("generisk nedtelling av dyrestøy" + repetisjoner); repetisjoner - = 1; }}}

Og en underklasse Hund:

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

På overbelastning av en metode, som lage støy() av Dyr klasse, vil kompilatoren løse metoden og koden på kompileringstidspunktet. Dette er et eksempel på statisk binding.

Men hvis vi tildeler et objekt av typen Hund til en referanse av typen Dyr, vil kompilatoren løse funksjonskodekartleggingen ved kjøretid. Dette er dynamisk binding.

For å forstå hvordan dette fungerer, la oss skrive et lite kodebit for å ringe klassene og metodene:

Dyredyr = nytt Dyr (); // kallemetoder for dyreobjekt animal.makeNoise (); animal.makeNoise (3); // tilordne et hundeobjekt til referanse av typen Animal Animal dogAnimal = new Dog (); dogAnimal.makeNoise (); Resultatet av koden ovenfor vil være:
com.baeldung.binding.Animal - generic animal noise com.baeldung.binding.Animal - generic animal noise countdown 3 com.baeldung.binding.Animal - generic animal noise countdown 2 com.baeldung.binding.Animal - generic animal noise countdown 1 com.baeldung.binding.Dog - woof woof!

La oss nå lage en klasse:

klasse AnimalActivity {public static void eat (Animal animal) {System.out.println ("Animal is eating"); } offentlig statisk tomrom spiser (Hundhund) {System.out.println ("Hunden spiser"); }}

La oss legge til linjen til hovedklassen:

AnimalActivity.eat (dogAnimal);

Resultatet vil være:

com.baeldung.binding.AnimalActivity - Dyr spiser

Dette eksemplet viser at en statisk funksjon gjennomgår statisk binding.

Årsaken er at underklasser ikke kan overstyre statiske metoder. Hvis underklassen implementerte den samme metoden, ville den skjule superklassens metode. Tilsvarende, hvis en metode er endelig eller privat, vil JVM gjøre en statisk binding.

En statisk bundet metode er ikke assosiert med et bestemt objekt, men kalles heller på Type (klasse i Java). Utførelsen av en slik metode er marginalt raskere.

Enhver annen metode er automatisk en virtuell metode i Java som standard. JVM løser slike metoder ved kjøretid, og dette er dynamisk bindende.

Den nøyaktige implementeringen avhenger av JVM, men det vil ta en C ++ - lignende tilnærming, der JVM ser opp det virtuelle bordet for å bestemme hvilket objekt metoden vil kalles.

3. Konklusjon

Binding er en integrert del av et språk som implementerer polymorfisme. Det er viktig å forstå konsekvensene av både statisk og dynamisk binding for å være sikker på at applikasjonene våre oppfører seg slik vi vil ha dem.

Med den forståelsen er vi imidlertid i stand til effektivt å bruke klassearv så vel som metodeoverbelastning.

Som alltid er koden tilgjengelig på GitHub.