在Java中如何将子对象列表传递和修改到以父对象列表作为参数的方法?

问题描述 投票:0回答:1

有一些帖子与我的要求类似,但我只需要描述一个实现并获得澄清。

我对Java不太熟悉。我需要修改两个类类型的列表对象。该列表将始终包含一种类型或另一种类型的对象,而不是同时包含两种类型。这些类有一个共同的父类。我想编写一个方法,可以使用强制转换来处理任一类类型的对象列表。我做了一个原型,这就是我的想法。

public class Parent {
    int x = 0;
}

public class Child1 extends Parent {
    int y = 1;
}

public class Child2 extends Parent {
    int z = 10;
}

import java.util.ArrayList;
import java.util.List;

public class CastTest {
    
    List<? extends Parent> modifyValues (List<? extends Parent> list) {
        int count = 1;
        for (Parent p: list) {
            p.x += count;
            if (p instanceof Child1) {
                Child1 c = (Child1)p;
                c.y += count;
            }
            else if (p instanceof Child2) {
                Child2 c = (Child2)p;
                c.z += count;
            }
            ++count;
        }
        return list;
    }

    void printValues (List<? extends Parent> list) {
        
        for (Parent p: list) {
            System.out.println("x:" + p.x);
            if (p instanceof Child1) {
                Child1 c = (Child1)p;
                System.out.println("y:" + c.y);
            }
            else if (p instanceof Child2) {
                Child2 c = (Child2)p;
                System.out.println("z:" + c.z);
            }
            System.out.println("------------------------");
        }
    }
    
    public static void main(String[] args) {
        
        CastTest castTest = new CastTest();
        
        System.out.println("-----------------Child 1-----------------");
        List<Child1> childList1 = new ArrayList<>();
        childList1.add(new Child1());
        childList1.add(new Child1());
        childList1.add(new Child1());

        List<? extends Parent> listAfter1 = castTest.modifyValues(childList1);
        castTest.printValues(listAfter1);
        
        System.out.println("\n-----------------Child 2-----------------");
        List<Child2> childList2 = new ArrayList<>();
        childList2.add(new Child2());
        childList2.add(new Child2());
        childList2.add(new Child2());

        List<? extends Parent> listAfter2 = castTest.modifyValues(childList2);
        castTest.printValues(listAfter2);
    }

}

这似乎有效。

在进行实际工作之前,我想知道此实现/转换是否可能存在问题,以及这是否是正确的方法或是否有更好的方法。

我必须使用 Java 8。

java java-8
1个回答
0
投票

您的解决方案工作正常,除非您开始添加 100 个以上的类。 然后,您必须为每个类实现不同的情况,因为即使某些类的变量名称(x,y,z)可能相同,必要的转换也会失败。

另一种可能性是使用反射。但这也需要对具有不同成员变量名称(x,y,z)的类进行不同的实现。 同样:可能,可行,但不是一个真正好的选择

在 Java 中做到这一点的最佳方法通常是让父类或接口声明一个函数(就像在您的例子中我们可以称之为

int getSpecialValue()
)来保证返回一个值。

这里将多个类和解决方案塞进一个类中:

package stackoverflow;

import java.util.List;

public class ForcedInheritance {


    // parent class provides function and possibly un-used variable
    static class NormalSolution {
        static public class NormalParent {
            int x               = 0;
            int specialValue    = 0;
            public void modifySpecialValue(final int pDelta) {
                specialValue += pDelta;
            }
            public int getSpecialValue() {
                return specialValue;
            }
        }
        static public class Child1ofNormalParent extends NormalParent {
            int y = 1;
        }
        static public class Child2ofNormalParent extends NormalParent {
            int z = 10;
        }
        List<? extends NormalParent> modifyValues(final List<? extends NormalParent> list) {
            int count = 1;
            for (final NormalParent p : list) {
                p.x += count;
                p.modifySpecialValue(count);
                ++count;
            }
            return list;
        }
        void printValues(final List<? extends NormalParent> list) {
            for (final NormalParent p : list) {
                System.out.println("x:" + p.x);
                System.out.println("special Value:" + p.getSpecialValue());
                System.out.println("------------------------");
            }
        }

    }


    // parent class forces children to provide method and variable
    static class AbstractSolution {
        static public abstract class AbstractParent {
            int x = 0;
            public abstract void modifySpecialValue(final int pDelta);
            public abstract int getSpecialValue();
        }
        static public class Child1ofAbstractParent extends AbstractParent {
            int y = 1;
            @Override public void modifySpecialValue(final int pDelta) {
                y += pDelta;
            }
            @Override public int getSpecialValue() {
                return y;
            }
        }
        static public class Child2ofAbstractParent extends AbstractParent {
            int z = 10;
            @Override public void modifySpecialValue(final int pDelta) {
                z += pDelta;
            }
            @Override public int getSpecialValue() {
                return z;
            }
        }
        List<? extends AbstractParent> modifyValues(final List<? extends AbstractParent> list) {
            int count = 1;
            for (final AbstractParent p : list) {
                p.x += count;
                p.modifySpecialValue(count);
                ++count;
            }
            return list;
        }
        void printValues(final List<? extends AbstractParent> list) {
            for (final AbstractParent p : list) {
                System.out.println("x:" + p.x);
                System.out.println("special value:" + p.getSpecialValue());
                System.out.println("------------------------");
            }
        }
    }


    // parent implements interface, similar to 'NormalSolution'
    static class InterfaceSolution1 {
        public interface ParentInterface1 {
            void modifySpecialValue(final int pDelta);
            int getSpecialValue();
        }
        static public abstract class InterfacedParent1 implements ParentInterface1 {
            int x = 0;
        }
        static public class Child1ofInterfacedParent1 extends InterfacedParent1 {
            int y = 1;
            @Override public void modifySpecialValue(final int pDelta) {
                y += pDelta;
            }
            @Override public int getSpecialValue() {
                return y;
            }
        }
        static public class Child2ofInterfacedParent1 extends InterfacedParent1 {
            int z = 10;
            @Override public void modifySpecialValue(final int pDelta) {
                z += pDelta;
            }
            @Override public int getSpecialValue() {
                return z;
            }
        }
        List<? extends InterfacedParent1> modifyValues(final List<? extends InterfacedParent1> list) {
            int count = 1;
            for (final InterfacedParent1 p : list) {
                p.x += count;
                p.modifySpecialValue(count);
                ++count;
            }
            return list;
        }
        void printValues(final List<? extends InterfacedParent1> list) {
            for (final InterfacedParent1 p : list) {
                System.out.println("x:" + p.x);
                System.out.println("special value:" + p.getSpecialValue());
                System.out.println("------------------------");
            }
        }
    }


    // each child implements interface on its own
    static class InterfaceSolution2 {
        public interface ParentInterface2 {
            void modifySpecialValue(final int pDelta);
            int getSpecialValue();
        }
        static public abstract class InterfacedParent2 {
            int x = 0;
        }
        static public class Child1ofInterfacedParent2 extends InterfacedParent2 implements ParentInterface2 {
            int y = 1;
            @Override public void modifySpecialValue(final int pDelta) {
                y += pDelta;
            }
            @Override public int getSpecialValue() {
                return y;
            }
        }
        static public class Child2ofInterfacedParent2 extends InterfacedParent2 implements ParentInterface2 {
            int z = 10;
            @Override public void modifySpecialValue(final int pDelta) {
                z += pDelta;
            }
            @Override public int getSpecialValue() {
                return z;
            }
        }
        List<? extends ParentInterface2> modifyValues(final List<? extends ParentInterface2> list) {
            int count = 1;
            for (final ParentInterface2 p : list) {
                //              p.x += count; //  not possible here
                p.modifySpecialValue(count);
                ++count;
            }
            return list;
        }
        void printValues(final List<? extends ParentInterface2> list) {
            for (final ParentInterface2 p : list) {
                //              System.out.println("x:" + p.x);  not possible here
                System.out.println("special value:" + p.getSpecialValue());
                System.out.println("------------------------");
            }
        }
    }



}
© www.soinside.com 2019 - 2024. All rights reserved.