javaabstract

Using abstract method in non-abstract class


I got the abstract class ContentClass

public abstract class ContentClass
{
    public abstract String getClassType();
    public abstract String getSortId();
}

And the non abstract class Node

public class Node <ContentClass>
{
    private ContentClass content;
    private Node left;
    private Node right;

    public Node(Node l, Node r,ContentClass c)
    {
        content = c;
        left = l;
        right = r;
    }

    public String getNodeSortId(){
    return content.getSortId();
    }
    public String getNodeType(){
    return content.getClassType();
    }
    public ContentClass getContent(){
        return content;
    }

    public Node getLeft(){
        return left;
    }

    public Node getRight(){
        return right;
    }
}

The problem at hand being that content.getSortId() and content.getNodeType() are both marked as "undeclared method". How do I fix this and what did I do wrong?

I want to later on create non-abstract content classes that can contain different types of content and the class Node is supposed to be able to take in any contentclass as a variable


Solution

  • You have misunderstood how a generic type is declared for a class.

    public class Node <ContentClass> does not make use of the abstract class named ContentClass. That line is actually declaring a brand new generic type identifier, which you happened to name ContentClass. It has no relationship whatsoever to the abstract class named ContentClass.

    If you look at, say, List or Comparable, you will see that they declare their generic argument type using a single capital letter: List<E>, Comparable<T>. Nearly all Java SE classes use this convention, and for good reason: it greatly reduces the likelihood of making this kind of mistake.

    What you probably want is this:

    public class Node<C extends ContentClass>
    {
        private C content;
        private Node left;
        private Node right;
    
        public Node(Node l, Node r, C c)
        {
            content = c;
            left = l;
            right = r;
        }
    
        // ...
    
        public C getContent() {
            return content;
        }
    

    In the above code, C is the type argument. Because it was declared as a type which must inherit from ContentClass, any object of type C is guaranteed to have the getClassType() and getSortId() methods.

    Aside from the declaration of C, the name “ContentClass” should not appear anywhere in your Node class.