4

比方说:

class A {
    public int fieldA = 0;
}

class B extends A {
    public int fieldB = 0; 
}

现在,我想从 A 创建一个 B 的实例:

A a = new A();
B b = (B) new A();

这给出了一个 classCastException。我可以在 B 中创建一个带有 A 实例并复制字段的 costructor,但这显然是不切实际的:

class B extends A {
    public int fieldB = 0; 

    B (A a){
        fieldA = a.fieldA;
    }
}

谢谢您的帮助

4

6 回答 6

8

举个例子

public class Animal
{
  public void eat(){}
}
public class Dog extends Animal
{
  public void eat(){}
  public void main(String[] args)
  {
    Animal animal=new Animal();
    Dog dog=(Dog) animal; //will not work
  }
}

通过使用强制转换,您实际上是在告诉编译器“相信我。我是专业人士,我知道自己在做什么,而且我知道虽然您不能保证,但我告诉您这个动物变量是肯定会变成一条狗。”

由于动物实际上不是狗(它是动物,您可以执行 Animal animal = new Dog(); 并且它会是狗)VM 在运行时抛出异常,因为您违反了该信任(您告诉编译器一切都会好的,但不是!)

编译器比盲目地接受所有东西要聪明一点,如果您尝试将对象转换为不同的继承层次结构(例如将 Dog 转换为 String),那么编译器会将其扔回给您,因为它知道这永远不可能工作。

因为您实际上只是在阻止编译器抱怨,所以每次转换时,重要的是检查您不会通过在 if 语句中使用 instanceof (或类似的东西)来导致 ClassCastException。

在您的情况下,您是说我的引用 b 将指向 B 点的对象,然后将其指向 A 类的对象(这不是引用 b 所期望的 B 类的对象)。因此你得到了classCastException。

你可以做类似的事情

A a = new B();
B b = (B) a;
于 2013-05-30T09:53:16.980 回答
1

试试这个,它会帮助你。我将向您展示您可以在您的程序中实现的小型演示。

//Inheitance Pass Reference of Child class into Super class object
class A
{

    void display()
    {
        System.out.println("\n\nSuper class A Dispaly method.");
    }
}

class B extends A
{

    void display1()
    {
        System.out.println("\n\nDerived class B Dispaly method.");
    }

    public static void main (String args[])
    {
        A objA = new A();
        objA.display();

        A a1;
        B b1 = new B();

        //Here is your answer.
        a1=b1;  //Dynamic Method Distpatch
        //a1 = new B(); //This will also work. //Dynamic Method Distpatch

        a1.display1();      
    }
}
于 2013-05-30T09:51:01.533 回答
1

A实际上不是 B(不是每个 A 都是 B,但所有 B 都是 A)

你可以这样做:

 A a = new B();
 if (a instanceof B) {
     B dog = (B) a;
 }
于 2013-05-30T09:51:14.627 回答
1

Class cast 的用法有所不同。

class Employee()
{
    //body
}

class SalariedEmployee extends Employee()
{
    //body
}

你有一些多态代码。

public static void met(Employee e)
{
    SalariedEmployee s = (SalariedEmployee)e
}

public static void somemethod()
{
    //You write a polymorphic method
    //You will create a list of Employees
    //Then you can write
    ArrayList<Employee> employees = new ArrayList<Employee>()

   //Create a SalariedEmployee
   Employee e = (Employee) new SalariedEmployee()
   employees.add(e);

   e = (Employee) new CommissionEmployee()
   employees.add(e);         

}

你不能这样做SalariedEmployee b = (SalariedEmployee) new Employee();,因为Employee不能保证 each 是SalariedEmployee.

于 2013-05-30T09:42:37.157 回答
1

假设你有AnimalDog extends Animal。您可以说“狗是动物”Animal animal = new Dog()),但不能说“动物是狗”Dog dog = new Animal())。

AnAnimal也可以是 aCat或任何东西,而 aDog或 aCat必然是 a Animal

于 2013-05-30T09:53:54.017 回答
0

此外,孩子总是知道父母是通过使用扩展关键字完成的,但父母对孩子一无所知。当写以下内容时:

A a = 新 B();

由于 child 中的 extends 子句,编译器能够将 child 的引用分配给 parent,这在编译时自行解决。继承关系在编译时自行解决。Java 中的强制转换仅影响引用的处理;他们从不改变实际对象的形式。引用指向的对象永远不会通过强制转换而改变,只有编译器(或运行时系统)的概念会改变。

于 2013-05-30T11:20:01.237 回答