Subclass with additional method in Java

2019-03-04 17:11发布

问题:

I have a problem with a subclass in Java. I have the following class:

MainIterator implements Iterator{
   //... Methods from the interface Iterator

   public void foo(){
      //Do something...
   }
}

and in my main class I call:

Iterator i = new MainIterator();
i.foo();

which does not work, because Iterator does not implement the function foo(). How is it possible to get this working without a typecast of i? i has to be from type Iterator.

回答1:

MainIterator i = new MainIterator();

The Java compiler only allows calling methods that belong to the declared type of the variable. If you use

Iterator i = new MainIterator();

you're telling the compiler: I create an instance of Iterator which is of type MainIterator, but you don't need to know about that in the rest of the code. Just consider this object as an instance of Iterator. And Iterator doesn't have any foo() method.



回答2:

You can declare your variable as MainIterator:

MainIterator i = new MainIterator();
i.foo();

Or you can cast:

Iterator i = new MainIterator();
((MainIterator) i).foo();

There are no other ways to do it.



回答3:

Iterator does not define foo() so you can not directly call foo() on a variable of type Iterator.

MainIterator defines foo() so you can call foo() on a variable of type MainIterator or a subtype.

You can cast a variable of type Iterator to MainIterator. There is really no other way around this. That is how it is supposed to work.



回答4:

If you are sure at the point where you are using i, that i is definitely of type MainIterator, it is alright to cast it. Also, if you are sure that you need a concrete MainIterator instance at this point, then you can simply type it as MainIterator i = new MainIterator(). For both cases it means that your design is tightly coupled to a particular implementation, which defeats the purpose of using an interface. So at this point I'd take a look at the design to make sure that happens where you are sure that all you need is an instance of MainIterator and no other instance.

If you must use Iterator but i can be any implementation of Iterator, you have a design problem because you are tightly coupled to a particular implementation (because you want to use the void foo method), but your code also wants to work with all implementations. This is a contradiction that you have to resolve, and it is hard to say how you can rectify it without looking at your overall design.