Skip to content

Commit 16815d5

Browse files
authored
Static and dynamic binding (#179)
1 parent 2c3017d commit 16815d5

1 file changed

Lines changed: 44 additions & 3 deletions

File tree

‎oop.md‎

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,52 @@ class Car {
410410
[к оглавлению](#ООП)
411411

412412
## Что такое _статическое_ и _динамическое связывание_?
413-
Присоединение вызова метода к телу метода называется связыванием. Если связывание проводится компилятором (компоновщиком) перед запуском программы, то оно называется _статическим_ или _ранним связыванием (early binding)_.
414413

415-
В свою очередь, _позднее связывание (late binding)_ это связывание, проводимое непосредственно во время выполнения программы, в зависимости от типа объекта. Позднее связывание также называют _динамическим (dynamic)_ или _связыванием на стадии выполнения (runtime binding)_. В языках, реализующих позднее связывание, должен существовать механизм определения фактического типа объекта во время работы программы, для вызова подходящего метода. Иначе говоря, компилятор не знает тип объекта, но механизм вызова методов определяет его и вызывает соответствующее тело метода. Механизм позднего связывания зависит от конкретного языка, но нетрудно предположить, что для его реализации в объекты должна включаться какая-то дополнительная информация.
414+
_Связывание (binding)_ - это сопоставление вызванного метода с конкретной реализацией (участком памяти), которая будет исполнена.
416415

417-
Для всех методов Java используется механизм позднего (динамического) связывания, если только метод не был объявлен как `final`, `static` или `private` (приватные методы являются `final` по умолчанию).
416+
_Early binding (static/compile-time)_ - связывание происходит на этапе компиляции. Компилятор может точно определить, какой метод вызвать по типу переменной, т.е. по типу ссылки на объект. Используется в следующих случаях:
417+
418+
- вызов `static`, `private` или `final` метода
419+
- вызов переопределенного (overloaded) метода
420+
- обращение к полю объекта
421+
422+
```java
423+
class Animal {
424+
static void staticMethod() { System.out.println("Animal static"); }
425+
private void privateMethod() { System.out.println("Animal private"); }
426+
final void finalMethod() { System.out.println("Animal final"); }
427+
void say(int a) { System.out.println("Animal says " + a); }
428+
void say(String s) { System.out.println("Animal says " + s); }
429+
}
430+
431+
class Dog extends Animal {
432+
static void staticMethod() { System.out.println("Dog static"); }
433+
}
434+
435+
Animal a = new Dog();
436+
a.staticMethod(); // "Animal static"
437+
a.say("hello"); // "Animal says hello" - compiler chose the implementation
438+
```
439+
440+
_Late binding (dynamic/runtime)_ - связывание происходит во время выполнения программы по типу объекта, а не по типу ссылки. Данный вид связывания используется при вызове переопределенных (overridden) методов. Late binding обеспечивает полиморфизм.
441+
442+
```java
443+
class Animal {
444+
void sound() { System.out.println("Some sound"); }
445+
}
446+
447+
class Dog extends Animal {
448+
@Override
449+
void sound() { System.out.println("Woof"); }
450+
}
451+
452+
Animal a = new Dog();
453+
a.sound(); // "Woof"
454+
```
455+
456+
Вызов методов при late binding происходит через vtable (virtual method table). _vtable_ - это таблица указателей на реализации методов, которую JVM создает для каждого класса на этапе компиляции. Обращение происходит по индексу к таблице класса объекта, на котором был вызван метод.
457+
458+
Важно: vtable не является частью спецификации JVM, это конкретная реализация динамической диспетчеризации (dynamic dispatch) в большинстве JVM.
418459

419460
[к оглавлению](#ООП)
420461

0 commit comments

Comments
 (0)