理解Java中抽象类的目的

假设我有两个类,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类中将方法明确定义为抽象的目的是什么?

@覆盖

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

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

但是不要太担心它。

抽象类vs接口

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

覆盖两种方法

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

 public abstract class Ordering { 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以实现另一种更有效的方式可能是有意义的(想象它的比较成本很高)。 但有些情况下,您希望提供基本已实现的function(然后是抽象类比接口更好的时候),或者当您想强制执行某些实现时(当最终关键字显示有用时)。

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

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

虽然永远不会有抽象类的实例,但您可以在inheritance者之间存储共享function……

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

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

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

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

覆盖函数用于显示函数具有基类实现。

同样,多个inheritance是不可能/建议的类,因此最大。 仅使用一个基类,并从其他function的接口inheritance。

@Override关键字的目的是什么,因为如果省略它,它仍然可以正常工作。

易读性。

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

接口不允许您包含代码。

另外,我也可以在B中实现method2()。 然后输出更改为B中使用的内容。这不会覆盖父类方法。 那么在A类中明确定义方法抽象的目的是什么?

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

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需要知道所有后代都会拥有它。

当你有多个类实现并且从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类中的那样你可以操纵常见的计算一些。

本文有一些关于问题标题的好概念(和例子)。

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

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

基本上, Abstract Classes的目的是使用以下方法定义一个Class:

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

补充评论

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