• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

narrowing of type and interfaces

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Consider the following situation:
----------------
interface A{
void a();
}
----------------
interface B{
void b(A av);
}
----------------
class myA implements A
{
public void a() {

}
}
-----------------------

class myB implements B{

public void b(myA av) {


}
------------------
The last class doesn't complie. It gives me this error:
myB is not abstract and does not override abstract method b(A) in B


The problem is myA is of type A since it's implementing interface A, so I guess there shouldn't be the error theoretically. or is it a bug with JDK compiler? I'm using JDK 1.6.0_02.
[ December 15, 2007: Message edited by: Joe Khan ]
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The compiler is pretty picky when matching signatures. Your myA class is indeed an A, but it's a special kind of A. Other users of myB would see implements B and expect to call your method with any implementation of A. The compiler requires you to accept any kind of A, not just myA.

Experiment with making the myA method use A or a supertype of A, say Object. Do any of those work better? Do they make sense?
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is not a compiler error, and it's correct that you get an error message here. If a non-abstract class implements an interface, then it must provide implementations for all methods in the interface with the correct method signature (method name and argument types). You cannot implement an interface and change the method signature by changing the type of the arguments. I'll try to explain why.

Suppose you declare a variable 'obj' like this:

B obj = new myB();

And now you want to call the method 'b' on 'obj'. Since the type of 'obj' is B, the compiler will check if the arguments you pass to method 'b' are of the type as specified in interface B. According to interface B, you can pass anything that implements A to the method. But your class myB has more strict requirements; it requires that the argument is an instance of myA or of a subclass of myA.

The compiler can't be sure at compile time that 'obj' refers to a myB, and so it cannot check the more strict requirement.

You might now ask "Why can't the compiler check that 'obj' refers to a myB? The compiler knows that if I do B obj = new myB();, doesn't it?".

In this case the compiler maybe could have known it, but that's not so in the more general case. You could for example have instantiated a class via reflection:

Class cls = new Class("myB");
B obj = cls.newInstance();


If you do that, there's no way the compiler could have known at compile-time to what kind of object 'obj' refers at runtime.
[ December 15, 2007: Message edited by: Jesper Young ]
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In short, being able to do that would violate Liskov's Substitution Principle: http://en.wikipedia.org/wiki/Liskov_substitution_principle
 
Joe Khan
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey thanks you guys for responses.
According to Ilja
(1)A is not substitutable by myA(A is a super type not a sub type of myA).
(2)myA is substitutable by A(myA is a sub type of A).

I tried to test second rule of substitution. Here's the code:

interface A{
void a();
}
-----------------
class myA implements A
{
public void a() {}

}
-----------------------
interface B{
void b(myA a);
}
--------------------------
class myB implements B{


public void b(A a) {


}
}

The news is I'm still having the error:
myB is not abstract and does not override abstract method b(myA) in B
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Joe]: The news is I'm still having the error:
myB is not abstract and does not override abstract method b(myA) in B


If you look carefully, that's a slightly different error than your original one. And like the first error, it tells you exactly what is wrong with the current code. Quite simply, if you need to override b(myA), then b(A) is not close enough. (And vice versa, in the original problem.) To override a method, you need to use the exact same parameter types, period. (Well, it gets more complicated if generics are involved, but that's not relevant here.) If you change the parameter types - even if the ypes are related - you will get errors. So, don't change the parameter types.
 
Joe Khan
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh yea Jim, you are right..
sorry I missed that overriding stuff.
There's no such thing auto-conversion with method overriding . The return type and arguments list have to be exactly same.
Auto-conversion only occurs on assignements or on method calls with arugments.
Thank you all for replies.

[ December 17, 2007: Message edited by: Joe Khan ]
[ December 17, 2007: Message edited by: Joe Khan ]
 
Quick! Before anybody notices! Cover it up with this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic