【问题标题】:How to cast parent into child in Java如何在Java中将父级转换为子级
【发布时间】:2018-05-16 14:55:53
【问题描述】:

我正在这样做:

Child child = (Child)parent;

这给了我一个错误,我发现不可能这样做。我不知道具体原因,但我认为应该有可能,如果Child 类继承自Parent 类,它包含Parent 对象数据。

我的问题是:

  • 为什么它不起作用?


  • 如何在不设置每个父母的情况下完成这项工作 像这样的属性

class Parent{
    public int parameter1;//...
    public int parameter1000;
}

class Child extends Parent
{
    public Child(Parent parent)
{
        this.parameter1 = parent.parameter1;//...
        this.parameter1000 = parent.parameter1000;
}
}

【问题讨论】:

  • 可以这样做,iffparent实际上是指Child实例。
  • parent是什么类型?
  • 我从文件中加载了一些数据,例如: public Parent loadMe() { Parent p = new Parent(); ... 返回 p; } 然后我需要将此父级重铸为它的一些子级
  • 您尝试做的事情是不可能的。狗是动物,但动物并不(总是)是狗。铸造不会神奇地将一种类型的对象转换为另一种类型。它只是告诉编译器你比编译器更了解对象的实际类型。如果您需要Child,那么您需要使用new Child() 而不是new Parent()
  • 我有多个孩子,我不能只做20个相同内容的方法,只返回一个孩子,这是可能的,但我相信它可以做得更容易更好。

标签: java class oop inheritance parent


【解决方案1】:

你可以这样做:

Parent p = new Child();
// do whatever
Child c = (Child)p;

或者如果你必须从一个纯 Parent 对象开始,你可以考虑在你的父类中有一个构造函数并调用:

class Child{
    public Child(Parent p){
        super(p);
    }
}
class Parent{
    public Parent(Args...){
        //set params
    }
}

或者组合模型:

class Child {
    Parent p;
    int param1;
    int param2;
}

这种情况下可以直接设置父级。

您也可以使用 Apache Commons BeanUtils 来执行此操作。使用它的 BeanUtils 类,您可以访问许多用于通过反射填充 JavaBeans 属性的实用方法。

要将所有公共/继承属性从父对象复制到子类对象,您可以使用其静态 copyProperties() 方法:

BeanUtils.copyProperties(parentObj,childObject);

但请注意,这是一项繁重的操作。

【讨论】:

  • 嗯,这个是可以的,但是还是需要逐行设置参数。
  • int 字段有什么用? @likaa
  • 我在父类中并没有真正的int字段,我有不同的属性,其中一些是不同的类型,如果我只有int参数,我会把它放入数组中。
  • 你也可以从继承模式转移到组合模式。
  • @AkashRoyChoudhury 这是个好主意,如果我找不到更好的解决方案,我会使用它!
【解决方案2】:

在您的子构造函数中将“this”更改为“super”,并删除父参数,而是将其替换为两个参数 int parameter1;//...int parameter1000; :)

class Parent{
public int parameter1;//...
public int parameter1000;
}

class Child extends Parent
{
    public Child(int parameter1, int parameter1000)
    {
        super.parameter1 = parameter1
        super.parameter1000 = parameter1000;
    }
}

【讨论】:

  • 我想我不明白你的答案,我想表明我在父类中有多个参数(这就是为什么 parameter1 ... parameter1000)而我的问题是,如何在没有 1000 行的情况下做到这一点设置此参数。
  • 如果父类字段是私有的怎么办?
【解决方案3】:

你真的想把你的父母投进子班吗?如果给定的 Object(作为 Parent 对象)被创建为子类,则无需强制转换即可访问正确的函数。这是一个例子: 在主体中,您会看到一个 Vector 'ps' 来存储父对象,但添加的是从父对象扩展的子对象。在遍历该向量时,我不知道接下来会得到哪种孩子(因此我无法转换为正确的类),但是由于我调用的函数的关键字 Override,正确的孩子/使用方法。

import java.util.Vector;
import lib.Parent;
import lib.C1;
import lib.C2;

public class MyClass {
    public static void main(String []args){
        System.out.println("Hello World");
        C1 c1 = new C1();
        C2 c2 = new C2();
        
        ps.add(c1);
        ps.add(c2);
        
        for(int k = 0; k < ps.size(); k++){
            ps.get(k).setInteger(); // no cast needed
            System.out.println("stored entity " + ps.get(k).i);
        }
        // or use a ranged for loop
        for(Parent p: ps){
            p.setInteger();
            System.out.println("stored entity " + p.i);
        }
    }
     
    static Vector<Parent> ps = new Vector<>();
}

Parent 类:关键字 abstract 强制每个子类实现该方法,因此如果您有 Parent 对象,您可以安全地调用该方法。由于 Parent 类本身是抽象的,因此您不会有一个只是 Parent 对象的对象,因为这是不允许的并且不会编译。

package lib;
public abstract class Parent{
    public Integer i;
    
    public abstract void setInteger();
}

这里有两个子类,它们具有不同的 setInteger() 方法实现。

package lib;
import lib.Parent;

public class C1 extends Parent{
    
    @Override
    public void setInteger(){
        i = new Integer(1);
    }
}

第二个孩子:

package lib;
import lib.Parent;

public class C2 extends Parent{
     
    @Override
    public void setInteger(){
        i = new Integer(2);
    }
}

输出是

stored entity 1
stored entity 2
stored entity 1  <-- ranged for
stored entity 2  <-- ranged for

编辑: 文件结构如下所示

|-MyClass.java |-库 |-父类.java |-C1.java |-C2.java

【讨论】:

    【解决方案4】:

    你可以这样做

    class how {
        public void data(){
          System.out.println("Im in class");
             }
          }
    
    
    public class Main  extends how{
    
        public void method1(){
             System.out.println("Hey implemntation done");
        }
    
    
    
    public static void main(String[] args) {
        how h = new Main();
        ((Main)h).method1();
           
        }
     }
    

    我们在这里得到的输出是Hey implementation done。我们将基类how 转换为子类Main 像这样((Main)h) 调用子类method1method1

    加上你只能在父类包含子类对象的引用时转换父类

    【讨论】:

      猜你喜欢
      • 2021-08-29
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      相关资源
      最近更新 更多