实现通用接口的Java通用类

时间:2018-02-08 22:31:03

标签: java generics inheritance

最初我想创建一种深层复制实现'X'接口的对象的通用方法。但是,我不想为每个实现'X'的类编写一个复制列表函数。相反,我创建了一个泛型类,它通过接口'X'绑定它的泛型。

问题在于,如果类'A'实现'X'并且包含(do)/(不)实现'X'的子类。如何阻止子类继承'X'的'A'实现并强制执行它们自己的实现,而不必为每个子类实现'X.

我很确定在java中这是不可能的,因为继承和泛型。

这是迄今为止的实现,但是我需要一个类型转换,它为不继承接口'X'的子类带来不安全的操作。

import java.util.*;


public class HelloWorld {

    public static void main(String[] args) {
    // Prints "Hello, World" to the terminal window.
    System.out.println("Hello, World");

    List<Foo> l = new ArrayList<Foo>();
    List<Bar> b = new ArrayList<Bar>();
    List<Nar> n = new ArrayList<Nar>();

    GenericCopyClass<Foo> g = new GenericCopyClass<Foo>();
    GenericCopyClass<Bar> gb = new GenericCopyClass<Bar>();
    GenericCopyClass<Nar> gn = new GenericCopyClass<Nar>();


    l.add(new Foo());
    l.add(new Foo());
    l.add(new Foo());


    b.add(new Bar());
    b.add(new Bar());
    b.add(new Bar());

    n.add(new Nar());
    n.add(new Nar());
    n.add(new Nar());


    //prints FOO
    List<Foo> foo = g.copyList(l);

    //prints BAR
    List<Bar> bar = gb.copyList(b);

    //prints FOO
    List<Nar> nar = gn.copyList(n);

    /* Is there a clean way to prevent a typecast of Foo to Nar using generics*/

    }

}

class Foo implements WantToClone{
    public Foo(){}
    private Foo(int i){
    System.out.println("Foo");
    }
    public Foo instance(){
    return new Foo(1);
    }
}

class Bar extends Foo{
    public Bar(){} 

    private Bar(int i){
    System.out.println("Bar");
    }
    public Bar instance(){
    return new Bar(1);
    }
}

class Nar extends Foo{
    public Nar(){} 

}

interface WantToClone<E extends WantToClone<E>>{
    public E instance();
}


class GenericCopyClass<S extends WantToClone>{

    public GenericCopyClass(){}

    public List<S> copyList(List<S> original){
        List<S> temp = new ArrayList<S>();

        for(S item : original){
            temp.add((S)item.instance());   
        }
        return original;
    }

}

输出如下:

Hello, World
Foo
Foo
Foo
Bar
Bar
Bar
Foo
Foo
Foo

*编辑1

问题:

隐式类型转换:

temp.add((S)item.instance());

接口未明确指定类实例:

interface WantToClone<E extends WantToClone<E>>

1 个答案:

答案 0 :(得分:1)

我会使用包含所有常用方法的参数化抽象类,并让子类仅实现instance方法:

    public abstract class AbstractFoo< F extends AbstractFoo<F> > 
    implements WantToClone<F>{

        public AbstractFoo(){}

        //add common methods here
    }

    public class Foo extends AbstractFoo<Foo>{
        public Foo(){}

        private Foo(int i){
            System.out.println("Foo");
        }

        public Foo instance(){
            return new Foo(1);
        }
    }

    public class Bar extends AbstractFoo<Bar>{
        public Bar(){} 

        private Bar(int i){
            System.out.println("Bar");
        }

        public Bar instance(){
            return new Bar(1);
        }
    }

    public class Nar extends AbstractFoo<Nar>{
        public Nar(){}

        @Override
        public Nar instance() {
            return new Nar();
        } 

    }

    public interface WantToClone< E extends WantToClone<E> >{
        public E instance();
    }


    public class GenericCopyClass< S extends WantToClone<S> >{

        public GenericCopyClass(){}

        public List<S> copyList(List<S> original){
            List<S> temp = new ArrayList<S>();

            for(S item : original){
                temp.add( item.instance() );   
            }
            return original;
        }    
    }