用Java编译对象

use*_*168 50 java casting object

我对在Java中强制转换对象意味着什么感到困惑.

说你有......

Superclass variable = new Subclass object();
(Superclass variable).method();
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?变量类型是否更改,或者变量中的对象是否更改?非常困惑.

ada*_*ost 79

看看这个样本:

public class A {
  //statements
}

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

A a=new B();

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

((B)a).foo();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.所以最初你无法访问子类中的方法,因为你只限于超类的方法.如果我理解正确,你输入变量来引用子类类型,以便您可以访问其内容? (6认同)

Sad*_*diq 48

假设你有一个超类Fruit和子类Banana,你有一个方法addBananaToBasket()

例如,该方法不接受葡萄,因此您需要确保在篮子中添加香蕉.

所以:

Fruit myFruit = new Banana();
((Banana)myFruit).addBananaToBasket(); ⇐这称为铸造


小智 10

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

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

变量不会改变,它仍然是超类的变量,但它指向子类的对象.

例如,假设您有两个类机器和相机; Camera是Machine的子类

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();
Run Code Online (Sandbox Code Playgroud)

如果你执行上面的语句,它将创建一个Camera类的实例,其引用指向它的Machine类.因此,现在输出将是" Camera Started "该变量仍然是Machine类的引用.如果您尝试machine1.snap();代码将无法编译

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


use*_*879 6

Superclass variable = new subclass object();
这只是创建一个类型为子类的对象,但是将它分配给类型超类.创建所有子类的数据等,但变量无法访问子类数据/函数.换句话说,你不能调用任何方法或访问特定于子类的数据,你只能访问超类的东西.

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

  • 子类可以覆盖超类上的函数,它确实提供对其数据/函数的访问. (3认同)

por*_*ida 5

有时您会希望收到一个 Parent 引用作为参数,并且在内部您可能想要做一些特定于孩子的事情。

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

...
Run Code Online (Sandbox Code Playgroud)

在上面的方法中,你可以传递 Shark 或 Dog,但是如果你有这样的东西怎么办:

void doSomethingSharky(Shark shark){
 //Here you cannot receive an Animal reference
}
Run Code Online (Sandbox Code Playgroud)

该方法只能通过传递鲨鱼引用来调用所以如果你有一个动物(它是一个鲨鱼),你可以这样调用它:

Animal animal...
doSomethingSharky((Shark) animal)
Run Code Online (Sandbox Code Playgroud)

最重要的是,您可以使用 Parent 引用,当您不关心父级的实现并使用强制转换将 Child 用作特定对象时通常会更好,它将是完全相同的对象,但您的引用知道这一点, 如果你不强制转换,你的引用将指向同一个对象,但不能确定它是什么类型的 Animal,因此只允许你调用已知的方法。

  • 这是一个很好的解释,但似乎没有引起任何关注? (2认同)