简体   繁体   中英

java declare a method in a implementing class and not in the interface

First of all i have little experience in Java.

Getting to my question, I am implementing my own list with my own methods.

 public class MyList<E> implements List<E>{

 private Node<E> head;

 private static class Node<E> {
     private E element; 
     .....
 }

Now, there is a method in this class that compares this list with a given one:

public boolean equals(List<E> list){
....
}

To start this method, first we would have to get list's head, so afterward i can access element and compare the list.
Now, we don't have a getHead() method. So, we tried creating the following method in the implementing class

public Node<E> getHead(){    

The compiler does not find the symbol. Of course, we need to declare it first in the interface. The problem is, if we try to do it, interface does not know what Node is. So i am in a deadlock here.

I get the error:

  Cannot find symbol
  symbol  : method getHead()
  location: interface List<E>
    Node<E> lhead = list.getHead();

What i want it to make getHead a implementation-specific method. How do i do that?

I ask, can we move the internal class in the implementing to the interface? Have no idea how to solve this issue,

thanks for your time

Are you implementing java.util.List or some custom List interface you created? If you are using the standard class, of course you cannot modify core JDK class.

If you have a custom List interface, I see few issues:

  • Your equals() method should accept Object and downcast. Otherwise you are overloading instead of overriding :

     public boolean equals(Object obj) { //check type first List<E> list = (List<E>)obj; 
  • Node class is defined privately inside MyList . Put it in your List interface and it will be publicly accessible.

  • Finally typically you define equals() in terms of content, not the representation. You might have several List implementations and as long as they hold the same data in the same order, lists should be considered equal. In your implementation only lists using head abstraction are equal. Instead of relying on getHead() , use an iterator and compare the items one-by-one.

getHead() is an implementation-specific method, it doesn't belong in the interface. But this also means that you cannot use it as a part of an interface, and you have to call it as a method of the implementing class:

List<String> myList = new MyList<String>();
myList.getHead() // Wrong. Compiler error.

MyList<String> myList = new MyList<String>();
myList.getHead() // Works :)
List<String> asList = myList; // If you want to work with a List from now on

In your case, there's also the issue that equals needs to take an Object , which means that you need to do a type-check if you need to use implementation-specific (or even List -specific) methods:

public boolean equals(Object o)

    if (o == this)
        return true;

    if( o instanceof MyList<E> ){
        MyList<E> myList = (MyList<E>)o;
        // do MyList stuff here ...

    }
    // Things to do if you're comparing something that isn't a `MyList`
    // go here
}

Just out of curiosity, but your list class should have a int getSize() and E get(int index) method (this is usually available in a list). Now, you can just check if the size is equal, if so you can iterate over the list and compare element by element (using the E get(int index) method).

Edit: reference implementation

public boolean equals(List<E> other) {
    boolean equal = (getSize() == other.getSize());
    for(int i = 0; i < getSize() && equal; i++) {
        equal = get(i).equals(other.get(i));
    }
    return equal;
}

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