Java Review (十三、面向对象----抽象类)

文章目录

如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用性,甚至可能更加抽象。从某种角度看, 祖先类更加通用, 只是将它作为派生其他类的基类,而不作为想使用的特定的实例类。


抽象方法和抽象类

抽象方法和抽象类必须使用 abstract 修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法 。

抽象方法和抽象类的规则如下 。

  • 抽象类必须使用 abstract 修饰符来修饰,抽象方法也必须使用 abstract 修饰符来修饰,抽象方法不能有方法体。
  • 抽象类不能被实例化,无法使用 new 关键字来调用抽象类的构造器创建抽象类的实例 。 即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。
  • 抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举) 5 种成分 。 抽象类的构造器不能用于创建实例, 主要是用于被其子类调用。
  • 含有抽象方法的类(包括直接定义了 一个抽象方法;或继承了 一个抽象父类,但没有完全实现父类包含的抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类 。

抽象类实例

public class Main {
    public static void main(String[] args) {
        Person p = new Student();
        p.run();
    }
}

//抽象类Person
abstract class Person {
    //抽象类
    public abstract void run();
}

//抽象类子类
class Student extends Person {
    //抽象类子类必须实现父类抽象方法
    @Override
    public void run() {
        System.out.println("Student.run");
    }
}

抽象类的作用

抽象类不能创建实例,只能当成父类来被继承。

从语义的角度来看,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类设计的随意性。抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会大致保留抽象类的行为方式。

如果编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,这就是一种模板模式,模板模式也是十分常见且简单的设计模式之一 。

下面再是一个个模板模式的范例,在这个范例的抽象父类中,父类的普通方法依赖于一个抽象方法,而抽象方法则推迟到子类中提供实现 。

模板模式范例-抽象父类

public abstract class SpeedMeter{
   // 转速
   private double turnRate;
  public SpeedMeter() {}
  // 把计算车轮周长的方法定义成抽象方法
   public abstract double calGirth() ;
   
   public void setTurnRate(double turnRate){
     this.turnRate = turnRate ;
   }
      
  //定义计算速度的通用算法
  public double getSpeed(){
    // 速度等于周长*转速
    return calGirth () * turnRate;
  }

}  

模板模式范例-子类

public class CarSpeedMeter extends SpeedMeter{
   private double radius;
   public CarSpeedMeter(double radius){
     this.radius = radius ;
   }   
   //实现父类抽象方法
   public double calGirth(){
    return radius * 2 * Math.PI ;
   }
    
   public static void main(String[] args){
     //既可创建CarSpeedMeter 类的对象,也可通过该对象来取得当前速度 
    CarSpeedMeter csm = new CarSpeedMeter(O.34) ;
    csm.setTurnRate(15) ;
    System.out.println(csm . getSpeed()) ;
   }

} 

SpeedMeter 类里提供了速度表的通用算法 , 但一些具体的实现细节则推迟到其子类 CarSpeedMeter类中实现 。 这也是一种典型的模板模式。

模板模式在面向对象的软件中很常用,其原理简单,实现也很简单 。 下面是使用模板模式的一些简单规则 。

  • 抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,留给其子类去实现 。
  • 父类中可能包含需要调用其他系列方法的方法,这些被调方法既可以由父类实现,也可以由其子类实现 。 父类里提供的方法只是定义了 一个通用方法,其实现也许并不完全由自身实现,而必须依赖于其子类的辅助 。

当使用了抽象的思想后:调用者只需关心抽象方法的定义,不必关心子类的具体实现。


参考:

【1】:《疯狂Java讲义》

【2】:《Java核心技术 卷一》

【3】:https://www.liaoxuefeng.com/wiki/1252599548343744/1260456371027744


上一篇:Java Review (十二、面向对象----final 修饰符)


下一篇:一个Java 8中简单Lambda表达式程序