从派生类创建基类对象

St.*_*rio 16 java inheritance class

我有以下课程:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我有一个具有类型参数的方法Derived.

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

但我不能只是做任务b = d;然后调用b.getStr()因为该方法d.getStr()将被调用.

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

Era*_*ran 22

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

然后 :

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

  • @ St.Antario你可以通过反思来做到这一点. (2认同)
  • @ St.Antario如果要调用基本实现,为什么要重写该方法?如果将其声明为final,则可以阻止覆盖该方法,在这种情况下,将始终调用基本实现. (2认同)

ami*_*mit 12

您可以使用"Has-a"关系而不是"is-a"关系.

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

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

  • 正是这个!在很多情况下,人们应该使用构图而不是继承! - 有时人们只是使用继承,因为在学校里学习它并认为做正确的OO你必须有许多扩展和实现,因为它看起来很花哨. (4认同)

Ser*_*nin 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();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,OP所讨论的"复制子对象"概念似乎是直接从C++中获取的 - 并且几乎对任何其他语言都没有多大意义. (2认同)

小智 5

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

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

Base castedInBase = derivedObj;
//child class specific member as well as hided fields are also availble here.
Run Code Online (Sandbox Code Playgroud)

你可以通过使用构造函数获得父类的对象 -

Base base= new Base(derivedObj);
//orrided method of base class lost,will refer to super class overrided method.
Run Code Online (Sandbox Code Playgroud)

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

public void makeStr(Derived derivedObj){
        Base castedInBase = derivedObj;
    }
Run Code Online (Sandbox Code Playgroud)

注意:这不可能从Child类对象中获取父类的重写方法.