Unusual Behavior of Abstract Method

I am a java beginner and I was learning to use interfaces. As I have learned that the class which implements an interface must give definition of its abstract methods if it is a concrete class. But I did following steps and By mistake I got a really unusual behavior.Below is what I did.

Firstly I created an interface named Printable and saved it in file Printable.java:

public interface Printable{
    public void print();
    public void show();
    default void defaultMethod(){
        System.out.println("default method is called");
    }
}

Then I created two classes ClassA and ClassB that implement Printable as follows:

ClassA:

public class ClassA implements Printable{
    public ClassA(){
        System.out.println("object of class A is created");
    }
    public void print(){
        System.out.println("print called from class A");
    }
}

ClassB:

public class ClassB implements Printable{
    public ClassB(){
        System.out.println("Object of class B is created");
    }
    public void print(){
        System.out.println("print called from class B");
    }
}

I created a test class named Test as follows:

public class Test{
    public static void main(String args[]){
        ClassA a1 = new ClassA();
        a1.print();
        ClassB b1 = new ClassB();
        b1.print();
        a1.defaultMethod();
    }
}

I knew that on compiling the above class I will get errors because I purposely did not give definition of the abstract method show() of interface Printable in classess A and B and I compiled the class as follows:

harsh@harsh-Inspiron-3558:~/java/upload$ ls
ClassA.java  ClassB.java  Printable.java  Test.java
harsh@harsh-Inspiron-3558:~/java/upload$ javac Test.java 
./ClassA.java:1: error: ClassA is not abstract and does not override abstract method show() in Printable
public class ClassA implements Printable{
       ^
./ClassB.java:1: error: ClassB is not abstract and does not override abstract method show() in Printable
public class ClassB implements Printable{
       ^
2 errors
harsh@harsh-Inspiron-3558:~/java/upload$ 

So I thought to comment the declaration of method show() in Printable and I did that and saved the file as follows:

public interface Printable{
    public void print();
    //public void show();
    default void defaultMethod(){
        System.out.println("default method is called");
    }
}

and now on recompiling the errors were gone and the output was as follows:

harsh@harsh-Inspiron-3558:~/java/upload$ javac Test.java 
harsh@harsh-Inspiron-3558:~/java/upload$ ls
ClassA.class  ClassA.java  ClassB.class  ClassB.java  Printable.class  Printable.java  Test.class  Test.java
harsh@harsh-Inspiron-3558:~/java/upload$ java Test 
object of class A is created
print called from class A
Object of class B is created
print called from class B
default method is called
harsh@harsh-Inspiron-3558:~/java/upload$

It was all ok upto here, but now i decided to remove the comment of declaration of show() in Printable and saved it as follows:

public interface Printable{
    public void print();
    public void show();
    default void defaultMethod(){
        System.out.println("default method is called");
    }
}

Now I recompiled it and hoped to get the errors again but this time on recompilation javac did not gave any errors but it was supposed to give errors because of not giving implementation of method show(). It compiled successfull as follows:

harsh@harsh-Inspiron-3558:~/java/upload$ ls
ClassA.class  ClassA.java  ClassB.class  ClassB.java  Printable.class  Printable.java  Test.class  Test.java
harsh@harsh-Inspiron-3558:~/java/upload$ javac Test.java 
harsh@harsh-Inspiron-3558:~/java/upload$ java Test 
object of class A is created
print called from class A
Object of class B is created
print called from class B
default method is called
harsh@harsh-Inspiron-3558:~/java/upload$ 

I am not able to understand why the compiler did not gave errors again, I did saved each file after any alterations I did. Please help, and sorry for any mistakes.

Jon Skeet
people
quotationmark

You're only recompiling Test.java each time. If you try to recompile everything, you'll see the error again.

I don't honestly remember the details about how javac works out what to recompile - whether it checks source vs class file timestamps, or whether it only compiles code where there is no class file, other than the source files you specify. I'm not going to look it up, because I don't think it's a good idea to depend on that: just recompile everything each time.

people

See more on this question at Stackoverflow