抽象方法的不寻常行为

时间:2017-09-14 13:49:20

标签: java interface javac

我是一名java初学者,我正在学习使用接口。据我所知,实现接口的类必须给出其抽象方法的定义,如果它是一个具体的类。但我做了以下步骤,错误地说我得到了一个非常不寻常的行为。我就是这样做的。

首先,我创建了一个名为Printable的接口,并将其保存在Printable.java文件中:

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

然后我创建了两个实现Printable的ClassA和ClassB类,如下所示:

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");
    }
}

我创建了一个名为Test的测试类,如下所示:

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

我知道在编译上面的类时我会得到错误,因为我故意没有给出classess A和B中接口Printable的抽象方法show()的定义,我按如下方式编译了类:

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$ 

所以我想在Printable中评论方法show()的声明,然后我按照以下方式保存了文件:

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

现在重新编译时错误消失了,输出结果如下:

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$

这一切都很好,但现在我决定删除Printable中show()声明的注释并保存如下:

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

现在我重新编译它并希望再次获得错误但是这次重新编译时javac没有给出任何错误,但它应该给出错误,因为没有给出方法show()的实现。它成功编译如下:

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$ 

我无法理解为什么编译器没有再次出错,我确实在我做了任何改动之后保存了每个文件。请帮助,并对任何错误表示抱歉。

1 个答案:

答案 0 :(得分:3)

您每次只重新编译Test.java。如果您尝试重新编译所有内容,您将再次看到错误。

我不记得有关javac如何解决重新编译内容的详细信息 - 是否检查源文件时间戳和源文件时间戳,或者它是否仅编译 之后的代码类文件,而不是您指定的源文件。我不打算查阅,因为我不认为依赖它是个好主意:每次都重新编译所有内容。