什么是抽象类
抽象类是相同概念实体的一种抽象,Java中用关键字abstract来定义抽象类和抽象方法。
什么是抽象方法
只有方法的声明,没有方法的具体实现的方法。
抽象类和抽象方法的特点
- 抽象类和抽象方法必须用abstract关键字来修饰,抽象方法没有方法体,即不能有{};
- 抽象类中不一定要有抽象方法,即也可以都是非抽象方法或两者并存,但是拥有抽象方法的类一定要定义为抽象类;
- 抽象类不能被实例化,但是抽象类依然有构造方法,抽象类的构造方法用于子类访问父类数据的初始化。
- 抽象类的子类可以是抽象类,但如果不是抽象类,必须重写抽象类中定义的所有抽象方法。
抽象类成员的特点
- 成员变量:可以为常量(例如final修饰的常量),也可以为变量;
- 静态成员变量:可以有,可以被继承,但是不会被重写
- 构造方法:上面提到过,可以有,用于子类访问父类时数据初始化;
- 成员方法:可以是抽象的成员方法(子类必须要实现重写的),也可以是非抽象的成员方法
- 静态成员方法:抽象类中可以有静态成员方法,可以被继承但不能被子类重写
下面是一些说明上面问题的示例代码:
/** * Created by lili on 15/10/21. */ abstract class Person { public int age = 1; public final int PerID = 2; public Person() { } public Person(int age) { this.age = age; } abstract void show();//定义子类必须要重写的,即必须要做的事 //子类必须要继承的,但不一定要重写 public void play() { System.out.println("抽象类中的非抽象方法"); } //子类必须继承且不能重写 public final void talk() { System.out.println("talk like a person"); } public static void think() { System.out.println("think like a person"); } } class Student extends Person{ public int age = 10; public final int PerID = 20;//注释后向下转型后的看成员变量访问的结果中PerID打印的是2,说明可被继承 public Student() { } //必须要重写 void show() { System.out.println("子类中重写抽象类中的抽象方法"); System.out.println("子类内部访问age:" + age);//打印的是10,成员变量可以被重写 System.out.println("子类内部访问PerID:" + PerID);//打印的是20,说明静态成员变量可以被"重写"; } // public final void talk() { //报错,被覆盖的方法为final // System.out.println("talk like a student"); // } public static void think() { System.out.println("think like a student"); } } public class PolymorphismTest { public static void main(String[] args) { Person person = new Student(); person.show();//方法被重写,访问的是重写后的方法 System.out.println(person.age);//打印1,打印的是父类的age System.out.println(person.PerID);//打印2,打印的是父类的PerID person.talk();//talk like a person,调用的是父类的访问,静态方法,不被重写 person.think(); System.out.println("--------向下转型后的看成员变量访问的结果-----------"); Student student = (Student)person; student.show();//方法被重写,访问的是重写后的方法 System.out.println(student.age);//打印10,成员变量被重写了 System.out.println(student.PerID);//打印20,成员方法被重写了 student.talk();//talk like a person,静态方法,不被重写,但被继承 student.think(); } }
运行结果:
子类中重写抽象类中的抽象方法
子类内部访问age:10
子类内部访问PerID:20
1
2
talk like a person
think like a person
--------向下转型后的看成员变量访问的结果-----------
子类中重写抽象类中的抽象方法
子类内部访问age:10
子类内部访问PerID:20
10
20
talk like a person
think like a student
Process finished with exit code 0
注释子类中的PerID定义,则运行结果为:
子类中重写抽象类中的抽象方法
子类内部访问age:10
子类内部访问PerID:2
1
2
talk like a person
think like a person
--------向下转型后的看成员变量访问的结果-----------
子类中重写抽象类中的抽象方法
子类内部访问age:10
子类内部访问PerID:2
10
2
talk like a person
think like a student
Process finished with exit code 0
抽象关键字abstract和其他关键字的冲突关系
- 不能和private一起使用:private修饰的方法不被继承,而抽象的方法必须要继承,所以会冲突报错。
- 和static一起使用无意义:static修饰的方法可以通过类名去访问,而抽象的方法没有实现方法体,所以无意义。
- 不能和final一起使用:final修饰的方法不被重写,而抽象的方法必须被非抽象子类重写,所以会报错。