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

120 阅读3分钟

文章目录

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

抽象方法和抽象类

==========================================================================

抽象方法和抽象类必须使用 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()) ;

}

}