有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从超类实例创建实例

考虑以下情况:

class A {
  int x;
  int y;
}

class B extends A {
  int z;
}

现在,在代码的某个地方,这些类的用法如下:

A objA = getAFromSomewhere();
B objB = null;

在某种情况下,我想做一些

objB = objA; // can't do this
objB.z = someZ;

当然,真正的对象要复杂一点,所以不仅仅是复制两个整数。但它们也不太复杂

我知道我可以像这样为B编写构造函数:

public B(A anA) {
  this.a = anA.a;
  this.b = anA.b;

  this.z = 0;
}

但如果这真的是唯一的方法,我更喜欢将B的其他成员合并到A中

根据答案进行更新

我的问题不够清楚。我理解objB=objA;无法工作(因此我要求“类似”,意思是代码复杂度相当的东西),我知道浅拷贝与深拷贝的问题
我所寻找的是复制基类成员的可能性(比如使用clone()。您可能理解,手动复制每个成员是一个糟糕的解决方案,因为它会增加代码的复杂性和冗余。谢谢你的回复


共 (6) 个答案

  1. # 1 楼答案

    也许你可以这样做:

    class A {
        int x;
        int y;
    
        A(A a) {
            this.x = a.x;
            this.y = a.y;
        }
    }
    
    class B extends A {
        int z;
    
        B(A a) {
            super(a);
            z = 0;
        }
    }
    

    您仍然列出了每个字段,但每个类只列出一次

  2. # 2 楼答案

    没有简单的解决方案,因为没有一刀切的解决方案。基本上,您没有B中的所有信息,因此无法保证您会有一个“合理的”B对象

    您可能只想在B中创建一个构造函数,它接受一个A并将所有A数据复制到新的B

  3. # 3 楼答案

    。。。不是因为这是人们应该做的,而是因为我觉得这是一个挑战,下面是一些测试代码,它可以简单地复制对象(使用setter和getter方法):

    import java.lang.reflect.Method;
    import org.junit.Test;
    
    public class ObjectUtils {
        @Test
        public void test() {
            A a = new A();
            B b = new B();
            a.setX(1);
            a.setY(2);
            this.copyProperties(a, b);
        }
        private void copyProperties(Object obja, Object objb) {
            Method m[] = obja.getClass().getDeclaredMethods();
            for(int i=0;i<m.length;i++) {
                try {
                    String name = m[i].getName();
                    if(name.startsWith("get") || name.startsWith("is")) {
                        Class rtype = m[i].getReturnType();
                        String setter = name.replaceFirst("^(get|is)","set");
                        Class s = objb.getClass();
                        Method method = s.getMethod(setter,rtype);
                        Object[] args = new Object[1];
                        args[0] = m[i].invoke(obja);
                        method.invoke(objb,args[0]);
                    }
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }
        class A {
            int x;
            int y;
            /**
             * @return the x
             */
            public int getX() {
                return x;
            }
            /**
             * @param x the x to set
             */
            public void setX(int x) {
                this.x = x;
            }
            /**
             * @return the y
             */
            public int getY() {
                return y;
            }
            /**
             * @param y the y to set
             */
            public void setY(int y) {
                this.y = y;
            }       
        }
        class B extends A {
            int z;
            /**
             * @return the z
             */
            public int getZ() {
                return z;
            }
            /**
             * @param z the z to set
             */
            public void setZ(int z) {
                this.z = z;
            }
        }
    }
    
  4. # 4 楼答案

    如果你不害怕普通的小动物,你可以使用PropertyUtils

    import org.apache.commons.beanutils.PropertyUtils;
    class B extends A {
    B(final A a) {
    try {
            PropertyUtils.copyProperties(this, a);
        }
        catch (Exception e) {
        }
    }
    }
    
  5. # 5 楼答案

    这里有一个(相对)微不足道的解决方案

    class B中实现一个构造函数,该构造函数接受class A的实例并复制字段

    语言本身没有通用解决方案的原因之一是深度复制的问题

    例如,如果源对象包含更多的Objects,而不是普通类型,那么泛型复制操作符会做什么?只是复制参考资料(提供一个浅显的副本),还是制作真实的副本

    那么,如果其中一个对象是Collection呢?它是否也应该复制集合中的每个元素

    唯一合乎逻辑的结论是执行一个复制,但是实际上你根本没有得到一个复制

  6. # 6 楼答案

    我也很震惊

    您确实不能这样做:objB = objA;。 因为雷诺和宝马是汽车,但不是所有的汽车都是宝马

    谢谢你把A当作汽车,B当作宝马

    现在你说:

    Car car = new Renault();
    BMV bmv = car;  // you cannot do this. This is exactly your case.