一.抽象类概念:
在面对对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有类都是用来描绘
对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,那么这个类就是抽象类。
比如:
说明:1.矩形、圆形、三角形都是图形,都是继承于shape类。
2.虽然图形shape是图形类也存在draw方法,但是它并不是一个具体的图形,因此它里面的draw方
法不能具体实现。
3.由于shape没有办法描述一个具体的图形,导致其内部的draw无法实现,因此我们可以将shape
设计成一个抽象类。
说明:
1.Animal是动物类,每一个动物都有叫的方法,但是Animal类并不是一只具体的动物,所以这个类
里面的bark无法具体实现。
2.Dog是狗类,属于动物,继承于Animal类,因为狗是一种具体的动物,所以狗类中bark可以被具
体实现。
3.Cat是猫类,属于动物,继承于Animal类,因为猫是一种具体的动物,所以猫类中bark可以被具
体实现。
4.因此将Animal设计为抽象类
在打印图形的例子中,父类的shape方法的draw好像并没有什么用,打印图形都是通过shape的子
类的draw方法来执行的,像这种没有实际用处的方法,我们可以将它设计为抽象方法(abstract),
包含抽象(abstract method)方法的类我们称为抽象类(abstract class)。
二.抽象类的语法
在java中,一个类如果被abstract修饰,那么这个类就是抽象类,abstract可以修饰方法,这个方法
被称为抽象方法被abstract修饰的方法不用有具体的实现。
// 抽象类:被abstract修饰的类
public abstract class Shape {
// 抽象方法:被abstract修饰的方法,没有方法体
abstract public void draw();
abstract void calcArea();
// 抽象类也是类,也可以增加普通方法和属性
public double getArea(){
return area;
}
protected double area; // 面积
}
注意:抽象类也是类,里面可以有属性、普通方法、甚至可以有构造方法。
三.抽象类特性
1.抽象类不可以直接实例化对象,如:
Shape shape = new Shape();
// 编译出错
Error:(30, 23) java: Shape是抽象的; 无法实例化
2.抽象方法不能被private修饰
abstract class Shape {
abstract private void draw();
}
// 编译出错
Error:(4, 27) java: 非法的修饰符组合: abstract和private
3.抽象方法不能被final、static方法修饰,因为抽象方法要被子类重写。
public abstract class Shape {
abstract final void methodA();
abstract public static void methodB();
}
// 编译报错:
// Error:(20, 25) java: 非法的修饰符组合: abstract和final
// Error:(21, 33) java: 非法的修饰符组合:final和static
4.抽象类必须被继承,子类必须重写父类中所有的抽象方法,不然这个子类还是抽象类,还是得用
abstract来进行修饰。
// 矩形类
public class Rect extends Shape {
private double length;
private double width;
Rect(double length, double width){
this.length = length;
this.width = width;
}
public void draw(){
System.out.println("矩形: length= "+length+" width= " + width);
}
public void calcArea(){
area = length * width;
}
}
// 圆类:
public class Circle extends Shape{
private double r;
final private static double PI = 3.14;
public Circle(double r){
this.r = r;
}
public void draw(){
System.out.println("圆:r = "+r);
}
public void calcArea(){
area = PI * r * r;
}
}
// 三角形类:
public abstract class Triangle extends Shape {
private double a;
private double b;
private double c;
@Override
public void draw() {
System.out.println("三角形:a = "+a + " b = "+b+" c = "+c);
}
// 三角形:直角三角形、等腰三角形等,还可以继续细化
//@Override
//double calcArea();
// 编译失败:要么实现该抽象方法,要么将三角形设计为抽象类
}
5.抽象类不一定包含抽象方法,但是有抽象方法一定是抽象类。
6.抽象类中可以有构造方法,供子类创建对象时初始化父类得成员变量。
四.抽象类的作用
1.抽象类本身并不能被实例化,如果要想使用的话,只能创建该抽象类的子类,然后子类重写其里
面的抽象方法。
我们不经有点疑惑,普通的类也可以被继承,里面的方法也可以被重写,那我们为什么要用抽象类和抽象方法呢?
抽象类和抽象方法确实是看起来有点麻烦,但是优点是:使用抽象类相当于编译器多了一项校验。
很多语法存在的意义都是为了"预防出错",例如我们曾经用过的final也是类似,就是让我们创建的变
量不能被修改,也就是相当于常量。但是在我们加上final之后,能够在不小心误修改它的情况下,
编译器会报错。