1

I'm trying to call a constructor for a generic abstract class within a method of said class. The code below shows this:

public abstract class Node<T> {
    public Collection <Node<T>> pars;   
    public Collection<Node<T>> interactors;
    private boolean target = false;
    private boolean multiple = false;
    private T value;

    //constructor for a simple node
    public Node(T val){
        this.value = val;
    }

    //constructor for a multiple interaction node
    public Node(Collection<Node<T>> inter, T val){
        this.interactors = inter;
        this.value = val;
        if (inter.size()>0){
            this.multiple = true;
        }
    }

    public void find_inters(){
        ArrayList<Collection<T>> multi_interactions = search();
        for (int i = 0; i < multi_interactions.size(); i++){
            Node<T> a = new Node<T>(multi_interactions.get(i), this.value);    <----i get compile error here
        }
    }
}

but I keep getting an error that I can't instantiate type Node. I want to create a new Node object within the function find_inters() but I can't. Anyone know why/possible solutions?

g00glechr0me
  • 365
  • 6
  • 19
  • If you need to instantiate the type, why make it `abstract`? – Sotirios Delimanolis Sep 21 '15 at 19:43
  • simple because there are other methods I cannot implement yet so I have to make them abstract. Will removing abstract allow me to instantiate a Node? (because I can always find a workaround for the abstract methods) – g00glechr0me Sep 21 '15 at 19:45
  • yes but you can't have unimplemented methods then. – zapl Sep 21 '15 at 19:46
  • I see, so is there another way I can have an unimplemented method? I could just write some garbage code in the method body and implement later but I'd like a better solution – g00glechr0me Sep 21 '15 at 19:48
  • [I don't think you understand what `abstract` classes are meant for.](http://stackoverflow.com/questions/13824142/what-are-abstract-classes-and-abstract-methods) – Sotirios Delimanolis Sep 21 '15 at 19:48
  • that's pretty true...I thought they were only so that I can define abstract methods. What else do they allow me to do? – g00glechr0me Sep 21 '15 at 19:49
  • @user3749778: An abstract class is a partial implementation that is meant to be designed and documented for inheritance. While you can instantiate a subclass of the parent abstract class, it doesn't make any sense to instantiate an abstract class because, by definition, it is not a complete implementation. – scottb Sep 21 '15 at 20:25
  • A best practice in a situation like this is to create an *interface* that defines the functionality and the contract of your type. Then you can create a *skeletal implementation* of your interface type using an abstract class which provides some (or even most) of the implementation of your type. Complete implementations extend your abstract class, but the *type* is provided by your interface. As a general rule, you want to avoid defining types with abstract classes. – scottb Sep 21 '15 at 20:29
  • _"I could just write some garbage code in the method body and implement later but I'd like a better solution"_ - This sounds like you're going to write methods for `Node` but simply haven't done so _yet_. That is different than _Node won't have methods but subclasses will_. If that's the case, simply don't declare Node as `abstract`, knowing that it's still in development... or implement stub methods you know you want, but have them do nothing for now. – Stephen P Sep 21 '15 at 22:14

2 Answers2

0

You've said that Node is abstract because you can't yet implement some of the methods, but the problem is that you want Node<T> a to be a Node object, but you have to decide what a will actually do when you call those methods.

You can have classes that don't have all their methods implemented -- that's how abstract classes work -- but you can't have objects that don't have all their methods implemented, because that object can have that method called, and your program needs to know what to do.

What you can do is write Node<T> a = new MySubNode<T>(...), where MySubNode is a subclass of Node with all the methods filled in. Or you can write Node<T> a = new Node<T>(...) { implementations of methods go here }, which is essentially the same thing, except the implementation is in an anonymous class. But you can't instantiate an abstract class.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • I see, this makes a lot of sense. But am I correct to say that the advantage of an abstract class is mainly to write abstract methods (or not write them)? – g00glechr0me Sep 21 '15 at 19:57
  • The point of an abstract class is to have non-abstract subclasses that actually fill in those methods, and in most cases, there will be multiple subclasses that fill in those methods in different ways. There might be some common functionality implemented in the abstract class, or a skeletal implementation that only needs a few parts filled in, but an abstract class without non-abstract implementations is pretty useless. – Louis Wasserman Sep 21 '15 at 19:59
0

Just to add to Louis's answer. If search() is abstract, you can change it to return ArrayList<Node<T>>, so the implementing classes can do something like Node<T> a = new MySubNode<T>(...) (unless search() is used somewhere else that requires ArrayList<Collection<T>>).

Peter L
  • 302
  • 1
  • 6
  • _"Just to add to Louis's answer"_ indicates this should be a comment on Louis' answer, not an answer of its own. – Stephen P Sep 21 '15 at 22:02
  • Yes, it should have been but I do not have enough reputation yet to comment (besides my own answers) and Louis's answer came while I was writing my own. – Peter L Sep 22 '15 at 15:52