Создайте объект базового класса из производного класса

У меня есть следующие классы:

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 объекта objec типа Derived? Я факт, я просто хочу создать копию субъекта Base типа Derived.

Ответы

Ответ 1

Вся суть переопределяющих методов в подклассах заключается в том, что метод подкласса будет выполняться во время выполнения, даже если тип времени компиляции - это класс суперкласса.

Если по какой-то причине вам нужен экземпляр суперкласса, вы должны добавить конструктор копирования в свой суперкласс и использовать его для создания такого экземпляра:

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
}

Ответ 2

Вы можете использовать "Has-a" отношение вместо "is-a" .

В этом случае вместо Derived extend Base вы можете создать поле типа Base.
Derived будет отдельным классом с его собственной функциональностью и будет поддерживать функциональность Base через поле Base.

Если это правильный дизайн или нет, это зависит от реализации, и его сложно предположить, если это так, на основе предоставленной информации.

Ответ 3

Когда вы наследуете один класс от другого в Java, нет такой вещи, как родительский "подобъект" для объекта дочернего класса. Кажется, вы хотите получить наследование на основе прототипа, например, в JavaScript.

Если вы хотите получить доступ к "подобъекту", вы можете реализовать свое "наследование" другим способом. Объект Derived не должен наследоваться от базового объекта, а вместо этого обернуть его.

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();
    // ...
}

Ответ 4

Основная идея заключается в том, что когда объект дочернего класса создан, чем нет определения переопределенного метода объекта базового класса в объекте дочернего класса, поэтому вы никогда не получите такой метод супер из объекта дочернего класса.

вы можете получить участников отдыха, просто указав его.

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

ПРИМЕЧАНИЕ: невозможно получить метод переопределения родительского класса из Объект класса ребенка.

Ответ 5

Если вы действительно хотите сделать реализацию базового класса доступным, вы можете сделать это так:

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 всегда может ссылаться на исходную реализацию Base для экземпляра this через super.getStr(), но для его вызова в произвольных экземплярах (например, переданных в качестве параметра) или для раскрытия этого возможность для других классов, вам нужен другой метод, как в приведенном выше примере. Затем вы можете вызывать getBaseStr() в произвольных экземплярах Derived.

Ответ 6

Вы не можете этого сделать.

Образец производного объекта навсегда будет привязан к его собственному классу. Вы не можете просто "вернуть" его обратно в базовый класс, и вы не можете просто "пропустить" его переопределенный метод, чтобы вернуться к реализации базового класса.

Ответ 7

Если вы хотите предположить, что объекты Base и Derived имеют общую функцию, вы можете реализовать интерфейс

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

Если вы хотите скопировать объекты, я бы пошел с ответом @Eran - создайте конструктор копирования.

Ответ 8

Я факт, я просто хочу создать копию базового подобъекта типа Derived.

Просто сделай это. Реализовать конструктор копирования в базе

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

и назовите его, когда вы хотите получить Base from Derived:

Base b = new Base(d);