java 从派生类创建基类对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30501237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:14:06  来源:igfitidea点击:

Create a base class object from a derived class

javaclassinheritance

提问by St.Antario

I have the following classes:

我有以下课程:

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

Now, I have a method which has a parameter of the type Derived.

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

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

But I can't just do assignment like b = d;and then invoke b.getStr()because the method d.getStr()is going to be called.

但我不能只做赋值b = d;然后调用,b.getStr()因为该方法d.getStr()将被调用。

How can I create the object of the type Basefrom the Basesubobject of the objec of the type Derived? I fact, I just wanta create the copy of the Basesubobject of the type Derived.

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

回答by Eran

The whole point of overriding methods in sub-classes is that the method of the sub-class would get executed in run-time, even if the compile time type is that of the super-class.

覆盖子类中方法的全部意义在于子类的方法将在运行时执行,即使编译时类型是超类的。

If for some reason you require an instance of the super-class, you should add a copy constructor to your super-class and use it to create such an instance :

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

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

}

Then :

然后 :

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

回答by amit

You can use a "Has-a" relationinstead of "is-a" relation.

您可以使用“Has-a”关系而不是“is-a”关系

In this case, rather than having Derivedextend Base, you can make it have a field of type Base.
Derivedwill be a seperate class, with its own functionality, and will support the functionality of Base, via its Basefield.

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

If it's the correct design or not is really implementation dependent, and it is hard to suggest if it is, based on the information provided.

设计是否正确实际上取决于实现,并且根据提供的信息很难建议是否正确。

回答by Sergei Petunin

When you inherit one class from another in Java, there is no such thing as a parent "subobject" for the object of the child class. You seem to be wishing for a prototype-based inheritance, like in JavaScript.

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

If you wish to access a "subobject", you may want to implement your "inheritance" another way. The Derived object should not inherit from the Base object, but instead wrap it.

如果您希望访问“子对象”,您可能希望以另一种方式实现您的“继承”。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();
    // ...
}

回答by Sergei Petunin

Basic idea is that when object of child class created than there is no definition of overridden method of base class object in child class object, so you never get such method of super from child class object.

基本思想是,当子类对象创建时,子类对象中没有定义基类对象的重写方法,因此您永远不会从子类对象中获得super的这种方法。

you can get rest members by just typecasting it.

你可以通过对它的类型转换来获得休息成员。

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

you can get only object of parent class by using constructor-

您只能通过使用构造函数获取父类的对象-

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

let suppose following is your method-

假设以下是您的方法-

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

NOTE:this is impossible to get overrided method of Parent class from Child class object.

注意:这是不可能从子类对象获取父类的覆盖方法。

回答by Holger

If you really want to make the implementation of the base class available, you can do it like:

如果你真的想让基类的实现可用,你可以这样做:

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

The whole point about it is, that if a class decides to override an inherited method, it also controls for its own instances whether the original method will be made available to other classes.

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

The Derivedclass can always invoke the original implementation of Basefor the thisinstance via super.getStr(), but in order to invoke it on arbitrary instances (e.g. those passed in as parameter) or to expose this possibility to other classes, you need another method like in the example above. Then you can invoke getBaseStr()on arbitrary instances of Derived.

Derived班可随时调用原来实行的Basethis通过实例super.getStr(),但为了调用它的任意实例(例如那些通过作为参数)或者暴露这种可能性的其他类,你需要像上面例子中的另一种方法。然后您可以调用getBaseStr()的任意实例Derived

回答by Zefick

I fact, I just wanta create the copy of the Base subobject of the type Derived.

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

Just do it. Implement copy constructot in your Base

去做就对了。在您的 Base 中实现复制构造函数

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

and call it when you want to get Base from Derived:

并在您想从 Derived 获取 Base 时调用它:

Base b = new Base(d);

回答by Thilo

You cannot do this.

你不能做这个。

The derived object instance will forever be attached to its own class. You cannot just "revert" it back to the base class, and you cannot just "skip" its overridden method to go back to the base class' implementation.

派生对象实例将永远附加到它自己的类。您不能只是将它“还原”回基类,也不能只是“跳过”它的重写方法以返回基类的实现。

回答by nuno

If you want to assume the Baseand Derivedobjects share a common feature you could implement an interface

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

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

If you want to copy objects I would go with @Eran answer - create a copy constructor.

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