7.abstract 修饰符
abstract 修饰符可以用来修饰类和成员方法
用 abstract 修饰的类表示抽象类,抽象类位于继承树的抽象层,抽象类不能被实例化,即不允许创建抽象类本身的实例。没有用 abstract 修饰的类称为具体类,具体类可以被实例化。
用 abstract 修饰的方法表示抽象方法,抽象方法没有方法体。抽象方法用来描述系统具有什么功能,但不提供具体的实现。没有用 abstract 修饰的方法称为具体方法,具体方法具有方法体。
abstract 语法规则:
抽象类可以没有抽象方法,但包括了抽象方法的类必须被定义为抽象类。如果子类没有实现父类中所有的抽象方法,那么子类也必须被定义为抽象类。
以下一个父类
package test;
//抽象类
abstract class Shape{
//受保护的属性
protected double length;
protected double width;
//构造方法
Shape(double num1,double num2){
this.length = num1;
this.width = num2;
}
//定义了一个抽象方法,方法体为空,只要有类继承就必须实现这个抽象方法,否则子类也必须声明为抽象类
abstract double area();
}
其中一个抽象方法 abstract double area();
现有一子类去实现这个父类,会出现什么情况?
package test;
//子类继承父类
class Square extends Shape{
Square(double num1,double num2){
super(num1,num2);
}
}
ERROR!!!
父类有一抽象方法 abstract double area();
子类必须去实现,否则本身也只能为抽象类。
所以,要么:
package test;
//子类继承父类
class Square extends Shape{
Square(double num1,double num2){
super(num1,num2);
}
//实现抽象方法
double area(){
System.out.println("正方形的面积为: ");
return length*width;
}
}
要么:
package test;
//子类继承父类
abstract class Square extends Shape{
Square(double num1,double num2){
super(num1,num2);
}
}
没有抽象构造方法,也没有抽象静态方法。
abstract class Base{
abstract Base() ;// 编译出错,构造方法不能是抽象的
static abstract void method() ;//编译出错, static 和 abstract 不能连用
static void method2(); //合法
}
抽象类中可以有非抽象的构造方法,创建子类的实例时可能会调用这些构造方法。抽象类不能被实例化,然而可以创建一个引用变量,其类型是一个抽象类,并让它引用非抽象的子类的一个实例。
abstract class Base{}
class Sub extends Base{
public static void main(String args[]){
Base base1 = new Base (); //编译出错,不能创建抽象类B ase 的实例
Base base1 = new Sub(); // 合法,可以创建具体类Sub 的实例
}}
抽象类及抽象方法不能被 final 修饰符修饰。因为抽象类只允许创建子类,它的抽象方法才能被实现,并且只有它的具体子类才能被实例化,而用final 修饰的类不允许拥有子类,用 final 修饰的方法不允许被子类方法覆盖,因此把abstract 修饰符与 final 修饰符连用,会导致自相矛盾。(从而引申出接口的方法不能用final修饰)