javaSE基础-抽象

抽象(abstract)

java关键字abstract,可用于修饰类、方法。

抽象类

格式:修饰符 abstract class 类名{}

1、此类不能实例化

2、抽象类中一定有构造器,便于子类实例化时调用

3、开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作

抽象方法

格式:修饰符 abstract 返回值 方法名(){}

1、抽象方法只能声明方法,没有方法体

2、包含抽象方法的类一定声明为抽象类

3、若子类重写了父类中的所有的抽象方法后,此子类方可实例化

特点:

  • 抽象类中可以没有抽象方法
  • 类中可以定义抽象方法
  • 抽象类不能直接实例化,要通过其普通的子类实例化,抽象类可以创建构造方法,为子类调用
  • 子类继承抽象类必须实现抽象类中所有抽象方法,否则子类也必须声明为抽象类
  • 抽象类修饰符必须是public或友好的(即默认的),不能是private,若为私有的子类无法继承重写抽象方法

示例一:

/**
 * abstract关键字的使用<br>
 * abstract可以用来修饰的结构有:类、方法<br>
 * 
 * @author jb
 * @date 2022/08/08
 */
public class AbstractTest {
    public static void main(String[] args) {
        // 抽象类不能实例化
        // Person2 p = new Person2();
        // p.eat();
        Person2 s = new Student("张三", 18); // 子类实例化对象,向上转型
        System.out.println(s); // com.bingeone.test.Student@70dea4e
        System.out.println(s.name); // 张三
        s.sing(); // 调用Student类的方法
        s.eat();// 调用Person2类的方法
        s.breath();
    }
}

abstract class Creature {
    public abstract void breath();
}

abstract class Person2 extends Creature { // Person2类继承Creature类,此时有两个抽象方法
    String name;
    int age;

    Person2() {
    }

    Person2(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat() {
        System.out.println("人要吃饭!");
    }

    public void walk() {
        System.out.println("人可以走路!");
    }

    // 抽象方法,没有方法体
    public abstract void sing();

}

class Student extends Person2 {

    public Student(String name, int age) {// 此继承父类,借鉴name,age的属性名,在子类中可以访问
        super(name, age);
    }

    @Override
    public void sing() {
        System.out.println("student is singing");
    }

    @Override
    public void breath() {
        System.out.println("student is breathing");
    }

}

示例二:

public abstract class Vehicle{
    public abstract double calcFuelEfficiency(); // 计算燃料效率的抽象方法
    public abstract double calcTripDistance(); // 计算行驶距离的抽象方法
}

public class Truck extends Vehicle{
    public double calcFuelEfficiency(){
         //编写计算卡车的燃料效率具体方法
     }	
    public double calcTripDistance(){
        //编写计算卡车行驶距离的具体方法
    }
        
}

示例三:

abstract class GeometricObject{
    public abstract double findrea();
}

class Circle extends GeometricObject{
    private double radius;
    public double findrea(){
        return 3.14*radius*radius;
    }
}

注意事项:

  • abstract不能用来修饰:属性,构造器等
  • abstract不能用来修饰私有方法、静态方法、final的方法、final的类

抽象类的匿名子类使用方式:

/**
 * 抽象类的匿名子类使用方法
 * 
 * @author jb
 * @date 2022/08/08
 */
public class PersonTest2 {
    public static void main(String[] args) {

        // 1、创建匿名子类的非匿名对象
        Person3 p = new Person3() {

            @Override
            public void eat() {
                System.out.println("吃什么呢。。。");
            }

            @Override
            public void breath() {
                System.out.println("有氧呼吸。。。");
            }
        };
        method(p);

        System.out.println("***********");

        // 2、创建匿名子类的匿名对象 -> 抽象类的简化用法
        method(new Person3() {

            @Override
            public void eat() {
                System.out.println("好好吃饭");
            }

            @Override
            public void breath() {
                System.out.println("深呼吸。。。");
            }
        });

        System.out.println("***********");
        // 3、匿名对象 -> 创建普通类作为实参传给方法使用
        method(new Employee("李四", 180));

        System.out.println("***********");
        // 4、正常使用方式:非匿名对象
        Employee employee = new Employee("张三", 185);
        employee.eat();
        employee.breath();
        System.out.println(employee);
    }

    public static void method(Person3 p) {
        p.eat();
        p.breath();
    }

}

/**
* 抽象类Person3
*/
abstract class Person3 {
    public abstract void eat();

    public abstract void breath();
}

/**
* 继承抽象类的子类Employee
*/
class Employee extends Person3 {
    String name;
    int height;

    @Override
    public void eat() {
        System.out.println(name + "正在吃饭。。");
    }

    @Override
    public void breath() {
        System.out.println(name + "有氧呼吸运动");
    }

    public Employee(String name, int height) {
        super();
        this.name = name;
        this.height = height;
    }

    @Override
    public String toString() {
        return "Employee [name=" + name + ", height=" + height + "]";
    }

}

//结果:
吃什么呢。。。
有氧呼吸。。。
***********
好好吃饭
深呼吸。。。
***********
李四正在吃饭。。
李四有氧呼吸运动
***********
张三正在吃饭。。
张三有氧呼吸运动
Employee [name=张三, height=185]

抽象类的应用

模板方法:在软件开发中实现一个算法,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变、将此部分抽象出来,供子类实现。这就是模板模式

示例四:

/**
 * 抽象类的应用:模板方法的设计模式<br>
 * 
 * @author jb
 * @date 2022/08/07
 */
public class TemplateTest {
    public static void main(String[] args) {
        SubTemplate t = new SubTemplate();
        t.spendTime(); // 调用父类的方法
    }
}

abstract class Template {

    public void spendTime() {
        long start = System.currentTimeMillis();

        this.code(); // 不确定部分,易变部分

        long end = System.currentTimeMillis();
        System.out.println("花费的时间为: " + (end - start) + "秒");

    }

    public abstract void code();
}

class SubTemplate extends Template {

    @Override
    public void code() {
        for (int i = 2; i < 100; i++) {
            boolean isFlag = true;
            for (int j = 2; j <= Math.sqrt(i); j++) {
                if (i % j == 0) {
                    isFlag = false;
                    break;
                }
            }
            if (isFlag) {
                System.out.println(i);
            }
        }
    }

}

应用场景:

模板方法设计模式是编程中经常使用的模式,各个框架、类库中都有它的影子

  • 数据库访问的封装
  • Junit单元测试
  • JavaWeb的Servlet中关于doGet/doPost的方法调用
  • Hibernate中模板程序
  • Spring中JDBCTemplate、HibernateTemplate等
posted @ 2022-10-18 20:54  Bingeone  阅读(21)  评论(0编辑  收藏  举报