Interface does not see concrete implementation - java

I have
ISomeInterface
public interface ISomeInterface{
public void myMethod();
}
AbstractClass
public abstract class AbstractClass implements ISomeInterface{
public void myMethod(){
//...here goes implemetations
}
}
ConcreteClass
public class ConcreteClass extends AbstractClass {
//...
}
Compiler prints than ConcreteClass is not abstract and does not override abstract method myMethod in ISomeInterface.
The idea is to give implementation to one abstract class and then inherit it in classes that extend it.
I think that ConcreteClass should gets implementation form AbstractClass since it's extending it. Right? What's the matter?
UPDATE
I haven't noticed until now that method is wrong and it has to be myMethod. Anyways, same error.
UPDATE2
The problem was that in AbstractClass them method had correct name but incorrect signature. After changing it according with interface the problem was solved :)

In AbstractClass you are creating a method myMethod(), but your interface method method() is not being implemented in ConcreteClass. The names are different.

Assuming that your sample code is complete, you need to implement method from your interface. In AbstractClass you have called it myMethod instead.
You can use the #Override annotation on any override methods. This will tell you if you have used the wrong parameter types, method name, or an incompatible return type (parameters and return types don't have to be the same; they can, for example, be covariant).
Additionally, in Java, we don't tend to prefix interface names with I (unlike the convention in C#). Your interface would usually be called SomeInterface and not ISomeInterface.
Also, the public on methods on interfaces is implicit, so you can leave it out. If you do include it you should probably include the abstract as well to include all of the implicit modifiers.
An updated code sample would be:
public interface SomeInterface{
void method();
}
public abstract class AbstractClass implements SomeInterface {
#Override
public void method(){
//...here goes implemetations
}
}

You are probably overriding the wrong method. What happens is that you are probably attempting to override a method in your abstract class but what you are actually doing is to just define a new method with a new name. In the interface, the method is named method but in your abstract class your method is named myMethod.
So, check this out:
public abstract class AbstractClass implements ISomeInterface{
// Not the same name as in the interface
public void myMethod(){
//...here goes implemetations
}
}
In order to solve it, simply change the method name in the subclass to the correct name.
public abstract class AbstractClass implements ISomeInterface{
// Now you have the correct name and inheritance will
// work as expected
#Override
public void method(){
//...here goes implemetations
}
}
This is the perfect case for explaining the #Override annotation as well ;)
When overriding a method, you might want to use the #Override annotation that instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, then it will generate an error.
When you declare a method with the annotation #Override the overridden method must match the signature of the interface-method (or superclass method). Read more about #Override in the Oracle Docs.
And, if you are not trying to override the method named method in your abstract class you simply need to add that method to your concrete class like this:
public class ConcreteClass extends AbstractClass {
// Now we are implementing the correct method from the interface
// If not, there will be a compiler error.
#Override
public void method() {
}
//...
}
On a side note which may be relevant: methods can have the same name but with different argument lists. This is known as overloading (or overloaded methods) which you can read more about in this article.
Edit: Since the OP is using Java 5 this question may be interesting. The #Override annotation changed between Java 5 and Java 6. In Java 5 it was not allowed to use the #Override annotation when implementing a method from an interface, it was just allowed when overriding a method from a superclass.

Your interface defines
public void method();
but your abstract class has
public void myMethod(){
//...here goes implemetations
}
Which isn't the same! Add the Override annotation to catch that kind of issue at compile time.
#Override
public void myMethod(){ // <-- compile error.
//...here goes implemetations
}
From the linked Javadoc,
Indicates that a method declaration is intended to override a method declaration in a supertype.

Well the first thing that I notice is that your method is not named the same thing in the interface and the abstract class.

Related

Implementing and extending, Interface and Abstract class respectively with same method name in java

I am trying to understand how default methods deal with diamond problem in various scenarios. And, this is one of the scenario which I'm not able to understand.
Following is the description,
1. Interface with a default method method()
2. Abstract Class with a method method()
3. Concrete Class implementing the above interface and extending the abstract class.
interface Interface {
default void method() {
System.out.println("Interface method");
}
}
abstract class AbstractClass {
void method() {
System.out.println("Abstract class method");
}
}
// Concrete class definition first starts
public class ConcreteClass extends AbstractClass implements Interface {
#Override
public void method() {
super.method();
}
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition first ends
// Concrete class definition Second starts
public class ConcreteClass extends AbstractClass implements Interface {
public static void main(String[] args) {
Interface test = new ConcreteClass();
test.method();
}
}
// Concrete class definition Second ends
My queries,
1. Why does definition first always gives output as "Abstract class method" even when I use the Interface type for concrete class object?
2. Why definition second doesn't compile?
If compiler is using abstract class implementation in definition first, then it should be able to identify that it will always use Abstract class implementation in definition second.
This behavior is very confusing to me and any help is greatly appreciated.
Otherwise, the more I delve deeper into this, the more confusing it gets.
Edit 1 :
Compilation error in second definition is "The inherited method AbstractClass.method() cannot hide the public abstract method in Interface"
Default methods are just that: defaults. If there is an implementation, it will be used. If there isn't, the default will be used. There is no diamond problem here (there can be with multiple defaults, however).
1) Dynamic dispatch
2) The abstract class gives the method named method package-private access; the interface demands it be public.

Generic inheritance Issue

I have a couple interfaces to support our post processing of entities:
WorkFlowProcessor
public interface WorkFlowProcessor {
void PostProcess(List<WorkFlowStrategy> strategies);
}
WorkFlowAction
public class WorkFlowAction implements WorkFlowProcessor{
...
...
public void PostProcess(List<WorkFlowStrategy> strategies){
for(WorkFlowStrategy strategy : strategies){
strategy.process(this)
}
}
}
WorkFlowStrategy
public interface WorkFlowStrategy {
void process(WorkFlowProcessor itemToProcess);
}
TicketWorkFlowStrategy
public class TicketWorkFlowStrategy implements WorkFlowStrategy {
...
...
#Overried
public void process(WorkFlowAction action){ //must override or implement a supertype method
// do a lot of processing
}
}
I'm trying to figure out why I cannot get it to compile with the WorkFlowAction class. Normally this works just fine. Any thoughts on how I can get this to run correctly?
That's because you've got to declare it with the same signature as the method in the interface:
<T extends WorkFlowProcessor> void process(T itemToProcess)
Declaring the method like this in the interface doesn't mean you can specialize implementations of it for more specific parameters. This method has to accept any WorkflowProcessor.
Because of that fact, the type variable here is pretty useless: you may as well just declare it thus in the interface, which makes it cleaner to implement too:
void process(WorkflowProcessor itemToProcess);
Method-level type variables aren't actually useful unless you doing one or more of the following:
Returning the same type as a non-generic parameter
Constraining a generic parameter to be related either to another parameter or the return type.
If you want to specialize the process method for a particular subclass of WorkflowProcessor, you have to put this on the interface:
public interface WorkFlowStrategy<T extends WorkFlowProcessor> {
void process(T itemToProcess);
}
Then:
public class TicketWorkFlowStrategy implements WorkFlowStrategy<WorkflowAction> {
#Override
public void process(WorkFlowAction action){
// ...
}
}
The implication being made by the process method as defined in the WorkFlowStrategy interface is that implementations should be able to accept any WorkFlowProcessor as an argument to the method. The generic definition you added to this method does nothing to change this.
In your case, the generic definition probably belongs on the interface level, not on the method level. You can then be explicit about what types can be supported.

Inheritance type issue: is there a clean solution?

I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
#Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
#Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?
There are at least a few ways to deal with this circumstance and, really, the right one depends on your particular requirements.
Ask yourself, "are both operation1 and operation2 part of the contract specified by my type?"
If the answer is clearly no, then you should not pollute the contract of your type by adding collateral methods to it. You should next ask yourself, "why am I not using interfaces to specify separate types, eg.: instead of AbstractClass, why am I not using MyInterface1 and MyInterface2 (each with its own separate contract)? Interfaces provide a limited form of multiple inheritance, and your implementing classes can implement any and all interfaces that pertain to it. This is a strategy commonly used by the Java Platform Libraries. In this circumstance, explicit casting to the type whose contract you want to use is exactly the right thing to do.
If the answer is clearly yes, then you should have both methods in your type ... but you should still ask yourself, "why am I not specifying my type with an interface"? In general, you should specify types with interfaces rather than abstract classes, but there are reasons to use the latter.
If the answer is somewhere in between, then you can consider specifying optional methods in your type. These are methods which are included in the contract of your type, but which implementing classes are not required to implement. Before Java 8, each implementing type would need to throw a UnsupportedOperationException for any optional methods that it did not implement. In Java 8, you can do something like this for optional methods:
======
public interface MyType {
void contractOperation1();
default void optionalOperation2() {
throw new UnsupportedOperationException();
}
}
A class that implements this interface will need to provide an implementation for contractOperation1(). However, the class will not need to provide an implementation for optionalOperation2() and if this method is invoked on an implementing class that has provided no implementation of its own, then the exception is thrown by default.
abstract class don't have the object,we just create the reference of that class and use it.
like:
instead of this-
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
use this one
private AbstractClass classA;
private AbstractClass classB;
If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class. Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class.
more details are here:about abstraction instance

Same method in Interface and Abstract class

I came to situation :
public interface Intr {
public void m1();
}
public abstract class Abs {
public void m1() {
System.out.println("Abs.m1()");
}
// public abstract void m1();
}
public class A extends Abs implements Intr {
#Override
public void m1() {
// which method am I overriding, well it is Abs.m1() but why?
// if method implemented is Abs.m1(), then why I am not getting error for Intr.m1() not implemented.
}
}
You are satisfying both conditions at once; ie. the one implementation is at the same time fulfilling the abstract class requirements and the interface requirements.
As a note, unless you are using Intr in another inheritance chain, you don't need it. Also, it might make sense to move the implements Intr up to the abstract class definition.
You can only override methods defined in another class.
Methods declared in an interface are merely implemented. This distinction exists in Java to tackle the problem of multiple inheritance. A class can only extend one parent class, therefore any calls to super will be resolved without ambiguity. Classes however can implement several interfaces, which can all declare the same method. It's best to think of interfaces as a list of "must have"s: to qualify as a Comparable your cluss must have a compareTo() method but it doesn't matter where it came from or what other interfaces require that same method.
So technically you override Abs.m1() and implement Intr.m1() in one fell swoop.
Note that this would be fine too:
public class B extends Abs implements Intr {
//m1() is inherited from Abs, so there's no need to override it to satisfy the interface
}
Here, both the interface and abstract class have the same method.
You have one class with named Derived which extends an abstract class and implement an interface. It's true and you override print method on Derived class it's fine and it compiles correctly and does not give any error but here you can't identify which class method is overridden like abstract class or interface.
This is runtime polymorphism you can't create an instance of an abstract class or interface but you can create a reference variable of that type. Here the solution is you can't identify that on compile-time it's actually overridden at run time.
interface AnInterface
{
public void print();
}
abstract class Base
{
public abstract void print();
}
public class Derived extends Base implements AnInterface
{
public void print(){
System.out.println("hello");
}
AnInterface iRef = new Derived();
iRef.print(); // It means interface method is overridden and it's decided when we call the method.
Base base = new Derived();
base.print(); // It means abstract class method is overridden.
}
#Override ensures you override the method with no difference Interface or abstract superclass. So no error with override.
On the other hand Interface method is also implemented in the superclass which is enough for Interface contracts.

Overriding Object class methods within an interface in Java

Let's consider the following simple code in Java.
package temppkg;
interface Interface
{
#Override
public abstract boolean equals(java.lang.Object arg);
#Override
public abstract String toString();
public void show();
}
final class Demo implements Interface
{
public void show()
{
System.out.println("Method invoked.");
}
}
final public class Main
{
public static void main(String...args)
{
new Demo().show();
}
}
In the above code snippet, the interface named Interface has some Object class methods from JDK and they are with the #Override annotation even though they are abstract. Now, the class Demo has implemented Interface and has not implemented the equals() and the toString(); methods. Still the compiler doesn't complain and the program is running successfully. Why?
What is the relation between interfaces and the object class in Java?
The Java Language Specification clearly says that the members of an
interface are those which are declared in the interface and those
which are inherited from direct super interfaces. If an interface has
no direct superinterface then the interface implicitly declares a
public abstract member method corresponding to each public instance
method declared in the Object class, unless a method with the same
signature, same return type, and a compatible throws clause is
explicitly declared by that interface. This is what makes the
signatures of the Object methods available to the compiler and the
code compiles without any error. Remember if the interface tries to
declare a public instance method declared 'final' in the Object class
then it'll result into a compile-time error. For example, 'public
final Class getClass()' is a public instance method declared 'final'
in the Object class and therefore if an interface tries to declare a
method with this signature then the compilation will fail.
http://geekexplains.blogspot.com/2008/06/do-interfaces-really-inherit-from-class.html
Check out JLS 9.2:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
In other words, every interface implicitly defines each of Object's methods, and you can therefore #Override those methods. The other methods aren't defined in Object, so you can't override them.
In Interface you're not actually overriding anything - an interface by definition can not provide implementations for any of its methods. The class Demo just inherits the equals and toString implementation from Object.
In essence an interface in Java contains a set of zero or more method signatures (all of them are implicitly abstract, in your code you made it explicit by adding the keyword abstract), and the concrete classes that implement the interface must provide an implementation for those methods. In the case of your code, that implementation comes from Object, since all the classes implicitly extend Object, which provides default implementations for equals and toString (among other methods).
You really shouldn't mark the methods in an interface with #Override, as you have seen, it's confusing and serves for no practical purpose. Instead, use #Override in the methods in the concrete class that implement the methods of the interface, like this:
class Demo implements Interface {
#Override
public void show() {
System.out.println("Method invoked.");
}
}
Also, it's completely unnecessary to declare equals and toString in an interface, so you're better off with this definition:
interface Interface {
public void show();
}
#Override can only be used for functions defined in the base class, Object. Object defines equals and toString, so you can use #Override with them, but not with, say, the function show. It indicates a relationship between the #Override functions in a class and its base classes, not it's derived classes.

Categories

Resources