简体   繁体   中英

How do I properly extend this abstract class?

Hi I'm inexperience with Java. I understand the concepts of inheritance but I think the syntax is eluding me. I'm seeking some help to get me started in extending this abstract class: I need to create a concrete object from it.

What this class should do is take in a type during initialization and store a list of objects of that type. Sort them and then return a list of n top objects when showTopN is called.

I have not started implementing the logic yet.

abstract class Foo<T extends Comparable<T>> {
    int n;

    Foo(int n){ // constructor; sets object property n
        this.n = n;
    }

    abstract void push(T object); //object method to store a new object in the list

    abstract List<T> showTopN(); // object method to return top n entries in the list, sorted.
}

I've tried to extend this into a concrete object this way:

class ConcreteFoo extends Foo {

        private List<Foo> fooList;

        public void push(Foo object) {

        }

        @Override
        public List<Foo> showTopN() {
            return fooList;
        }

        @Override
        public int compareTo(ConcreteFoo other) {
            return 0;
        }
}

But the compiler is complaining that I have not overridden the push method. What is wrong?

There are two things going on here. One is the "abstractness" of Foo, but the other is the Generics. You have neglected the generics aspect.

If you know the type of object that your Concrete foo cares about, you can just use that:

class ConcreteFoo extends Foo<SomeKnownClass> {
    private List<SomeKnownClass> list = new ArrayList<SomeKnownClass>();
    void push(SomeKnownClass skc) {}
    List<SomeKnownClass> showTopN() { return list; }
}

Now, if you don't know the type of it, you can still use generics:

class ConcreteFoo<T extends Comparable<T>> extends Foo<T> {
    private List<T> list = new ArrayList<T>();
    void push(T skc) {}
    List<T> showTopN() { return list; }
}

Note that neither Foo nor ConcreteFoo implement Comparable, so you don't need the compareTo method.

The push method specifies that it will accept a T object, which is Foo 's generic type, which you haven't declared. If you want Foo to be a List of itself, which I'm not certain that you do, you'd have to declare it as

 class ConcreteFoo extends Foo<Foo> {

But I think you need to re-examine your basic principles.

You're conflating a container with the objects that it contains. The class structure that you want is something like:

class Foo implements Comparable<Foo> { ... }

abstract class GenericContainer<T> {
    abstract void push(T object); //object method to store a new object in the list

    abstract List<T> showTopN(); // object method to return top k entries in the list, sorted.
}


class FooContainer extends GenericContainer<Foo> {
    private List<Foo> fooList;
    ...
}

Your showTopN method can then be something like:

public List<Foo> showTopN() {
    return Collections.sort(fooList).subList(0, n);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM