一、知识清单
1、abstract抽象的
2、abstract可以用来修饰的结构:类、方法
3、abstract修饰类:抽象类
>此类不能实例化
>抽象类中一定有构造器,便于子类实例化调用(涉及:子类对象实例化的全过程)
>开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
4、abstract修饰方法:抽象方法
>抽象方法只有方法的声明,没有方法体
>包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有差抽象方法的
>若子类重写了父类中所有的抽象方法后,子类方可实例化
>若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
>抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
6、抽象类也是类,所以可以用类名.属性或方法来调用静态属性、方法。
5、abstract使用上的注意点:
>abstract不能用来修饰:属性、构造器、代码块等结构
>abstract不能用来修饰私有方法、静态方法、final方法、final类
原因看这abstract 不能与哪些关键字同时但是本文作者第二行有错误:子类是可以继承父类的private方法的,但是由于受到封装性的影响不能够直接调用,而且在子类中声明与父类同名同参的私有方法时,在子类中不会构成重写。
二、代码演示
上面的结论大家一看就能懂,没有特别要说明之处,这里直接贴出代码演示。
public class AbstractTest {
public static void main(String[] args) {
//一旦Person类抽象了,就不可实例化
//Person p1=new Person();Cannot instantiate the type Person
//下面也是使用的虽然有的父类使用abstract修饰了,但是多态仍然是使用的
Creature p1=new Student();
Person p2=new Student();
p1.breath();
System.out.println(Person.name);//可以调用的
}
}
abstract class Creature{
public abstract void breath();
}
abstract class Person extends Creature{
static String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
//不是抽象方法
// public void eat(){};
//抽象方法:只有方法声明没有方法体
public abstract void eat();
public void walk(){
System.out.println("人走路");
}
}
class Student extends Person{
String snum;
public Student(String name,int age){
super(name,age);
}
public Student(){
}
@Override
public void eat() {
System.out.println("学生多吃有营养的食物");
}
@Override
public void breath() {
System.out.println("学生呼吸新鲜空气");
}
}
二、抽象类的匿名子类
/*
* 抽象类的匿名子类
*
*/
public class AnonymousSubClassOfAbstractClass {
public static void method1(Person p){
p.eat();
p.breath();
}
public static void method(Student s){
}
public static void main(String[] args) {
method(new Student());//匿名对象
Worker worder=new Worker();
method1(worder);//非匿名的类非匿名的对象
method1(new Worker());//非匿名的类匿名的对象
System.out.println("-------");
//创建了一个匿名子类的非匿名的对象:这里可不是Person类的对象
//而是其子类的,因为我们知道抽象类是不能造对象的,所以我们
//虽然形式上看着是Person类的对象,实质上是Person子类的对象
Person p=new Person(){//发送了多态,编译时是父类的eat方法,运行时是子类的
@Override
public void eat() {
System.out.println("吃东西");
}
@Override
public void breath() {
System.out.println("好好吸气");
}
};
//匿名子类的匿名对象
new Person(){
@Override
public void eat() {
System.out.println("我爱吃");
}
@Override
public void breath() {
System.out.println("我还睡");
}
};
}
}
class Worker extends Person{
@Override
public void eat() {
}
@Override
public void breath() {
}