抽象类

Java 核心
第 2 级, 课程 5
可用

“你好,阿米戈!我要和你说一个很有趣的新话题。”

“今天是有趣话题日呢!”

“谢谢你。”

“不客气。”

还记得我们之前为简化所有棋子类而引入的 ChessItem 基类吗?”

“记得。”

“现在,假如每个棋子都有一个方法可以渲染屏幕上的棋子。我们调用此方法,棋子就会在它当前的坐标上自我描画。那如果把这个方法改用到基类里,会对我们有帮助吗?”

“会。”学习了多态后,我可以对所有棋子调用渲染方法,而不受棋子类型限制。就像下面这样:”

例如:
class ChessBoard
{
  public void drawAllChessItems()
  {
  //draw them regardless of their type.
  ArrayList <ChessItem> items = new ArrayList<ChessItem>();
  items.add(new King());
  items.add(new Queen());
  items.add(new Bishop());

  //draw them regardless of their type.
  for (ChessItem item: items)
  {
   item.draw();
  }
 }
}

“做得不错。完全正确。ChessItem 类本身应用 draw 方法会发生什么呢?”

“我不知道。国际象棋里没有这个棋子。这就意味着,它没有可视化的形象。”

“正是。而且创建 ChessItem 对象也没有什么意义。世界上没有这个棋子。它只是一个抽象 — 我们为了方便而创造的一个类。这就是抽象在 OOP 里的运作方式:我们把所有重要的(全部棋子共享的)数据和方法移入基类,但是我们保留了与每个特定棋子相对应的类的不同之处。”

抽象类 - 1

对此,Java 有一个特别的类类型:抽象类。关于抽象类,有 3 点要牢记。

1) 抽象类可以声明方法,而无需实现它。这种方法我们称之为抽象方法。

例如:
 public abstract class ChessItem
{
 public int x, y; //coordinates
 private int value; //the piece's "value"

 public int getValue() //an ordinary method, returns value
 {
   return value;
 }

 public abstract void draw(); //abstract method. There is no implementation.

}
3
任务
Java 核心, 第 2 级, 课程 5
已锁定
Code entry
Sometimes you don't need to think, you just need to hammer it out! As paradoxical as it may seem, sometimes your fingers will "remember" better than your conscious mind. That's why while training at the secret CodeGym center you will sometimes encounter tasks that require you to enter code. By entering code, you get used to the syntax and assimilate some material. What's more, you combat laziness.

2) 抽象方法会带有关键字 abstract 标记。

如果一个类有多个抽象方法,那这个类也可以标为 abstract。

3) 我们无法给抽象类创建对象。有如此意图的代码将无法编译。

Java 语言代码 说明
ChessItem item = new ChessItem();
item.draw();
此代码将无法编译。
ChessItem item = new Queen();
item.draw();
但是你可以这样做。

4) 如果你的类继承自抽象类,就需要重写此继承类的所有方法,换言之,你要实现它们。否则,你的类也要声明为抽象类。如果类有多个未实现的方法直接在类中声明或继承自父类,那么这个类也可以认为是抽象类。

“但是为什么一定要做这些?为什么需要抽象类?不可以改用普通类吗?相较于抽象方法,我们能不能创建一个空的实现,只有左右两个括号?”

“当然可以。但是这些限制条件就像是 private 修饰符。我们使用 private 修饰符来特意拦截对数据的直接访问,如此,其他程序员和他们的类只能用我们的 public 方法。”

抽象类也是同样的道理。无论这个类是谁写的,都不希望任何人给他们的类创建实例。相反,作者会希望他或她的抽象类可以得到继承和重写。

“我还是不明白为什么我们要用这个方法来让事情变得复杂。”

“大项目里更容易说明这个功能的优点。类越多,你就越能清楚地认识到划定类的角色的重要性。不久,你会发现此举的优点。这个过程每个人都会经历。”

评论 (5)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Super Ego 级别 14,Wu Han,China
8 三月 2023
(转自ChatGPT) 当我们在进行Android实际项目开发时,经常会遇到需要定义一些共性的类或方法,但是又不希望这些类或方法被直接实例化或调用,而是需要在子类中进行具体实现的情况。这时候,抽象类就可以派上用场了。 抽象类是一种特殊的类,它不能被直接实例化,而是需要被继承后才能被使用。抽象类中可以包含抽象方法,这些方法只有声明,没有具体实现。子类继承抽象类后,必须实现其中的抽象方法,否则子类也必须声明为抽象类。 在Android开发中,我们经常会定义一些基础类,如Activity、Fragment、View等,这些类中包含了一些共性的方法和属性,但是具体实现需要在子类中完成。这时候,我们可以将这些基础类定义为抽象类,子类继承后再进行具体实现。 另外,抽象类还可以用于定义接口,即定义一些方法的声明,由子类去实现。这种方式可以让我们在定义接口时,不必将所有方法都声明出来,而是只需要声明一些核心方法,其他方法由子类去实现。 总之,抽象类在Android实际项目开发中起到了很重要的作用,它可以帮助我们定义一些共性的类或方法,同时也可以规范子类的实现方式,提高代码的可读性和可维护性。 ``````````````````````````````````````` 抽象类中的抽象方法必须被子类实现,否则子类也必须声明为抽象类。但是,抽象类中也可以包含非抽象方法,这些方法可以有具体的实现,子类可以选择性地覆盖这些方法。 因此,子类中可以只实现抽象类中的部分方法,而不必实现所有方法。如果子类只实现了部分方法,那么该子类仍然必须声明为抽象类,因为它没有完全实现抽象类中的所有抽象方法。 需要注意的是,如果子类中没有实现抽象类中的所有抽象方法,那么在子类中创建对象时会报编译错误。因此,在子类中实现抽象方法是非常重要的,否则无法创建该子类的对象。
Squad303 级别 16,China,China
7 八月 2022
学完学校的JAVA+javaee后还是得来再夯实下基础
Anonymous #10912351 级别 14,Changsha,China
23 一月 2022
暗物质告急
Tom 级别 41,San Jose,Sweden
2 二月 2021
從實例比較容易懂~直接作練習
momoshenchi 级别 22,Wenzhou,China
6 八月 2020
没搞懂