在Java中强制转换对象

在Java中强制转换对象,java,object,casting,Java,Object,Casting,我不明白在Java中强制转换对象意味着什么 说你有 Superclass variable = new Subclass object(); (Superclass variable).method(); 这里发生了什么?变量类型是否发生变化,或者是变量中的对象发生了变化?非常混乱。超类变量=新的子类对象()这只是创建subclass类型的对象,但将其分配给类型超类。创建了所有子类的数据等,但变量无法访问子类数据/函数。换句话说,您不能调用任何方法或访问特定于子类的数据,只能访问超类 但是,您

我不明白在Java中强制转换对象意味着什么

说你有

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

这里发生了什么?变量类型是否发生变化,或者是变量中的对象发生了变化?非常混乱。

超类变量=新的子类对象()
这只是创建subclass类型的对象,但将其分配给类型超类。创建了所有子类的数据等,但变量无法访问子类数据/函数。换句话说,您不能调用任何方法或访问特定于子类的数据,只能访问超类


但是,您可以将Superclassvariable强制转换为子类并使用其方法/数据。

请查看此示例:

public class A {
  //statements
}

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

A a=new B();

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

((B)a).foo();

假设您有一个超类水果和子类香蕉,您有一个addBananaToBasket()方法

例如,该方法将不接受葡萄,因此您希望确保将香蕉添加到篮子中

因此:

Fruit myFruit=新香蕉()

((香蕉)myFruit).addBananaToBasket()⇐ 在这个例子中,超类变量告诉子类对象实现超类的方法。这就是java对象类型转换的情况。此处,method()函数最初是超类的方法,但超类变量无法访问超类中不存在的子类对象的其他方法。

强制转换是必要的,以告知您正在调用子类而不是父类方法。所以它一直在下降。但是,如果该方法已在父类中定义并在子类中重写,则不进行任何强制转换。这里有一个例子:

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

两个方法调用都将打印:“thisisthechild”

有时候,您希望收到一个父引用作为参数,并且在其中您可能希望对一个孩子做一些特定的事情

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)
只能通过传递shark引用来调用该方法 因此,如果你有一种动物(实际上是鲨鱼),你可以这样称呼它:

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

总之,您可以使用父引用,如果您不关心父对象的实现,而使用强制转换将子对象用作特定对象,则通常会更好,因为它将是完全相同的对象,但您的引用知道它,如果您不强制转换,您的引用将指向同一个对象,但无法确定它将是哪种动物,因此只允许您调用已知的方法。

您所引用的示例在java中称为Upcasting

它创建了一个子类对象,其中有一个超类变量指向它

变量没有改变,它仍然是超类的变量,但它指向子类的对象

例如,假设您有两个类:机器和照相机;照相机是机器的一个子类

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” 变量仍然是机器类的引用。如果您尝试
machine1.snap()代码将不会编译


这里的要点是所有的相机都是机器,因为相机是机器的一个子类,但所有的机器都不是相机。因此,您可以创建子类的对象并将其指向超类引用,但不能要求超类引用执行子类对象的所有功能(在我们的示例中,
machine1.snap()
不会编译)。超类引用只能访问超类已知的函数(在我们的示例中
machine1.start()
)。您不能要求机器参考人拍照。:)

在某些情况下,我们无法保证集合或wise中存在的元素或对象的类型, 在强制检索时,我们应该执行类型转换,否则我们将得到编译时错误

数组始终是类型安全的,也就是说,我们可以为数组中存在的元素类型提供保证。
为了实现类型安全,我们必须使用类型转换

例如,你有动物超类和猫子类。假设你的子类有speak();方法


假设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 
    }
}

请提供一个实际例子。在这种情况下,我很难理解您所说的内容。您发布的内容不是有效的Java。我想说你的意思是
((子类)变量).method()
。这将把
变量
转换为
子类
(这是一种安全转换),然后在其上执行
方法()
,这可能是一种未在
超类
上定义的方法。不过,子类可以覆盖超类上的函数,而超类确实提供对其数据/函数的访问。谢谢。因此,最初您无法访问子类中的方法,因为您仅限于超类的方法。如果我理解正确的话,您将变量转换为引用子类类型,这样您就可以访问它的内容了?@AVD如果方法foo()被重写了怎么办?你还需要施放吗?@Atieh-不。一个问题是关于施放的。这是最不正确的答案,在这个问题上,它是如何做到的。不是在Java中,你不能-1这是一个很好的解释,似乎没有什么吸引力??而且,调用machine1.start()将调用Camera.start(),因为调用new Camera()覆盖了机器的start()方法为什么不直接执行“Cat a=new Cat()”?