Java抽象类和抽象方法详解

抽象类的存在是为了编程设计的需要,被abstract关键字修饰符修饰的抽象类通常处于继承树的顶端,相比于其子类更加抽象


什么是抽象

提到抽象,人们自然会想到将『抽象』作为其一大特性的『面向对象编程(OOP)』(面向对象的四大特性:抽象、封装、继承、多态)

确实,『抽象』这个概念只出现在『面向对象编程』里面——和具象相对应,『抽象』表示某种不确定,即存在潜在的可能性(父类抽象,在子类逐渐具体)

为了表示『抽象』这一概念,我们使用abstract关键字表示——abstract类是抽象类,abstract方法是抽象方法

既然抽象是面向对象编程语言的特性,而面向编程语言有Java、C++等,它们都有abstract关键字;下面就以Java为例讲解抽象类和抽象方法


抽象类和抽象方法

始终记住,抽象类和抽象方法的产生是为了维护继承链的逻辑,即抽象类相对于那些普通的类处于继承树的根部

那抽象方法呢?抽象方法的产生完全是为了迎合抽象类的存在:抽象方法只能写在抽象类中!

至于字段,抽象类的字段(反正也没有abstract抽象字段一说)只要像正常的继承关系那样使用就好了,不必担心

abstract关键字修饰的类叫抽象类
abstract关键字修饰的方法叫抽象方法

学习『抽象』的两个指导思想:
抽象(abstract class)类不能被实例化!!
抽象方法(abstract method)只能存在于抽象类中!!

/**Person抽象类*/
public abstract class Person{

    /**抽象类的字段只要正常使用就好了,默认访问权限是package*/
    static String name="大黄";//静态字段可以被继承和隐藏
    int age=30;//非静态字段可以被继承和重写

    /**抽象类可以有非抽象非静态方法,在其子类中可以被继承和重写*/
    void say(){
        System.out.println("Hello world!");
    }

    /**抽象类可以有非抽象静态方法,在其子类中可以被继承和隐藏*/
    static void eat(String food){
        System.out.println("Person can eat "+food);
    }

    /**抽象方法只能存在于抽象类中,它没有方法体,必须在子类中具体实现;注意:1.抽象类甚至可以没有抽象方法(抽象类的关键是不能实例化而不是抽象方法!);2.没有所谓的抽象静态方法(abstract static,这样的事情你永远也不要尝试!)*/
    abstract void printInfo();
}
/**Student类,继承自Person抽象类*/
public class Student extends Person{

    /**自动获得从父类继承来的成员字段*/
    static String name="小明";
    int age=12;

    /**自动获得从父类继承来的非抽象方法*/

    /**重写继承来的父类方法*/
    @Override
    void say(){
        System.out.println("Hello Java!");
    }

    /**在子类中具体实现抽象类的抽象方法,使用@Override规范书写*/
    @Override
    void printInfo(){
        System.out.println("My name is "+name+" and I am "+age+" years old.");
    }
}
/**测试驱动*/
public class TestDrive{
    public static void main(String[] args){
        //Person p = new Person();此句会报错,因为不能实例化一个抽象类
        Student s = new Student();//实例化抽象类的子类
        Person t = new Student();//向上转型
        System.out.println("Testing s...(导出类)");
        System.out.println("s.name: "+s.name);
        System.out.println("s.age"+s.age);
        s.say();
        Person.eat();
        s.printInfo();
        System.out.println("\nTesting t...(抽象类)");
        System.out.println("t.name: "+t.name);
        System.out.println("t.age: "+t.age);
        t.say();
        Person.eat();
        t.printInfo();
    }
}

抽象类好理解,反正记着一点:抽象类不能被实例化,必须通过继承抽象类然后实例化它的子类——抽象类的作用可以看作是『类的模版』,本身不参与实例的构建,必须通过它的子类实现其宏伟抱负(有点子承父志的味道)

抽象类中不能有finalstatic方法,因为被final或static修饰的方法不能被子类实现(本质上是重写,或者说覆写)

关于抽象方法,总结起来有以下几点:
1)抽象类中可以有抽象方法,也可以没有抽象方法;但是抽象方法只能存在于抽象类中
2)抽象类中的非抽象方法如同在非抽象类中一样,正常继承使用
3)不存在所谓的抽象静态方法(abstract static,永远不要这样干!)

关于第三点,我是这样理解的:因为静态方法总是和一个类相绑定的,也因为这样我们使用类名而不是实例来调用某个类的静态方法;(反证法)如果一个抽象类的抽象方法被修饰为static的,我们推荐使用类名来调用该方法,即调用抽象类的静态方法(在「类」上面划着重号),可是又因为这个方法还被abstract修饰,是没有方法体的,我们不能直接调用(必须要现在子类中具体实现后才能调用),于是矛盾——故不存在所谓的抽象静态方法

测试结果如下:
Java抽象类和抽象方法详解_第1张图片

你可能感兴趣的:(Java,语言)