1

Below is the base class relevant code DblyLinkList, complete code for DblyLinkList class here,

package JavaCollections.list;

public class DblyLinkList<T> implements Iterable<T>{

   protected DListNode<T> sentinel;
   protected int size;

   class DListNode<T> {
       private T item;
       private DListNode<T> prev;
       private DListNode<T> next;

       DListNode(T item, DListNode<T> p, DListNode<T> n) {
           this.item = item;
           this.prev = p;
           this.next = n;
        }
    }

    DListNode<T> newNode(T item, DListNode<T> prev, DListNode<T> next) {
       return new DListNode(item, prev, next);
    }

    public DblyLinkList() {
       this.sentinel = this.newNode(null, this.sentinel, this.sentinel);
    }

    .........
}

Below is the class LockableList introduced in same package, that sets the lock field as false for every node creation. To remove LockableNode node, remove() method will check the value of lock field.

On calling super(item, p, n);, Error: The constructor DblyLinkList<T>.DListNode<T>(T, DblyLinkList<T>.DListNode<T>, DblyLinkList<T>.DListNode<T>) is undefined

How do I write a constructor in below derived class LockableList.LockableNode that can be called by overridden method newNode?

package JavaCollections.list;

import JavaCollections.list.DblyLinkList.DListNode;

public class LockableList<T> extends DblyLinkList<T> {

    class LockableNode<T> extends DListNode<T>{
        /**
         * Do not lock the node during creation of a node.
         */
        private boolean lock; 

        LockableNode(T item, DblyLinkList<T>.DListNode<T> p,
                        DblyLinkList<T>.DListNode<T> n) {
            super(item, p, n); //this does not work
            this.lock = false;
        }
    }

    @Override
    LockableNode<T> newNode(T item, DListNode<T> prev, DListNode<T> next) {
        //return new LockableNode(item, prev, next); //How do i call the constructor?
    }

    public LockableList(){
        this.sentinel = this.newNode(null, this.sentinel, this.sentinel);
    }

    ........
}

Note: It is an exercise for inheritance and encapsulation

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 1
    try the following: `class LockableNode extends DblyLinkList.DListNode { ...` – A4L Aug 28 '15 at 10:14
  • It would help if you described the problem more specifically than 'this does not work'. Does your compiler/IDE report provide an error message? It is runtime behavior that doesn't work as you expect? – dsh Aug 28 '15 at 12:35
  • @A4L As you said, I made changes it is working. why is it working? – overexchange Aug 31 '15 at 07:44
  • @overexchange the problem is that both of your inner classes are not defined as `static` which means they can only exist within the context of the outer class, so in order to reference such a class you need specify its full name, i.e. including the name of the parent class `DblyLinkList.DListNode`. But this does not make much sence, they should be declare as `static` because you don't want and need to create an instace of the outer class in order to have a node instance. So you can add `static` to the declaration of your inner classes and keep the `extends` like you had it before. – A4L Sep 02 '15 at 13:37
  • @A4L `static class DListNode`? `static class LockableNode`? I did not get you. How would I write code like `return new DListNode(item, prev, next);` and `return new LockableNode(item, prev, next);`? I think the actual reason/fix is [here](http://stackoverflow.com/a/32306804/3317808) – overexchange Sep 02 '15 at 13:48
  • @overexchange exactly. You won't have to change any thing in that code, plus why would you need such code? just use the constructors diretly, since they are static now there is no need for an enclosing instance. – A4L Sep 02 '15 at 13:54
  • @A4L I see similar idea here: `static class Node implements Map.Entry{..}`. How would one call the constructor within this static class `Node`? because static classes are not instantiable – overexchange Sep 03 '15 at 03:56
  • @overexchange sure you can please read this [answer](http://stackoverflow.com/a/7486051/1113392) and also follow th link in it. – A4L Sep 03 '15 at 08:05

2 Answers2

0

You didn't give to contstructor an acces level, then by default:

Modifier    Class   Package     Subclass    World
no modifier     Y         Y            N        N

This is known as package-private, and this constructor is not accessible for inner subclasses even if they are in same package. This happens because is an inner class, so even if the subclass can access to super(), the inner class doesn't.

So :

public class LockableList<T> extends DblyLinkList<T> {

    LockableList() {
        super();  //this work
    }

    class LockableNode<T> extends DListNode<T>{
        LockableNode(T item, DblyLinkList<T>.DListNode<T> p, DblyLinkList<T>.DListNode<T> n) {
        super(item, p, n); //this does not work
    }
}

If you declare the constructor of DblyLinkListpublic or protected will be accessible from inner class.

protected DListNode<T> newNode(T item, DListNode<T> prev, DListNode<T> next) {
    return new DListNode(item, prev, next);
}

Modifier    Class   Package     Subclass    World
public          Y         Y            Y        Y
protected       Y         Y            Y        N

Check also this question for clarification about access levels in Java

Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • adding how many extra lines of code @RobbyCornelissen ? because your sollution doesn't work by itself.... – Jordi Castilla Aug 28 '15 at 10:11
  • 2
    The problem is unrelated to the access modifiers. It's the type parameters that are being shadowed. – Robby Cornelissen Aug 28 '15 at 10:15
  • 1
    @RobbyCornelissen Firstly make sure that all the access levels and design of `DblyLinkList` class is fine. Am pasting the link for `DblyLinkList` class in query. I already reviewed `DblyLinkList` class on codereview.SE – overexchange Aug 28 '15 at 10:21
0

try this:

LockableNode(T item, DListNode<T> p,
            DListNode<T> n) {
        super(item, p, n);
        this.lock = false;
}
seneque
  • 279
  • 1
  • 5