简体   繁体   中英

In Java, how can I implement new functionality in a subclass of a Deque class without access to the private fields in the Deque class?

I'm doing an assignment for my data structures course, and I need to know if it's possible to write an enqueueAtFront() method in LinkedOutputRestrictedDeque, a subclass of LinkedQueue, without changing the fields of LinkedQueue to protected rather than private.

So, here is the problem statement:

An output-restricted double-ended queue supports insertions from both ends, but accesses and deletions only from the front. You will develop a singly linked implementation of an output-restricted double-ended queue.

You will extend the provided QueueADT interface with a new interface called OutputRestrictedDequeADT which will declare one new operation:

void enqueueAtFront(E theElement);

You will develop a new class called LinkedOutputRestrictedDeque. This class will extend the provided LinkedQueue class and will implement the OutputRestrictedDequeADT interface.

If you make ANY changes to the LinkedQueue class then you MUST list these changes (and your reasons for these changes) in your executive summary.

So really, all I really need to do is write the enqueueAtFront() method, and I am technically allowed to make changes to LinkedQueue, but I want to know if it's possible to achieve this without changing LinkedQueue's fields to protected. Here is the code of LinkedQueue if necessary:

/*
 * TCSS 342
 */

package structures;

import exceptions.EmptyCollectionException;

/**
 * A singly-linked implementation of the QueueADT.
 * 
 * @author Alan Fowler - An adaptation of code from several textbooks
 * @version 1.1
 *
 * @param <E>
 */
public class LinkedQueue<E> implements QueueADT<E> {

    /**
     * The number of elements contained in the queue.
     */
    private int mySize;

    /**
     * A reference to the first node in the queue.
     * (The 'head' of the queue.)
     */
    private Node<E> myFront;

    /**
     * A reference to the last node in the queue.
     * (The 'tail' of the queue.)
     */
    private Node<E> myRear;

    /**
     * Initialize an empty queue.
     */
    public LinkedQueue() {
        mySize = 0;
        myFront = null;
        myRear = null;
    }

    @Override
    public void enqueue(final E theElement) {
        if (mySize == 0) { // Make a queue of one element
            myFront = new Node<E>(theElement);
            myRear = myFront;
        } else { // Regular case
            myRear.myNext = new Node<E>(theElement);
            myRear = myRear.myNext;
        }
        mySize++;
    }


    @Override
    public E dequeue() {
        if (mySize == 0) {
            throw new EmptyCollectionException("queue");
        }

        final E returnValue = myFront.myData;
        myFront = myFront.myNext;
        mySize--;
        return returnValue;
    }


    @Override
    public E first() {
        if (mySize == 0) {
            throw new EmptyCollectionException("queue");
        }
        return myFront.myData;
    }

    @Override
    public int size() {
        return mySize;
    }

    @Override
    public boolean isEmpty() {
        return mySize == 0;
    }

    /**
     * The returned String lists each element in the queue and includes a label for
     * the front of the queue.
     * 
     * <p>The format of the returned String is:
     * Front -> 8, 6, 7, 5, 3, 0, 9
     */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        if (mySize > 0) {
            sb.append("front -> ");
            Node<E> temp = myFront;
            for (int i = 0; i < mySize - 1; i++) {
                sb.append(temp.myData);
                sb.append(", ");
                temp = temp.myNext;
            }
            sb.append(temp.myData);
        }
        return sb.toString();
    }




    // Inner Node class

    /**
     * Represents a node in a singly linked structure.
     * 
     * @author Alan Fowler - An adaptation of code from several textbooks
     * @version 1.1
     *
     * @param <T>
     */
    public class Node<T> {

        /**
         * A reference to the next node in the liked structure.
         */
        private Node<T> myNext;

        /**
         * A reference to the data element held in this node.
         */
        private T myData;

        /**
         * Initialize the node using the specified data element.
         * 
         * @param theData the data element held in this node
         */
        Node(final T theData) {
            this(theData, null);
        }

        /**
         * Initialize the node using the specified data element and
         * the specified next node.
         * 
         * @param theData the data element held in this node
         * @param theNext the next node in the linked structure
         */
        Node(final T theData, final Node<T> theNext) {
            myData = theData;
            myNext = theNext;
        }
    }


}

Do I need to change the fields to protected or make getters/setters, or am I missing some obvious solution? I'm obviously fairly new to this stuff. I just don't want to ruin the encapsulation if I don't have to.

If you are allowed to make changes to LinkedQueue , you better add some method to it. For example, you can add protected method enqueueAtFront to LinkedQueue , and make it public in new class. It will do less damage to encapsulation.

Making fields protected will expose them to any subclass of your class. Some wrong code may break class contract. For example, someone may forget to update field mySize . When you add protected methods you keep you fields safe, allowing only limited set of operations.

No. Inheritance rules are explicit here; if you want a subclass to have access to the parent's fields, they must be at least in protected visibility.

It also makes sense; a private field would indicate that this information is explicit and exclusive to the parent, whereas a protected field indicates that this information can be used by the parent class and its children, which is what you want to accomplish.

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