从超类创建一个子类

时间:2013-05-30 09:34:30

标签: java inheritance

让我们说:

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

感谢您的帮助

6 个答案:

答案 0 :(得分: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
  }
}

通过使用演员你基本上告诉编译器“相信我。我是专业人士,我知道我在做什么,我知道虽然你不能保证,但我告诉你这个动物变量肯定会成为一只狗。“

由于动物实际上不是狗(它是动物,你可以做动物动物=新狗();而且它是狗)VM在运行时抛出异常,因为你违反了这种信任(你告诉编译器一切都会好的,但事实并非如此!)

编译器比仅仅盲目地接受所有内容更聪明一点,如果你尝试在不同的继承层次结构中强制转换对象(例如将一个Dog转换为一个String),那么编译器会把它扔回给你,因为它知道它永远不会可能会工作。

因为你实际上只是停止编译器的抱怨,所以每次你强制转换它都很重要,通过在if语句中使用instanceof来检查你是否会导致ClassCastException(或者是那种效果。)

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

您可以执行类似

的操作
A a = new B();
B b = (B) a;

答案 1 :(得分: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不能保证每个SalariedEmployee

答案 2 :(得分: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();      
    }
}

答案 3 :(得分:1)

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

你可以这样做:

 A a = new B();
 if (a instanceof B) {
     B dog = (B) a;
 }

答案 4 :(得分:1)

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

Animal也可以是Cat或其他,而DogCat必须是Animal

答案 5 :(得分:0)

此外,Child始终知道使用extends关键字完成的父级,但父级不了解子级。写下以下内容时:

a a = new B();

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