Java: разница между A x = new A () и A x = new B (), когда B расширяет A

Возможный дубликат:
java наследование – пожалуйста, объясните

Я изучаю Java, и у меня есть два вопроса:

  1. В чем разница между:

    A x = new A(); 

    а также

     A x = new B(); 

    Учитывая, что:

     class A class B extends A 
  2. В чем разница между:

     A x = new B(); (A)x.run_function(); 

    Предположим, что оба A и B имеют функцию run_function , какая из них будет выполнена?

6 Solutions collect form web for “Java: разница между A x = new A () и A x = new B (), когда B расширяет A”

Важнейшее различие между статическими и динамическими типами объектов и ссылками на объекты.

Скажем, B продолжается A и C расширяет B.

Динамический тип объекта (тип, используемый в новом) – это его фактический тип времени выполнения: он определяет фактические методы, которые присутствуют для объекта.

Статический тип ссылки на объект (переменная) является типом времени компиляции: он определяет или, скорее, объявляет, какие методы можно вызывать на объекте, который ссылается на переменную.

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

Таким образом, в нашем примере переменная со статическим типом A может ссылаться на объекты с динамическими типами A, B и C. Переменная со статическим типом B может ссылаться на объекты с динамическими типами B и C. Переменная со статическим типом C может ссылаться только на объекты с динамический тип C.

Наконец, вызов метода по ссылке на объект – это тонкое и сложное взаимодействие между статическими и динамическими типами. (Прочтите спецификацию языка Java при вызове метода, если вы мне не верите.)

Если оба A и B реализуют метод f (), например, а статический тип – A, а связанный с ним динамический тип – это C для вызова метода, то Bf () будет вызываться:

 B extends A, C extends B public Af() {} public Bf() {} A x = new C(); // static type A, dynamic type C xf(); // Bf() invoked 

Упрощение упрощения: сначала статические типы как приемника (типа A), так и аргументы (без аргументов) используются для определения наиболее подходящей (наиболее конкретной) сигнатуры метода для этого конкретного вызова, и это делается во время компиляции. Здесь это, очевидно, Af ().

Затем на втором этапе во время выполнения динамический тип используется для определения фактической реализации нашей сигнатуры метода. Начнем с типа C, но мы не найдем реализацию f (), поэтому переходим к B, и там мы имеем метод Bf (), который соответствует сигнатуре Af (). Таким образом вызывается Bf ().

В нашем примере мы говорим, что метод Bf () переопределяет метод Af (). Механизм переопределения методов в иерархии типов называется подтиповым polymorphismом.

1. В

 A x = new A(); 

x является экземпляром A и типа A

тогда как в

 A x = new B(); 

x является экземпляром B и типа A


2. Важно отметить, что (во втором случае), если вы вызываете x.someMethod() , будет вызываться метод B , а не метод A (это называется динамической привязкой , в отличие от статической привязки ). Кроме того, литье меняет только тип , поэтому

 A x = new B(); ((A)x).run_function(); // Need extra parenthesis! 

будет по-прежнему вызывать метод B


Как я сказал выше, вам нужно включить эти дополнительные скобки, поскольку

 (A)x.run_function(); 

эквивалентно

 (A)(x.run_function()); 

Дело 1:

Вы увидите разницу, когда у вас есть метод в B, который НЕ находится в A.

Когда вы пытаетесь вызвать этот метод с использованием ссылки «x», он не будет виден.

Случай 2:

Все вызовы методов будут основаны на типе объекта не ссылочного типа из-за polymorphismа (кроме статических методов)

 A x = new B(); 

В этом случае будет run_function class B run_function .

 A x = new A(); 

В этом случае будет выполняться class run_function .

 1.What is the difference between: A x = new A();and A x = new B(); 

Разница в том, что в первом случае вы создаете экземпляр classа типа A. Таким образом, вы сможете только вызывать методы, определенные в A. Во втором случае, если один и тот же метод имен существует как в A, так и в B, тогда B будет вызываться во время выполнения.

Однако во втором случае, используя reflection, также можно будет вызывать методы, которые определены в classе B, а не в classе A.

A x = new B(); (A)x.run_function(); Предположим, что оба A и B имеют функцию run_function, какая из них будет выполнена?

Помните – переопределение определяется во время выполнения, тогда как перегрузка определяется во время компиляции.

Таким образом, метод в classе B будет вызываться во время выполнения на основе Dynamic Binding.

  1. Нет никакой реальной разницы. Фактически для второго случая A старит объект B, но B является A, поэтому нет проблем. B в этом случае ведет себя как A.

  2. Он будет вызывать функцию run_function ()

Кроме того, с:

 A x = new B() 

Вы не сможете выполнять методы, определенные в B и которые не определены в A Однако, как указано ранее из-за polymorphismа в Java, если вы выполняете какие-либо методы, а B' переопределил эти методы, то он будет использовать реализацию B

  • Какова точка частной чистой виртуальной функции?
  • Список всех базовых classов в иерархии данного classа?
  • Может ли controller AngularJS наследовать от другого controllerа в том же модуле?
  • Во время выполнения найдите все classы в приложении Java, которые расширяют базовый class
  • Что такое объект classа (java.lang.Class)?
  • Перегрузка и переопределение
  • ASP.NET MVC 3: DefaultModelBinder с наследованием / polymorphismом
  • Наследование наследования проекта Maven - нужно ли указывать родительскую версию?
  • Вызов конструктора базового classа из конструктора производного classа
  • C #: создание унаследованного события
  • Виртуальные таблицы и макет памяти в нескольких виртуальных наследования
  • Interesting Posts

    Как преобразовать линейный переход ^ M в нормальный разрыв строки в файле, открытом в vim?

    Есть ли ограничение, которое ограничивает мой общий метод численными типами?

    Как сделать из списка в double в Java?

    Использование нескольких подключений Wi-Fi одновременно в Windows

    objective CONNECTIVITY_ACTION получена дважды при подключении Wi-Fi

    .NET Events – Что такое отправитель объекта и EventArgs?

    Использование Linq с 2D-массивом, Select not found

    Я сломал свой MBR / Windows, не разрешил мне переформатировать!

    Преобразовать вектор в строку

    Чтение двоичных данных из std :: cin

    Как проверить абстрактный class на Java с помощью JUnit?

    Статические методы унаследованы в Java?

    PHPstorm 10.0.3 Ошибка 502 Bad Gateway (из-за JavaVM?)

    Как изменить разрешения для всех файлов в каталоге и при добавлении новых файлов к значениям по умолчанию?

    Android PendingIntent, не получаемый BroadcastReceiver

    Давайте будем гением компьютера.