Повышающее и понижающее преобразование - важная часть Java, которая позволяет нам создавать сложные программы с использованием простого синтаксиса и дает нам большие преимущества, такие как полиморфизм или группирование различных объектов. Java позволяет обрабатывать объект типа подкласса как объект любого типа суперкласса. Это называется апкастингом. Повышение качества выполняется автоматически, а понижающее преобразование должно выполняться программистом вручную, и я постараюсь объяснить, почему это так.
Повышение и понижающее приведение НЕ похожи на приведение примитивов от одного к другому, и я считаю, что это вызывает большую путаницу, когда программист начинает изучать приведение объектов.
Полиморфизм: все методы в java по умолчанию виртуальные. Это означает, что любой метод может быть переопределен при использовании в наследовании, если этот метод не объявлен как final или static.
Вы можете увидеть ниже пример того, как getType();
работает в зависимости от типа объекта (Dog, Pet, Police Dog).
Предположим, у вас есть три собаки
Собака - это суперкласс.
Pet Dog - Собака расширяет Dog.
Police Dog - Полицейская собака расширяет Pet Dog.
public class Dog{
public String getType () {
System.out.println("NormalDog");
return "NormalDog";
}
}
/**
* Pet Dog has an extra method dogName()
*/
public class PetDog extends Dog{
public String getType () {
System.out.println("PetDog");
return "PetDog";
}
public String dogName () {
System.out.println("I don't have Name !!");
return "NO Name";
}
}
/**
* Police Dog has an extra method secretId()
*/
public class PoliceDog extends PetDog{
public String secretId() {
System.out.println("ID");
return "ID";
}
public String getType () {
System.out.println("I am a Police Dog");
return "Police Dog";
}
}
Полиморфизм: все методы в java по умолчанию виртуальные. Это означает, что любой метод может быть переопределен при использовании в наследовании, если этот метод не объявлен как final или static (объяснение относится к концепции виртуальных таблиц)
Виртуальная таблица / таблица отправки: таблица отправки объекта будет содержать адреса динамически связанных методов объекта. Вызов метода выполняется путем выборки адреса метода из диспетчерской таблицы объекта. Таблица диспетчеризации одинакова для всех объектов, принадлежащих к одному классу, и поэтому обычно используется ими совместно.
public static void main (String[] args) {
/**
* Creating the different objects with super class Reference
*/
Dog obj1 = new Dog();
` /**
* Object of Pet Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry about it
*
*/
Dog obj2 = new PetDog();
` /**
* Object of Police Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry
* about it here even though we are extending PoliceDog with PetDog
* since PetDog is extending Dog Java automatically upcast for us
*/
Dog obj3 = new PoliceDog();
}
obj1.getType();
Печать Normal Dog
obj2.getType();
Печать Pet Dog
obj3.getType();
Печать Police Dog
Понижающее значение должно выполняться программистом вручную
Когда вы пытаетесь вызвать метод secretID();
на obj3
, который равен PoliceDog object
, но ссылается на Dog
, который является суперклассом в иерархии, он выдает ошибку, поскольку obj3
не имеет доступа к методу secretId()
. Чтобы вызвать этот метод, который вам нужно уменьшить вручную, чтобы этот объект obj3 был PoliceDog
( (PoliceDog)obj3).secretID();
который печатает ID
Аналогичным образом, чтобы вызвать dogName();
method в классе PetDog
, вам нужно понизить obj2
до PetDog
, поскольку obj2 ссылается на Dog
и не имеет доступа к dogName();
методу.
( (PetDog)obj2).dogName();
Почему так происходит автоматическое преобразование вверх, а преобразование в сторону уменьшения должно выполняться вручную? Видите ли, апкастинг никогда не подводит. Но если у вас есть группа разных собак и вы хотите свести их всех к их типам, тогда есть шанс, что некоторые из этих собак на самом деле принадлежат к разным типам, то есть PetDog
, PoliceDog
, и процесс завершается ошибкой из-за выброса ClassCastException
.
Это причина, по которой вам нужно вручную понижать уровень ваших объектов, если вы связали свои объекты с типом суперкласса.
Примечание: здесь ссылка означает, что вы не меняете адрес памяти ваших объектов, когда вы понижаете его, он все равно остается таким же, вы просто группируете их по определенному типу в этом случае Dog
person
Nagarjuna Yelisetty
schedule
27.09.2015
Dog
- этоAnimal
. В большинстве случаев в апкастинге нет необходимости, если вы не хотите использовать определенный перегруженный метод.callme
существует как вAnimal
, так и вDog
.callme2
существует только вDog
, который вы преобразовываетеa
вDog
, чтобы он работал. - person Engineer2021   schedule 01.05.2014