有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何使类的子类返回正确的Java类型

我有一个类,其方法返回该类的对象列表:

public class Parent {
    public static List<Parent> all_possible(int i) {
        //...
    }

    //other methods
}

我试图创建一个也有这个方法的子类,除了它返回子类的列表。 对于上面的代码,我必须为子类重写它,因为类型错误:

public class Child extends Parent {
    public static List<Child> all_possible(int i) {
        //same thing as above except different type
    }
    
    //child methods
}

是否有可能以这样的方式编写该类,以便从该类继承的所有子类都使用正确的类型? 还是有更好的方法

另外,是否可能有类似改变类型的变量?例如:

public class Parent {
    public static List<Parent> objects;
}
//...
public class Child extends Parent {
    public static List<Child> objects;
}

提前谢谢

编辑: Thisstackoverflow post解释了如何使用实例方法,但没有解释如何使用静态方法或静态变量

显然这是不可能的,那么我应该使用什么替代方案呢


共 (2) 个答案

  1. # 1 楼答案

    before所述,静态方法不能被重写,但子类实现隐藏了超类实现,也就是说,仅当从Child类的引用调用时,才会调用子类的静态方法

    示例代码:

        static class Parent {
            static List<Parent> objects = new ArrayList<>();
            final String name; 
    
            public Parent(String name) {
                this.name = name;
                Parent.objects.add(this);
            }
            
            @Override
            public String toString() {
                return name;
            }
            
            static List<? extends Parent> all() {
                return new ArrayList<>(Parent.objects);
            }
            
            public List<? extends Parent> allPossible(int i) {
                return new ArrayList<>(Arrays.asList(new Parent("instance.parent.1"), new Parent("instance.parent.2")));
            }
        }
    
        static class Child extends Parent {
            static List<Child> objects = new ArrayList<>();
            
            static List<Child> all() {
                return new ArrayList<>(Child.objects); 
            }
            
            public Child(String name) {
                super(name);
                Child.objects.add(this);
            }
            
            @Override
            public List<Child> allPossible(int i) {
                return new ArrayList<>(Arrays.asList(new Child("instance.child.1")));
            }
        }
    

    测试:

    System.out.println("instance");
    Parent p = new Parent("main.p");
    Parent c = new Child("main.c");  // Child instance referenced by Parent variable
    
    System.out.println(p.allPossible(2));
    System.out.println(c.allPossible(2));
    System.out.println("static");
    System.out.println("p.all: " + p.all());
    System.out.println("c.all: " + c.all());
    System.out.println("Child.all: " + Child.all());
    System.out.println("\nobjects");
    System.out.println("p.objects: " + p.objects);
    System.out.println("c.objects: " + c.objects);
    System.out.println("Child.objects: " + Child.objects);
    

    输出:

    instance
    [instance.parent.1, instance.parent.2]
    [instance.child.1]
    static
    p.all: [main.p, main.c, instance.parent.1, instance.parent.2, instance.child.1]
    c.all: [main.p, main.c, instance.parent.1, instance.parent.2, instance.child.1]
    Child.all: [main.c, instance.child.1]
    
    objects
    p.objects: [main.p, main.c, instance.parent.1, instance.parent.2, instance.child.1]
    c.objects: [main.p, main.c, instance.parent.1, instance.parent.2, instance.child.1]
    Child.objects: [main.c, instance.child.1]
    
  2. # 2 楼答案

    在做了一些测试之后,我做了一个半解

    我把静态变量objects变成了HashMap<Type, ArrayList<Parent>>

    然后,当我得到所有对象的列表时,我访问带有子对象类型的objects

    代码:

    class Parent {
        private static Map<Type, List<Parent>> objects = new HashMap<>();
        public static List<Parent> all(Class c) {
            //...
            return objects.get(c);
        }
        public static List<Parent> all() {
            return all(Parent.class);
        }
        //...
    }
    
    class Child {
        public static List<Child> getAll() {
            return (List<Child>)(List<?>)getAll(Child.class);
        }
        //...
    }
    

    这不是一个完美的解决方案,因为我仍然需要在每个子类中编写一些代码,但这是我能找到的最好的解决方案