Java связать два объекта

Различия между ранним и поздним связыванием в Java

Java-университет

Чтобы выяснить, в чем состоит различие между ранним (статическим) и поздним (динамическим) связыванием в Java, нужно сначала понять, что такое это самое связывание. Связывание означает наличие связи между ссылкой и кодом. Например, переменная, на которую вы ссылаетесь, привязана к коду, в котором она определена. Аналогично, вызываемый метод привязан к месту в коде, где он определен.

Различия между ранним и поздним связыванием в Java - 1

Существует два типа связывания методов в языке Java: ранее связывание (его ещё называют статическим) и позднее (соответственно, динамическое) связывание. Вызов метода в Java означает, что этот метод привязывается к конкретному коду или в момент компиляции, или во время выполнения, при запуске программы и создании объектов. Можно понять из названия, статическое связывание носит более статический характер, так как происходит во время компиляции, то есть код «знает», какой метод вызывать после компиляции исходного кода на Java в файлы классов. А поскольку это относится к ранней стадии жизненного цикла программы, то называется также ранним связыванием (early binding). С другой стороны, динамическое связывание происходит во время выполнения, после запуска программы виртуальной машиной Java. В этом случае то, какой метод вызвать, определяется конкретным объектом, так что в момент компиляции информация недоступна, ведь объекты создаются во время выполнения. А поскольку это происходит на поздней стадии жизненного цикла программы, то называется в языке Java поздним связыванием (late binding).

Читайте также:  Css element selector list

Давайте рассмотрим еще несколько отличий, чтобы лучше разобраться с этим, а, кроме того, мочь ответить на этот очень популярный вопрос, который задают на собеседованиях по Java.

Раннее и позднее связывание в Java

Существует множество различий статического и динамического связывания в языке Java, но важнейшее – то, как их использует JVM. Задумывались ли вы когда-нибудь, каким образом JVM решает, какой метод вызвать, если в области видимости содержится более одного метода с одним именем? Если вы когда-либо использовали перегрузку или переопределение методов, то знаете, что в Java может быть несколько методов с одним именем. В случае с Java виртуальная машина JVM использует как статическое, так и динамическое связывание для выбора нужного метода.

Пример статического и динамического связывания в Java

В этой программе вы увидите, что привязка виртуальных методов не происходит во время компиляции при помощи статического связывания, поскольку в этом случае вызывался бы метод из суперкласса, как происходит со статическими методами, которые связываются рано. Если будет вызван метод из подкласса, то для связывания функции использовался конкретный объект во время выполнения, а, следовательно, для связывания виртуальных функций используется динамическое связывание.

 public class Main < public static void main(String[] args) < // Пример статического и динамического связывания в Java Insurance current = new CarInsurance(); // Динамическое связывание на основе объекта int premium = current.premium(); // Статическое связывание на основе класса String category = current.category(); System.out.println("premium : " + premium); System.out.println("category : " + category); >> class Insurance < public static final int LOW = 100; public int premium()< return LOW; >public static String category() < return "Insurance"; >> class CarInsurance extends Insurance < public static final int HIGH = 200; public int premium()< return HIGH; >public static String category() < return "Car Insurance"; >> Результаты выполнения: premium : 200 category : Insurance 

Как вы видите, вызов метода premium() привел к выполнению метода из подкласса, в то время как вызов метода category() привел к выполнению метода суперкласса. Это происходит из-за того, что premium() – виртуальный метод, который разрешается при помощи позднего связывания, в то время как category() – статический метод, который разрешается при помощи статического связывания во время компиляции по имени класса.

Читайте также:  Html div margin collapse

Различия между ранним и поздним связыванием в языке Java

  1. Статическое связывание происходит во время компиляции, а динамическое – во время выполнения.
  2. Поскольку статическое связывание происходит на ранней стадии жизненного цикла программы, его называют ранним связыванием. Аналогично, динамическое связывание называют также поздним связыванием, поскольку оно происходит позже, во время работы программы.
  3. Статическое связывание используется в языке Java для разрешения перегруженных методов, в то время как динамическое связывание используется в языке Java для разрешения переопределенных методов.
  4. Аналогично, приватные, статические и терминальные методы разрешаются при помощи статического связывания, поскольку их нельзя переопределять, а все виртуальные методы разрешаются при помощи динамического связывания.
  5. В случае статического связывания используются не конкретные объекты, а информация о типе, то есть для обнаружения нужного метода используется тип ссылочной переменной. С другой стороны, при динамическом связывании для нахождения нужного метода в Java используется конкретный объект.

Различия между ранним и поздним связыванием в Java - 2

Что выведет эта программа? Collection , Set или HashSet ? Вот и все, что мы хотели рассказать вам о различиях между ранним (статическим) и поздним (динамическим) связыванием в языке Java. Это один из лучших вопросов для телефонного собеседования по языку Java, поскольку оно предоставляет немало возможностей проверки глубины знаний кандидата. Всегда помните, что приватные, статические и final-методы связываются при помощи статического связывания, а виртуальные – динамического. Аналогично, лучший пример статического связывания – перегрузка методов, а переопределение – динамического. Источник

Источник

Отношения между классами

Большая часть классов приложения связаны между собой. В этом разделе рассмотрим какие бывают отношения между классами в Java.

1. IS-A отношения

В ООП принцип IS-A основан на наследовании классов или реализации интерфейсов. Например, если класс HeavyBox наследует Box , мы говорим, что HeavyBox является Box ( HeavyBox IS-A Box ). Или другой пример — класс Lorry расширяет класс Car . В этом случае Lorry IS-A Car .

То же самое относится и к реализации интерфейсов. Если класс Transport реализует интерфейс Moveable , то они находятся в отношении Transport IS-A Moveable .

2. HAS-A отношения

HAS-A отношения основаны на использовании. Выделяют три варианта отношения HAS-A: ассоциация, агрегация и композиция.

Начнем с ассоциации. В этих отношениях объекты двух классов могут ссылаться друг на друга. Например, класс Horse HAS-A Halter если код в классе Horse содержит ссылку на экземпляр класса Halter :

Ассоциация

Агрегация и композиция являются частными случаями ассоциации. Агрегация — отношение когда один объект является частью другого. А композиция — еще более тесная связь, когда объект не только является частью другого объекта, но и вообще не может принадлежать другому объекту. Разница будет понятна при рассмотрении реализации этих отношений.

Агрегация

Объект класса Halter создается извне Horse и передается в конструктор для установления связи. Если объект класса Horse будет удален, объект класса Halter может и дальше использоваться, если, конечно, на него останется ссылка:

Композиция

Теперь посмотрим на реализацию композиции. Объект класса Halter создается в конструкторе, что означает более тесную связь между объектами. Объект класса Halter не может существовать без создавшего его объекта Horse:

Источник

Статическое и динамическое связывание в Java

Polymorphism позволяет объекту принимать несколько форм — когда метод демонстрирует полиморфизм, компилятор должен сопоставить имя метода с окончательной реализацией.

Если он отображается во время компиляции, это статическая или ранняя привязка.

Если проблема решена во время выполнения, она называется динамической или поздней привязкой.

2. Понимание через код

Когда подкласс расширяет суперкласс, он может повторно реализовать методы, определенные в нем. Это называется переопределением метода.

Например, давайте создадим суперклассAnimal:

public class Animal < static Logger logger = LoggerFactory.getLogger(Animal.class); public void makeNoise() < logger.info("generic animal noise"); >public void makeNoise(Integer repetitions) < while(repetitions != 0) < logger.info("generic animal noise countdown " + repetitions); repetitions -= 1; >> >
public class Dog extends Animal < static Logger logger = LoggerFactory.getLogger(Dog.class); @Override public void makeNoise() < logger.info("woof woof!"); >>

При перегрузке метода, такого какmakeNoise() классаAnimal, компилятор разрешит метод и его код во время компиляции. This is an example of static binding.

Однако, если мы присвоим объект типаDog ссылке типаAnimal, компилятор разрешит отображение кода функции во время выполнения. Это динамическое связывание.

Чтобы понять, как это работает, давайте напишем небольшой фрагмент кода для вызова классов и их методов:

Animal animal = new Animal(); // calling methods of animal object animal.makeNoise(); animal.makeNoise(3); // assigning a dog object to reference of type Animal Animal dogAnimal = new Dog(); dogAnimal.makeNoise(); The output of the above code will be:
com.example.binding.Animal - generic animal noise com.example.binding.Animal - generic animal noise countdown 3 com.example.binding.Animal - generic animal noise countdown 2 com.example.binding.Animal - generic animal noise countdown 1 com.example.binding.Dog - woof woof!

А теперь давайте создадим класс:

class AnimalActivity < public static void eat(Animal animal) < System.out.println("Animal is eating"); >public static void eat(Dog dog) < System.out.println("Dog is eating"); >>

Давайте добавим эти строки в основной класс:

AnimalActivity.eat(dogAnimal);
com.example.binding.AnimalActivity - Animal is eating

This example shows that a static function undergoes static binding.

Причина в том, что подклассы не могут переопределять статические методы. Если бы подкласс реализовал тот же метод, он бы скрыл метод суперкласса. Similarly, if a method is final or private, the JVM will do a static binding.с

Статический связанный метод не связан с конкретным объектом, а скорее вызывается вType (класс в Java). Выполнение такого метода незначительно быстрее.

Любой другой метод автоматически является виртуальным методом в Java по умолчанию. JVM разрешает такие методы во время выполнения, и это динамическое связывание.

Точная реализация зависит от JVM, но для этого потребуется подход, подобный C ++, где JVM ищет виртуальную таблицу, чтобы решить, какой объект будет вызываться методом.

3. Заключение

Связывание является неотъемлемой частью языка, реализующего полиморфизм, важно понимать последствия статического и динамического связывания, чтобы быть уверенным, что наши приложения ведут себя так, как мы хотим.

Однако с этим пониманием мы можем эффективно использовать наследование классов, а также перегрузку методов.

Источник

Оцените статью