抽象类和抽象方法
当编写一个类时,常常会为该类定义一些方法,这些方法用以描述该类的行为方式,那么这些方法都有具体的方法体,但在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确地知道这些子类如何实现这些方法。
抽象方法(只有方法签名没有实现的方法)和抽象类必须使用abstract修饰来定义,有抽象方法的类只能定义成抽象类,抽象类里可以没有抽象方法
规则:
抽象类和抽象方法必须使用abstract修饰符来修饰,抽象方法不能有方法体
抽象类不能被实例化,我们不能用new关键字来调用抽象类的构造器创建抽象类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能用来创建实例。
抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要用于被其子类调用
含有抽象方法的类(包括直接定义了一个抽象方法;或继承了一个抽象父类,但没有完全实现父类包含的抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。
定义抽象方法只需要在普通方法上增加abstract修饰符,并把普通方法的方法体(也就是方法后花括号的部分)全部去掉,并在方法后增加分号即可。
例如:
public abstract void book();
定义抽象类我们只需要在普通类上增加
abstract
修饰符即可。甚至一个普通类没有包含抽象方法的类,增加
abstract
修饰符后也将变成抽象类。
例如:
public abstract class SpeedMeter
{
//转速
private double turnRate;
public SpeedMeter()
{
}
//把返回车轮半径的方法定义成抽象方法
public abstract double getRadius();
public void setTurnRate(double turnRate)
{
this.turnRate = turnRate;
}
//定义计算速度的通用算法
public double getSpeed()
{
//速度等于 车轮半径 *2 *PI *转速
return java.lang.Math.PI * 2 *getRadius() * turnRate;
}
}
public class CarSpeedMeter extends SpeedMeter
{
public double getRadius()
{
return 0.28;
}
public static void main(String[] args)
{
CarSpeedMeter csm = new CarSpeedMeter();
csm.setTurnRate(15);
System.out.println(csm.getSpeed());
}
}
当使用abstract修饰类时,表明这个类只能被继承;当使用abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。而final修饰的类不能继承,final修饰的方法不能被重写。因此final和abstract永远不能同时使用。
关于abstract的小知识点:abstract不能用于修饰成员变量,不能用于修饰局部变量,即没有抽象变量、没有抽象,成员等说法;abstract也不能用于修饰构造器,没有抽象构造器,抽象类里定义的构造器只能是普通构造器。除此之外,当使用static修饰一个方法时,表明这个方法属于该类本身,即通过类就可以调用发方法,但如果该方法被定义成抽象方法,则导致通过该类来调用该方法时出现错误(调用了一个没有方法体的方法),因此static和abstract不能同时修饰某个方法,即没有所谓的类抽象方法。但它们也不是绝对互斥的,static和abstract虽然不能同时修饰某个方法,但它们可以同时修饰内部类。
抽象类的作用
抽象类不能够创建实例,只能当成父类来被继承。从语义的角度来看,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出来一个抽象类,以这个抽象类作为其子类的模板,这样就避免了子类设计的随意性。
抽象类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,留给其子类去实现。
父类中可能包含需要调用其他系列方法的方法,这些被调方法既可以由父类实现,也可以由其子类实现。父类里提供的方法只是定义了一个通用算法,其实现也许并不完全由自身实现,而必须依赖于其子类的辅助。
归纳起来,抽象类可用“有得有失"4个字来描述。"得"是指抽象类多了一个能力:抽象类可以包含抽象方法,"失"指的是抽象类失去了一个能力:抽象类不能用于创建实例。
接口和抽象类的共同点和区别
共同点:1 接口和抽象类都是上层的抽象层
2 都不能被实例化
3 都能包含的抽象的方法,这些抽象的方法用于描述类具备的功能,但是不比提供具体实现
区别:
在抽象类中可以写非抽象的方法,从而避免在子类中重复书写他们,这样可以提高代码的复用性,这是抽象类的优势;接口中只能有抽象的方法。
一个类只能继承一个直接父类;但是一个类可以实现多个接口
关于接口的知识本文不作介绍,大家有兴趣的可以自行查阅资料哦!