理解Java中抽象类的目的

时间:2012-02-08 16:34:32

标签: java override abstract-class

假设我有两个类,A和B.A类被定义为抽象,而B扩展了这个抽象类,最后我测试了结果,两个类都是同一个包的一部分。

public abstract class A {

    protected abstract void method1(); 

    protected void method2() { 
        System.out.println("This is Class A's method"); 
    } 
}

public class B extends A {

    @Override
    protected void method1() {
        System.out.println("This is B's implementaiton of A's method");
    } 
}  

现在当我测试它们时:

B b = new B();
b.method1();
b.method2();  

我得到预期的输出:

This is B's implementaiton of A's method
This is Class A's method

问题:

  • @Override关键字的目的是什么,因为如果我省略它,那就是它 仍然是一样的。
  • 如果我没有实现抽象方法,我会收到编译错误。那么实现接口有什么不同呢?
  • 另外,我也可以在B中实现method2()。然后输出更改为B中使用的内容。这是否也会覆盖父类方法?那么在A类中明确定义方法为 abstract 的目的是什么?

8 个答案:

答案 0 :(得分:18)

  1. @Override不是关键字,它是一个可选的注释,可帮助编译器检查您确实覆盖了某个方法。如果你说@Override但是没有方法可以覆盖,编译器会告诉你你可能犯了一个错字。将method1重命名为method12以查看效果。
  2. 接口不能有任何实现,而抽象类可以选择为其某些方法提供实现。此外,接口不能包含数据成员。
  3. 将方法定义为抽象意味着派生类必须提供实现。没有声明它是抽象的说派生类只是可以提供他们自己的实现,但他们不需要。

答案 1 :(得分:13)

<强> @覆盖

@Override是在Java 5中引入的(并在Java 6中进行了一些扩展)。它只是提供信息。它说“我想要覆盖父类或接口中已经存在的东西。

IDE就像Eclipse一样可以警告你,如果你没有这样的父方法(例如,如果你错误地使用了这个名字)。在这种情况下,不会调用您的方法(因为拼写错误)。

但不要过于担心。

抽象类与界面

抽象类允许您定义保留未定义部分的基本功能。界面不允许您实现任何内容。您可以对除了每种情况下真正发生变化的部分之外的所有内容进所以当你需要它时,你继承并实现了缺失的部分。

覆盖两种方法

是。在Java中,您可以覆盖在父类中未声明为final的所有方法。没关系。如果你想让它不可修改,你可以宣布它是最终的。例如,如果您想声明订单,您可以:

public abstract class Ordering<X>
{
abstract boolean isLower(X a, X b);
abstract boolean isEquals(X a, X b);
   final boolean isGreater(X a, X b) {
      return !isLower(a, b) && !isEquals(a, b);
   }
}

当然,覆盖isGreater以实现另一种更有效的方式可能是有意义的(想象它的比较成本很高)。但是有些情况下你想提供基本的已经实现的功能(当抽象类比接口更好时),或者当你想强制实现某些实现时(当最终关键字显示有用时)。

答案 2 :(得分:4)

Abstract Classes允许您存储基本级别的实现(继承),同时还生成一个合同,保证继承的类将自己实现特定的功能(接口)......

虽然永远不会有抽象类的实例,但您可以在继承者之间存储共享功能......

我一直认为它们是接口,允许某些方法的基本级实现......

答案 3 :(得分:2)

抽象类和接口之间的主要区别在于接口只定义了一个接口,抽象类也可以有一个实现和字段/属性。

抽象类可以被视为IS-A关系(例如,马是动物)。对于接口,它主要是类可以具有的一些特征(例如,INAVigable,ISortable)。

也无法实例化抽象方法(也不能实现接口)。

重写函数用于显示函数具有基类实现。

对于类,也不可能/建议多重继承,因此最大。仅使用一个基类,并从其他功能的接口继承。

答案 4 :(得分:1)

  

@Override关键字的目的是什么,因为如果我省略它,它   仍然是一样的。

的易读性。

  

如果我没有实现抽象方法,我会收到编译错误。那是什么呢?   实现接口的区别?

接口不允许您包含代码。

  

另外,我也可以在B中实现method2()。然后输出改变   什么在B中使用。这不是覆盖父类   方法。那么显式定义方法的目的是什么呢?   A类摘要?

是的,它覆盖了父方法。您通常将方法定义为抽象,以留下子项的实现(必须实现它或者是抽象的)。如果它不是抽象的,你必须实现它。

答案 5 :(得分:1)

What is the purpose of @Override keyword

这是后来的Java添加,它用于弱自我控制。它是注释,即库类,而不是关键字。

So what is the difference to implementing an interface?

小。 Iterface是一个所有方法都是抽象的类。此外,只允许一个父类,而它可以是多个接口。您也可以将成员放入课堂,但不能放入界面。

Then what is the purpose of explicitly Defining a method abstract in Class A?

只有在没有正文时才应将其声明为抽象。 JVM需要知道所有后代都会拥有它。

答案 6 :(得分:0)

当你有多个类实现并且从method2调用method1时,真正的用法就会出现。在这种情况下,在执行method2之后,将执行相应类中的method1。

public abstract class A {

    protected abstract void method1(int val); 

    protected void method2() { 
        System.out.println("This is Class A's method");
        //Let us I calculated something here, may be sum of two ints 
        method1(//pass above calculated int);
    } 
}

public class B extends A {

    @Override
    protected void method1(int val) {
        System.out.println("This is B's implementaiton of A's method");
        //Here you may do this class specific manipulation on val.
    } 
}  

就像在C类中一样,你可以操纵常见的计算一些。

答案 7 :(得分:0)

这个article有一些关于你问题标题的好概念(和例子)。

  

抽象类是包含一个或多个抽象方法的类。 抽象方法是声明的方法,但不包含任何实现。 抽象类可能无法实例化,并且需要子类来提供抽象方法的实现。

假设您要使用某些方法定义类,但是对于程序/项目的任何设计目的,您需要确保在必须实现特定方法(抽象方法)时抽象类已扩展。

基本上,抽象类的目的是使用以下方法定义类:

    必须在子类上声明(摘要)
  • 可选地在子类
  • 上使用(非抽象)


其他评论

  • 几年前,我开发了一个Android应用程序(Java,而不是Kotlin),在使用许多库的过程中,我遇到了使用Abstract Classes扩展我的类的行为,并且由于这种类的行为, Android Studio会自动添加到我的代码中,所有抽象方法都是我正在扩展的抽象类的一部分。