【Java基础】抽象类和抽象方法的总结

什么是抽象类

  抽象类是相同概念实体的一种抽象,Java中用关键字abstract来定义抽象类和抽象方法。

 

什么是抽象方法

  只有方法的声明,没有方法的具体实现的方法。

 

抽象类和抽象方法的特点

  1. 抽象类和抽象方法必须用abstract关键字来修饰,抽象方法没有方法体,即不能有{};
  2. 抽象类中不一定要有抽象方法,即也可以都是非抽象方法或两者并存,但是拥有抽象方法的类一定要定义为抽象类;
  3. 抽象类不能被实例化,但是抽象类依然有构造方法,抽象类的构造方法用于子类访问父类数据的初始化。
  4. 抽象类的子类可以是抽象类,但如果不是抽象类,必须重写抽象类中定义的所有抽象方法。

抽象类成员的特点

  1. 成员变量:可以为常量(例如final修饰的常量),也可以为变量;
  2. 静态成员变量:可以有,可以被继承,但是不会被重写
  3. 构造方法:上面提到过,可以有,用于子类访问父类时数据初始化;
  4. 成员方法:可以是抽象的成员方法(子类必须要实现重写的),也可以是非抽象的成员方法
  5. 静态成员方法:抽象类中可以有静态成员方法,可以被继承但不能被子类重写

下面是一些说明上面问题的示例代码:


/**
 * 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和其他关键字的冲突关系

  1. 不能和private一起使用:private修饰的方法不被继承,而抽象的方法必须要继承,所以会冲突报错。
  2. 和static一起使用无意义:static修饰的方法可以通过类名去访问,而抽象的方法没有实现方法体,所以无意义。
  3. 不能和final一起使用:final修饰的方法不被重写,而抽象的方法必须被非抽象子类重写,所以会报错。

 

posted @ 2015-10-23 13:14  FightingBoy&Gril  阅读(2120)  评论(0编辑  收藏  举报