【问题标题】:An abstract class in Java need not implement any methods from its implementing interface. Why?Java 中的抽象类不需要从其实现接口实现任何方法。为什么?
【发布时间】:2011-12-23 00:26:06
【问题描述】:

我们看下面的Java简单代码sn-p。

interface Sum
{
    abstract public void showSum();
}

interface Mul
{
    abstract public void showMul();
}

abstract class Super implements Sum
{
    protected int x;
    protected int y;

    public Super(int x, int y)
    {
        this.x=x;
        this.y=y;
    }

    //No error, though the method showSum() of the implementing iterface Sum is commented. Why?

    /*public void showSum()
    {
        System.out.println("Sum = "+(x+y));
    }*/
}

final class Calculation extends Super implements Mul
{
    public Calculation(int x, int y)
    {
        super(x,y);
    }

    public void showSum()
    {
        System.out.println("Summation = "+(x+y));
    }

    //If showMul() is commented , it would issue a compile-time error. Why?
    public void showMul()
    {
        System.out.println("Multiplication = "+(x*y));
    }   
}

final public class Main
{
    public static void main(String[] args) throws IOException
    {
        Scanner s=new Scanner(System.in);

        System.out.print("\nEnter a number : ");
        int x=s.nextInt();

        System.out.print("\nEnter another number : ");
        int y=s.nextInt();

        Calculation c=new Calculation(x,y);
        c.showSum();
        c.showMul();
    }
}

由于接口 Sum 只包含一个方法 showSum(); 正在由抽象类 Super 实现,因此抽象类 Super 来实现该方法showSum();。然而,编译器根本没有抱怨,程序运行良好,完全没有问题。为什么?


同样,非抽象最终类 Calculation 正在实现 Mul 接口,并包含其实现接口中提供的方法showMul(); 的实际实现。如果在类 Calculation 中这个方法 showMul() 被注释,它会发出编译时错误。为什么同样的事情不适用于那个抽象类Super

【问题讨论】:

标签: java


【解决方案1】:

abstract 类不是真正的实现类。它可能包含abstract 方法,不需要implement 来自interface 的方法。定义抽象/接口方法是 REAL 实现类的关注点。

看看抽象类和接口的区别

Interface:
public interface InterfaceClass {
    void interfaceMethod();
    //no method definition
}


//Abstract Class implementing InterfaceClass
abstract class AbsClass implements InterfaceClass{
    abstract void abstractMethod();
    public void doSomethingCommon() {
        System.out.println("Abstract class may contain method definition");
    }
    //no need to implement methods of InterfaceClass because AbsClass is abstract
}

这是扩展AbsClass的真实类:RealClass的职责是定义所有抽象方法和接口方法。此外,它可以overrideabstract类中定义的方法作为好吧。

public class RealClass extends AbsClass{
    @Override
    public void interfaceMethod() {
        //implement interface method here
    }
    @Override
    void abstractMethod() {
    }
    // you may override the doSomethingCommon() of AbsClass too
    @Override
    public void doSomethingCommon() {
        // TODO Auto-generated method stub
        super.doSomethingCommon();
    }
}

为什么AbsClass没有编译时错误: 我们不能创建抽象类的实例。这就是为什么在编译时显示错误没有任何意义。

【讨论】:

    【解决方案2】:

    在这种情况下,抽象类的行为类似于接口。

    来自Java Tutorial...抽象类类似于接口,只是它们提供了部分实现,将其留给子类来完成实现。如果抽象类只包含抽象方法声明,则应将其声明为接口

    您不会在扩展另一个接口的接口中实现方法。而且您不必在实现接口的抽象类中实现方法。

    【讨论】:

      【解决方案3】:

      因为它是抽象的。抽象类是允许声明一些方法而不提供这些方法的任何实现的类,强制具体子类这样做。你可以添加方法

      @Override
      public abstract void showSum();
      

      到抽象类,但是对于已经在接口中声明的方法,它只是多余的。

      【讨论】:

        【解决方案4】:

        这应该是对 JB Nizet 的回答的评论,但我还不能发布 cmets :( 请注意,您可以在抽象类中提供 showSum() 方法的实现,并且仍然让该类保持抽象而没有任何问题。抽象类可以实现所有方法并且仍然是抽象的!

        【讨论】:

          【解决方案5】:

          来自 Oracle 的 Java 教程:

          实现接口的类必须实现所有 接口的方法。但是,可以定义一个类 不实现接口的所有方法,前提是 类被声明为抽象类。

          参考文档:https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html当抽象类实现接口时部分。

          【讨论】:

            猜你喜欢
            • 2014-03-18
            • 2018-07-19
            • 1970-01-01
            • 2011-11-20
            • 1970-01-01
            • 2013-02-15
            • 2020-02-04
            • 2011-02-11
            • 2012-01-20
            相关资源
            最近更新 更多