java_se 抽象类(包含多态知识)

来源:互联网 发布:mac版qq接收文件 编辑:程序博客网 时间:2024/05/21 10:22

1概念
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类,抽象类是把一些有共性的类的属性或者方法抽取出来,定义为一个抽象类,然后继承该抽象类,重写方法来达到代码的重用性等优点
2 抽象方法
2.1定义:
如 public abstracr void f1();
方法没有方法体,且被abstract修饰
说明:假定有一个Animal 类 里面有一个sleep()方法,但是对于所有的动物睡觉方式不一样,所以你根本无法准确的去描述具体动物的sleep()方法,只有具体的动物类继承了Animal ,才可以再准确的去实现(描述)该方法。
含有抽象方法的类就是抽象类,但是抽象类可以包含非抽象方法,也可以没有抽象方法。
3完整的定义一个抽象类

abstract class A{//定义一个抽象类 用abstract修饰  private String name;  A(){}//可以包含无参构造,  A(String name){//有参构造   this.name=name;}    public void fun(){//普通方法        System.out.println("存在方法体的方法");    }    public abstract void print();//抽象方法,没有方法体,有abstract关键字做修饰}

4:抽象类的特点说明
1)、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,需要依靠子类采用向上转型的方式处理,它只需要有一个引用即可
如:A a;向上转型:父类引用指向子类对象
2)抽象方法必须被子类重写(如果子类不重写父类的抽象方法,该子类还是抽象类,那么就没有任何的意义),因为抽象类出发点就是用来被子类去继承,去实现具体的方法
3)只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。
4)abstract 不能与private、static、final或native并列修饰同一个方法
5)abstract不能与final并列修饰同一个类
5完整研究实例
老师案例
具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。

分析:从具体到抽象:
基础班老师:
成员变量:姓名,年龄
构造方法:有参构造方法/无参构造方法
成员方法:SetXXX()/GetXXX():公共访问方法
teach()
eat()
就业班老师:
成员变量:姓名,年龄
构造方法:有参构造方法/无参构造方法
成员方法:SetXXX()/GetXXX():公共访问方法
teach()
eat()
将共性内容:抽取为一个独立类:老师类(抽象类): teach();每一个老师讲的内容不一样,应该定义为抽象功能,由具体的子类去实现;
代码的实现应该从抽象开始写分析。
从抽象到具体

抽象类public abstract class Teacher {    //成员变量    private String name ;    private int age ;    //无参    public Teacher() {    }    //有参    public Teacher(String name, int age) {        this.name = name;        this.age = age;    }    //SetXXX/GetXXX()公共访问方法(alt+shift+s-->r)    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    //teach()    public abstract void teach() ;    //非抽象方法    public void sleep(){        System.out.println("困了,就需要休息....");    }    //可以写一些简单的工具方法    public void show(){        System.out.println(name+"---"+age);    }}
//基本班的老师类public class BasicTeacher extends Teacher {    public BasicTeacher() {        super();    }    public BasicTeacher(String name, int age) {        super(name, age);    }    @Override    public void teach() {        System.out.println("基础班老师教JavaSE...");    }}
//就业班老师类public class WokeTeacher extends Teacher {    //有参    public WokeTeacher() {        super();    }    //无参    public WokeTeacher(String name, int age) {        super(name, age);    }    @Override    public void teach() {        System.out.println("就业班老师讲JavaEE...");    }}
测试类public class AbstractTest {    public static void main(String[] args) {        //测试基础班老师        Teacher t = new BasicTeacher() ;//向上转型        t.setName("高圆圆") ;        t.setAge(27) ;        t.show();        System.out.println(t.getName()+"----"+t.getAge());        //调用功能        t.sleep() ;        t.teach() ;        System.out.println("------------------------");        //方式2:有参构造        t = new BasicTeacher("唐嫣",27) ;        System.out.println(t.getName()+"----"+t.getAge());        //调用功能        t.sleep() ;        t.teach() ;        //就业班老师类似基础班老师    }}

说明:
执行顺序
注:其实抽象类就是一种模板,里面的抽象方法
1Teacher t = new BasicTeacher() ;不要想着父类是抽象类,其实就是一个栈内存里面的t变量指向堆内存里面new 出来的对象,实际还是看new对象。其实可以按着BasicTeacher t=new BasicTeacher();来理解就是来实例化子类的,然后去调用子类的无参构造函数去初始化,应为是继承所以getXX,setXXX子类已经具备了,就可以调用来初始化对象。
3t.show(); 理解 初学者认为 show方法不是抽象类的吗,则么可以用抽象类来调用,其实子类已经继承了父类,拥有了父类的方法,加之t已经指向了子类对象,好比是子类自己亲生的的引用,只不过是一种抽象类的规定一样(规定就该这样写),心里默默的忽略ta。
4t.teach() ;理解 因为子类已经重写了该方法,所以执行的时候看的是子类的重写后的方法,也是编译看左,执行看右 Teacher t = new BasicTeacher() ,具体说明 编译时候看看Teacher 里面有没有teacher方法,即编译看左,运行时候看的是子类重写的方法,如果子类没有重写该方法,就会报错,因为不可以new对象,这时候子类也是抽象类。即运行看右。