Casting Objects em Java

Estou confuso sobre o que significa lançar objects em Java.

Diga que você tem …

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

O que esta acontecendo aqui? O tipo de variável é alterado ou é o object dentro da variável que muda? Muito confuso.

Dê uma olhada neste exemplo:

 public class A { //statements } public class B extends A { public void foo() { } } A a=new B(); //To execute **foo()** method. ((B)a).foo(); 

Digamos que você tenha uma superclass Fruit e a subclass Banana e você tenha um método addBananaToBasket ()

O método não aceitará uvas, por exemplo, para ter certeza de que você está adicionando uma banana à cesta.

Assim:

Fruit myFruit = new Banana();
((Banana)myFruit).addBananaToBasket(); ⇐ Isso é chamado de casting

O exemplo a que você está se referindo é chamado Upcasting em java.

Cria um object de subclass com uma variável superclass apontando para ele.

A variável não muda, ainda é a variável da superclass, mas está apontando para o object da subclass.

Por exemplo, digamos que você tenha duas classs Machine e Camera; A câmera é uma subclass da máquina

 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(); 

Se você executar as instruções acima, ele criará uma instância da class Camera com uma referência da class Machine apontando para ela. Agora, a saída será ” Camera Started ” A variável ainda é uma referência da class Machine. Se você tentar machine1.snap(); o código não compilará

O takeaway aqui é tudo Câmeras são máquinas desde que a câmera é uma subclass de máquina, mas todas as máquinas não são câmeras. Então você pode criar um object de subclass e apontá-lo para uma superclass de class, mas você não pode pedir à superclass de referência para fazer todas as funções de um object de subclass (No nosso exemplo, machine1.snap() não compilará). A referência da superclass tem access apenas às funções conhecidas da superclass (no nosso exemplo machine1.start() ). Você não pode pedir uma referência de máquina para tirar um piscar de olhos. 🙂

Superclass variable = new subclass object();
Isto apenas cria um object do tipo subclass, mas o atribui ao tipo de superclass. Todos os dados das subclasss são criados, etc, mas a variável não pode acessar os dados / funções das subclasss. Em outras palavras, você não pode chamar nenhum método ou acessar dados específicos da subclass, você só pode acessar o material das superclasss.

No entanto, você pode converter a variável Superclass na Subclass e usar seus methods / dados.

Às vezes você vai gostar de receber como argumento uma referência aos Pais e dentro de você provavelmente querer fazer algo específico de uma criança.

 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. } ... 

No método acima você pode passar Shark ou Dog, mas e se você tem algo assim:

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

Esse método só pode ser chamado passando referências de tubarão. Então, se você tem um Animal (e é profundamente um Tubarão), você pode chamá-lo assim:

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

Bottom line, você pode usar referências pai e é geralmente melhor quando você não se importa com a implementação do pai e usar o casting para usar o filho como um object específico, será exatamente o mesmo object, mas sua referência sabe disso , se você não fizer isso, sua referência apontará para o mesmo object, mas não pode ter certeza de que tipo de Animal seria, portanto, só permitirá que você chame methods conhecidos.

Vamos dizer que você tem class A como superclass e subclass Classe B de 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 } } 

Neste exemplo, sua variável superclass está dizendo ao object da subclass para implementar o método da superclass. Esse é o caso da conversão de tipo de object java. Aqui, a function method () é originalmente o método da superclass, mas a variável superclass não pode acessar os outros methods do object da subclass que não estão presentes na superclass.

Por exemplo, você tem superclass de Animal e subclass de Cat. Mostre que sua subclass possui speak (); método.

 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(); } } 

em alguns casos, não podemos fornecer garantia para o tipo de elementos ou objects presentes em nossa coleção ou sábio, no momento da recuperação obrigatória, devemos executar a conversão de tipos, caso contrário, obteremos erros de tempo de compilation.

Os arrays são sempre seguros, ou seja, podemos fornecer a garantia para o tipo de elementos presentes no array. para conseguir segurança de tipo, temos que usar typecasting.

Casting é necessário para dizer que você está chamando um filho e não um método pai. Então é sempre para baixo. No entanto, se o método já estiver definido na class pai e sobrescrito na class filha, você não converterá nenhum. Aqui um exemplo:

 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(); 

A chamada de dois methods será impressa: “this is the child”.