从派生类创建基类对象

时间:2015-05-28 08:33:49

标签: java class inheritance

我有以下课程:

public class Base{

    //fields
    public String getStr(){
        String str = null;
        //Getting str from the fields
        return str;
    }
}

public class Derived extends Base{

    //fields
    //some other fileds
    public String getStr(){
        String str = null;
        //Getting str from the fields + some other fields
        return str;
    }
}

现在,我有一个方法,其参数类型为Derived

public void makeStr(Derived d){
    Base b = null;
    //Getting the Base class subobject from d and printing the str
}

但我不能像b = d;那样执行任务,然后调用b.getStr(),因为将调用方法d.getStr()

如何从Base类型的对象的Base子对象创建Derived类型的对象?事实上,我只想创建Base类型的Derived子对象的副本。

8 个答案:

答案 0 :(得分:22)

子类中重写方法的重点在于子类的方法将在运行时执行,即使编译时类型是超类的类型。

如果由于某种原因需要超类的实例,则应该向超类添加一个复制构造函数并使用它来创建这样的实例:

public class Base {
    ...
    Base (Base source) {
        // copy the properties from source
    }

}

然后:

public void makeStr(Derived d)
{ 
    Base b = new Base(d);
    ... b.getStr() will call the Base class implementation
}

答案 1 :(得分:12)

您可以使用"Has-a" relation代替"is-a" relation

在这种情况下,您可以使其具有Derived类型的字段,而不是Base扩展Base
Derived将是一个单独的类,具有自己的功能,并将通过其Base字段支持Base的功能。

如果它是正确的设计是否真的依赖于实现,并且根据提供的信息很难建议它是否正确。

答案 2 :(得分:5)

当你在Java中从另一个类继承一个类时,对于子类的对象,没有父类“子对象”这样的东西。您似乎希望基于原型的继承,就像在JavaScript中一样。

如果您想访问“子对象”,您可能希望以另一种方式实现“继承”。 Derived对象不应该从Base对象继承,而是包装它。

class Derived {

    private Base base;

    public Derived(Base base) {
        this.base = base;
    }

    public Base getBase() {
        return this.base;
    }
}

public void makeStr(Derived d){
    Base b = d.getBase();
    // ...
}

答案 3 :(得分:5)

基本思想是,当创建子类的对象时,子类对象中没有基类对象的重写方法的定义,所以你永远不会从子类对象中获得这样的超级方法。

你可以通过强制转换来获得休息成员。

Base castedInBase = derivedObj;
//child class specific member as well as hided fields are also availble here.

您只能使用构造函数 -

获取父类的对象
Base base= new Base(derivedObj);
//orrided method of base class lost,will refer to super class overrided method.

让我们假设以下是您的方法 -

public void makeStr(Derived derivedObj){
        Base castedInBase = derivedObj;
    }
  

注意:这是不可能从父类的重写方法   子类对象。

答案 4 :(得分:4)

如果您真的想要实现基类的实现,可以这样做:

public class Derived extends Base{
    …
    public String getStr(){
        String str = null;
        // produce the specialized string
        return str;
    }
    public String getBaseStr(){
         return super.getStr(); // delegate to base class
    }
}

关于它的重点是,如果一个类决定覆盖一个继承的方法,它还控制它自己的实例是否原始方法可用于其他类。

Derived类始终可以通过Basethis实例调用super.getStr()的原始实现,但是为了在任意实例上调用它(例如通过的那些实例)在as参数中)或者将这种可能性暴露给其他类,你需要另一种方法,如上例所示。然后,您可以在getBaseStr()的任意实例上调用Derived

答案 5 :(得分:3)

你不能这样做。

派生的对象实例将永远附加到自己的类。你不能只是"还原"它回到基类,你不能只是"跳过"它被重写的方法回到基类'实施

答案 6 :(得分:3)

如果您想假设BaseDerived个对象共享一个共同特征,您可以实现一个接口

public interface IStr {
    String getStr();
}
public class Base implements IStr {
    //...
}
public class Derived implements IStr {
    //...
}
public void makeStr(IStr o) {
    // ...
}

如果你想复制对象我将使用@Eran回答 - 创建一个复制构造函数。

答案 7 :(得分:3)

  

事实上,我只想创建Derived类型的Base子对象的副本。

做吧。在Base中实现copy constructot

public Base(Base b) {
    // assign all required fields from the old object
    ...
}

并在想要从Derived获得Base时调用它:

Base b = new Base(d);