Приведение объектов в Java - PullRequest
50 голосов
/ 15 марта 2011

Я не совсем понимаю, что значит приводить объекты в Java.

Скажи, что у тебя есть ...

Superclass variable = new Subclass object();
(Superclass variable).method();

Что здесь происходит? Меняется ли тип переменной или объект в переменной изменяется? Очень растерян.

Ответы [ 10 ]

77 голосов
/ 15 марта 2011

Посмотрите на этот образец:

public class A {
  //statements
}

public class B extends A {
  public void foo() { }
}

A a=new B();

//To execute **foo()** method.

((B)a).foo();
48 голосов
/ 15 марта 2011

Скажем, у вас есть суперкласс Fruit и подкласс Banana , и у вас есть метод addBananaToBasket ()

Метод не принимает, например, виноград , поэтому необходимо убедиться, что вы добавляете банан в корзину.

Итак:

Fruit myFruit = new Banana();
((Banana)myFruit).addBananaToBasket(); ⇐ Это называется кастингом

10 голосов
/ 02 декабря 2013

Пример, на который вы ссылаетесь, называется Upcasting in java.

Создает объект подкласса, на который указывает переменная суперкласса.

Переменная не изменяется, она по-прежнему является переменной суперкласса, но она указывает на объект подкласса.

Например, допустим, у вас есть два класса Machine и Camera; Камера является подклассом машины

class Machine{

    public void start(){

        System.out.println("Machine Started");
    }
}

class Camera extends Machine{
     public void start(){

            System.out.println("Camera Started");
        }
     public void snap(){
         System.out.println("Photo taken");
     }
 }
Machine machine1 = new Camera();
machine1.start();

Если вы выполните приведенные выше операторы, он создаст экземпляр класса Camera со ссылкой на класс Machine, указывающий на него. Итак, теперь вывод будет " Camera Started " Переменная все еще является ссылкой на класс Machine. Если вы попытаетесь machine1.snap();, код не скомпилируется

Вывод: все камеры являются машинами, поскольку камера является подклассом машин, но все машины не являются камерами. Таким образом, вы можете создать объект подкласса и указать ему ссылку на суперкласс, но вы не можете попросить ссылку на суперкласс выполнить все функции объекта подкласса (в нашем примере machine1.snap() не будет компилироваться). Ссылка на суперкласс имеет доступ только к функциям, известным суперклассу (в нашем примере machine1.start()). Вы не можете попросить ссылку на машину сделать снимок. :)

6 голосов
/ 15 марта 2011

Superclass variable = new subclass object();
Это просто создает объект подкласса типа, но назначает его суперклассу типа. Все данные подклассов созданы и т. Д., Но переменная не может получить доступ к данным / функциям подклассов. Другими словами, вы не можете вызывать какие-либо методы или обращаться к данным, относящимся к подклассу, вы можете получить доступ только к материалу суперклассов.

Однако вы можете привести Superclassvariable к Подклассу и использовать его методы / данные.

4 голосов
/ 12 сентября 2015

Допустим, у вас есть класс A в качестве суперкласса и подкласс класса B в A.

public class A {

    public void printFromA(){
        System.out.println("Inside A");
    }
}
public class B extends A {

    public void printFromB(){
        System.out.println("Inside B");
    }

}

public class MainClass {

    public static void main(String []args){

        A a = new B();
        a.printFromA(); //this can be called without typecasting

        ((B)a).printFromB(); //the method printFromB needs to be typecast 
    }
}
4 голосов
/ 11 сентября 2013

Иногда вам захочется получить в качестве аргумента родительскую ссылку, и внутри вы, вероятно, захотите сделать что-то специфическое для ребенка.

abstract class Animal{
 public abstract void move();
}
class Shark extends Animal{
 public void move(){
  swim();
 }
 public void swim(){}
 public void bite(){}
}
class Dog extends Animal{
 public void move(){
  run();
 }
 public void run(){}
 public void bark(){}
}

...

void somethingSpecific(Animal animal){
 // Here you don't know and may don't care which animal enters
 animal.move(); // You can call parent methods but you can't call bark or bite.
 if(animal instanceof Shark){
  Shark shark = (Shark)animal;
  shark.bite(); // Now you can call bite!
 }
 //doSomethingSharky(animal); // You cannot call this method.
}

...

В вышеописанном методе вы можете передать либо Акулу, либо Собаку, но что еслиу вас есть что-то вроде этого:

void doSomethingSharky(Shark shark){
 //Here you cannot receive an Animal reference
}

Этот метод может быть вызван только путем передачи ссылок на акулу. Поэтому, если у вас есть животное (и это глубоко Акула), вы можете вызвать его так:

Animal animal...
doSomethingSharky((Shark) animal)

В итоге, вы можете использовать родительские ссылки, и, как правило, лучше, если вы не заботитесь о реализации родителя и используете приведение для использования дочернего объекта в качестве конкретного объекта, это будет точно такой же объект,но ваша ссылка знает это, если вы не разыгрываете ее, ваша ссылка будет указывать на тот же объект, но не может быть уверена, какой это будет тип Animal, поэтому позволит вам вызывать только известные методы.

2 голосов
/ 20 февраля 2015

Например, у вас есть суперкласс Animal и подкласс Cat. Скажем, у вашего подкласса имеется функция speak (); способ.

class Animal{

  public void walk(){

  }

}

class Cat extends Animal{

  @Override
  public void walk(){

  }

  public void speak(){

  }

  public void main(String args[]){

    Animal a=new Cat();
    //a.speak(); Compile Error
    // If you use speak method for "a" reference variable you should downcast. Like this:

    ((Cat)a).speak();
  }

}
2 голосов
/ 12 февраля 2012

В этом примере ваша переменная суперкласса сообщает объекту подкласса для реализации метода суперкласса. Это случай приведения типов объектов Java. Здесь функция method () изначально является методом суперкласса, но переменная суперкласса не может обращаться к другим методам объекта подкласса, которых нет в суперклассе.

1 голос
/ 30 декабря 2014

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

Массивы всегда безопасны от типа, то есть мы можем предоставить гарантию на тип элементов, присутствующих в массиве. для достижения безопасности типов мы должны использовать типирование.

0 голосов
/ 05 августа 2013

Приведение необходимо, чтобы сказать, что вы вызываете дочерний, а не родительский метод. Так что это всегда вниз. Однако, если метод уже определен в родительском классе и переопределен в дочернем классе, вы не выполняете приведение. Вот пример:

class Parent{
   void method(){ System.out.print("this is the parent"); }
}

class Child extends Parent{
   @override
   void method(){ System.out.print("this is the child"); }
}
...
Parent o = new Child();
o.method();
((Child)o).method();  

При вызове двух методов будет напечатано: «это дочерний элемент».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...