java accidential implicit interface implementation - java

Recently came across an interesting feature, which, though, can result in a unexpected output of Eclipse "add unimplemented methods" feature. What is the "googl-able" name of the language concept behind this "occasional implicit implementation"?
I wouldn't expect the code below to compile but it did and is working
interface CallmeIfc {
public void callme();
}
class CallmeCode {
public void callme() {
// implementation
}
}
class CallmeImpl extends CallmeCode implements CallmeIfc {
// empty class body
}
public static void main(String[] args) {
CallmeIfc me = (CallmeIfc) new CallmeImpl();
me.callme(); // calls CallmeCode.callme()
}

In CallmeImpl, the public callme() method is inherited from CallmeCode, so CallmeImpl respects the contract defined in the CallmeIfc.
Then, in your main() method, polymorphism allows you to assign a subclass instance (CallmeImpl) to a superclass or superinterface reference - in this particular case, the "me" reference, of type CallmeIfc (you have a typo here, BTW).

Actually this looks like a compiler bug to me: The Java Language Specification writes:
An instance method m1 declared in a
class C overrides another instance
method, m2, declared in class A iff
all of the following are true:
C is a subclass of A.
The signature of m1 is a subsignature (§8.4.2) of the signature of m2.
Either
m2 is public, protected or declared with default access in the same package as C, or
m1 overrides a method m3, m3 distinct from m1, m3 distinct from m2, such that m3 overrides m2.
In your case, the first condition is not satisfied: The method callme is declared in class CallMeCode, which is not a subtype of CallmeIfc.
Edit: Bobah is right, the Spec distinguishes between implementing and overriding. In fact, it actually mandates the observed behaviour:
Unless the class being declared is
abstract, the declarations of all the
method members of each direct
superinterface must be implemented
either by a declaration in this class
or by an existing method declaration
inherited from the direct superclass,
because a class that is not abstract
is not permitted to have abstract
methods
The Spec does not explain why.

Although CallmeCode class doesn't implement the CallmeIfc interface, it provides the necessary implementation. It is as if class CallmeCode implements the interface. It would have worked also with this code:
interface CallmeIfc {
public void callme();
}
class CallmeCode implements CallmeIfc {
public void callme() {
// implementation
}
}
class CallmeImpl extends CallmeCode implements CallmeIfc {
// empty class body
}
In your case this is fine because class CallmeCode has a method callme. If the method would have been named different it wouldn't compile.

Related

Overriding abstract generic method in Java

Problem outline
I'm generifying the better part of my current project's base and I had an idea that I decided to test regarding overriding an abstract method. Here are my test classes in Java:
public abstract class Base {
public abstract <T extends Base> T test();
}
First implementation:
public class Inheritor extends Base {
#Override
public Inheritor test() {
return null;
}
}
Second implementation:
public class Inheritor2 extends Base {
#Override
public <T extends Base> T test() {
return null;
}
}
Question 1
Why does it compile? I admit I had high hopes it would be legal, since it makes the contract not only ensure it returns something that does extend Base, but is more specialized already (so that I don't need to cast the result to my specialized class somewhere later).
All sounds nice but do I really fulfill the contract that the base class forces me into? My overriden implementation in Inheritor loses certain layer of genericness doesn't it? My implementation of this method in Inheritor doesn't ever return an instance of Inheritor2, possibility of which the abstract method seemed to enforce (as both extend Base).
I would like pointing to some excerpt from documentation. My guess is it has something to do with type erasure, would be nice if someone mentioned it's accuracy in his/her answer.
Question 2
Does this procedure have a formal name other than one I stated in the title?
Question 3
Is this possible in C#? Colleague's scratch test seemed to fail on compilation. Is there then a difference in approach to generic abstract method overriding?
Here are the technicalities.
Concerning overriding:
An instance method mC declared in or inherited by class C, overrides
from C another method mA declared in class A, iff all of the following
are true:
A is a superclass of C.
C does not inherit mA.
The signature of mC is a subsignature (§8.4.2) of the signature of mA.
One of the following is true:
mA is public.
[...]
In your case, A is Base and C is Inheritor, Base#test() is mA and Inheritor#test() is mC.
mC is a subsignature of mA because
The signature of a method m1 is a subsignature of the signature of a
method m2 if either:
- m2 has the same signature as m1, or
- the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
The erasure of mA is
public abstract Base test()
and mC
public Inheritor test()
is a subsignature. What about the return type?
If a method declaration d1 with return type R1 overrides or hides the
declaration of another method d2 with return type R2, then d1 must be
return-type-substitutable (§8.4.5) for d2, or a compile-time error
occurs.
Following the return-type-substitutable, we see
If R1 is a reference type then one of the following is true:
R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9).
Inheritor is a subtype of T extends Base through unchecked conversion, so we're all good (though you should have gotten a warning from your compiler).
So to answer your questions:
It compiles because of the rules declared in the Java Language Specification.
It's called overriding.
I don't have a full answer for you, but C# doesn't seem to have type erasure, so these rules wouldn't apply.
The dangers of unchecked conversion would allow you to do
class Inheritor extends Base {
#Override
public Inheritor test() {
return new Inheritor();
}
}
and then
Base ref = new Inheritor();
Inheritor2 wrong = ref.<Inheritor2>test();
which would cause a ClassCastException at runtime. Use it at your own risk.
I can tell you why it should work - Liskov substitution principle
The question to ask is, if you replace Base with Inheritor, or Inheritor2, will all the consumers continue to work without negative consequences? If they expect anything that extends Base from test, then swapping Inheritor2 with Inheritor, or vice versa, will be fine from the perspective a consumer. So, the compiler ought to allow it.
You do really fulfill the contract, which says any subtype of Base can be returned. Any subtype can be one subtype, a random subtype, etc.
Like the commenter Elliott, I believe it's just called overriding a method.
Here's a similar implementation in C# but with generics on the class level.
public abstract class Base<Type>
where Type : Base<Type>
{
public abstract Type test();
}
public class Inheritor:Base<Inheritor>
{
public override Inheritor test()
{
return null;
}
}
public class Inheritor2<Type> : Base<Type>
where Type : Base<Type>
{
public override Type test()
{
return default(Type);
}
}

Using subclass' method in superclass

I have a class (called SubClass for simplicity) that extends SuperClass and implements IClass.
I know that you can call SuperClass' methods by using super.method(), but is it possible to call a method from SubClass which it implements from IClass?
Example:
public class SuperClass {
public void method(){
implementedMethod();
}
}
Subclass:
public class SubClass extends SuperClass implements IClass{
public void implementedMethod() {
System.out.println("Hello World");
}
}
IClass:
public interface IClass {
public void implementedMethod();
}
I would like to call SubClass' implementedMethod() (Which it gets from IClass) from SuperClass
How would I go about doing that?
You can make the super class abstract:
public abstract class SuperClass implements IClass {
public void method(){
implementedMethod();
}
}
Given the types above, anExpressionOfTypeSubClassOrIClass.implementedMethod() must be used. Note that the Type of an expression - the view it provides - must have the method intended to be used. In this case, an expression of type SuperClass cannot be used here because it has no declared implementedMethod member.
One approach - and arguably the preferred approach - is to use abstract methods. Even though abstract methods are not strictly required for Polymorphism they describe scenarios such as this where a subclass should provide the implementation. (The abstract methods could be replaced with empty method expecting - but not requiring - to be overridden in sublcasses, but why not use abstract for its designed purpose?)
abstract class SuperClass implements IClass {
// Don't implement this, but declare it abstract
// so that we can conform to IClass as well
public abstract void implementedMethod();
public void method () {
// Now this object (which conforms to IClass) has implementedMethod
// which will be implemented by a concrete subclass.
implementedMethod();
}
}
This has the "negative" aspects that SuperClass cannot be directly instantiated (it is abstract, after all) and that SuperClass must implement (or, as shown, delegate out via abstract) the expected signature. In this case I also chose to make SuperClass implement IClass even though it's not strictly required because it guarantees that the SuperClass and all subclasses can be viewed as an IClass.
Alternatively, remember that Types of Expressions are just views of objects and are not necessarily the same as the actual Concrete Type of object. While I would advise against using the following code because it loses some type-safety, I think it shows the important point.
class SuperClass {
public void method () {
// We try to cast and NARROW the type to a
// specific "view". This can fail which is one
// reason why it's not usually appropriate.
((IClass)this).implementedMethod();
}
}
class SubClass extends SuperClass implements IClass {
// ..
}
class BrokenSubClass extends SuperClass () {
}
// OK! Although it is the SAME OBJECT, the SuperClass
// method can "view" the current instance (this) as an IClass
// because SubClass implements IClass. This view must be
// explicitly request through a cast because SuperClass itself
// does not implement IClass or have a suitable method to override.
(new SubClass()).method();
// BAD! ClassCastException, BrokenSubClass cannot be "viewed" as IClass!
// But we didn't know until runtime due to lost type-safety.
(new BrokenSubClass()).method();
The only way to call that method would be to create an object of type SubClass (in SuperClass) and call subClassInstance.implementedMethod().
I also want to stress that this is very inelegant. As stated in a comment on your question, you should reconsider your class designs if your superclass needs to call a subclass method.

Overriding method

Class subA is the subclass of class A. I tried to override a method but Somehow it doesn't let me override it. why is that? Is it because of the argument in the parameter?
Error message read:
name clash: add(E#1) in subA and add(E#2) in A have the same erasure, yet neither overrides the other
where E#1,E#2 are type-variables:
E#1 extends Object declared in class subA
E#2 extends Object declared in class A
SuperClass A:
public class A <E> {
public void add(E toInsert) {...}
}
SubClass subA:
public class subA <E> extends A {
//overrides the method from A class
public void add (E toInsert) <-- doesn't let me overrides
{...}
}
You are subclassing the raw A class (generic parameters have not been provided), which by definition from the Java Language Specification strips all generic information from the superclass. This means that your subclass generic method is incompatible with the (now) non-generic superclass method.
Provide a generic parameter for A by passing through the generic parameter for your subclass:
public class subA <E extends Comparable<E>> extends A<E> {
#Override
public void add (E toInsert) {
// ...
}
}
Function Overriding in C++ Programming
If base class and derived class have member functions with same name and arguments. If you create an object of derived class and write code to access that member function then, the member function in derived class is only invoked, i.e., the member function of derived class overrides the member function of base class. This feature in C++ programming is known as function overriding.
Example to demonstrate function overriding in C++ programming
Accessing the Overridden Function in Base Class From Derived Class
To access the overridden function of base class from derived class, scope resolution operator ::. For example: If you want to access get_data() function of base class from derived class in above example then, the following statement is used in derived class.
A::get_data; // Calling get_data() of class A.
It is because, if the name of class is not specified, the compiler thinks get_data() function is calling itself.
User of scope resolution operator in overridden function
- See more at: http://www.programiz.com/cpp-programming/function-overriding#sthash.7UmWybpS.dpuf
public class subA <E extends A> extends A {
because E is defined in A you need to have your generic extend the same generic type of A is. I'm sure someone would have a better explanation than mine but I know this way works.

trying to understand implicit superinterfaces

Sorry to bring back the dead. But I still don't clearly understand what this section of specification states.
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.
Given
interface Testing
{
void test();
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Now as the spec states that the above will change to
interface Testing
{
void test();
String toString();
//other non-final methods of Object
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Also. please confirm if there is an hierarchy of interfaces then all of them get these abstract methods.
What it means is that every class extends Object (at some point in its class heirarchy). However, interfaces do not extend Object. This is to avoid the problems that arise from multiple inheirtance.
Since interfaces do not extend Object that would mean we were unable to use methods like toString if the type (not class) of the object we had access to was an interface. But we know those methods must be available since all classes at some point extend from Object. Therefore, to get around this problem all of Object's not final methods are implicitly declared in all interfaces that have no superinterfaces. These contracts of these methods are always satisfied since all classes must at some point extend from Object.
TL;DR -- it's a trick to make sure we can access the methods made available by Object when we have an instance of some class stored in variable that's type is an interface (eg. Serializable)
edit: To answer your question, You're slightly off. All non-final methods of Object are added to an interface (whether they are used or not) if that interface has no parent interface AND for each method to added: that there is no matching method is explicitly declared by the interface.
As long as there is no super interface to an interface it gets the implicit declaration of the Object class methods. As long as these methods are included in the interface. Every interface that either extends or implements this interface doesn't see much difference between the methods that are explicitly declared by this interface or it got implicitly. That point forward that interface is as good as declared them explicitly.

Redefining static method in child class

I would like to know the reason why this is first allowed in Java (or oops in general)
I remember that the static methods are common for both parent and child class
public class Redefine extends Parent{
public static void test () {
}
}
class Parent{
public static void test () {
}
}
Q1 : Since Overriding is not supported for static methods , how can both classe contain same methods ?
Q2 : If change the method in static to throw an exception not defined its not compiling.
why is the case. Its obviously not overriding so i should be allowed to throw new exceptions right ?
public class Redefine extends Parent{
public static void test () throws Exception{
}
}
A1:: static method are per-class. They have nothing to do with inheritance hierarchies in terms of polymorphism. So calling Parent.test() will call the parent method, while calling Redefine.test() will call the child.
A2: JLS 8.4.8 writes:
If a class declares a static method m, then the declaration m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the class.
A method declaration must not have a throws clause that conflicts (§8.4.6) with that of any method that it overrides or hides; otherwise, a compile-time error occurs.
you arent overriding it, you are hiding it
http://faq.javaranch.com/java/OverridingVsHiding
what exception are you getting?
Q1: Static methods are not overridden, so these are two different methods with the same signature. One is called with Parent.test(), the other is called with Redefine.test()
Q2: Your method seems valid. What error do you get?

Categories