Java小白一文讲解Java中抽象类相关知识点

抽象类

当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么,这个类就是抽象类

抽象类的价值更多是在于设计,是设计者设计好之后,让子类继承并实现抽象类

class Animal{
    private String name;
    private int age;
    public Animal(String name, int age){
        super();
        this.name = name;
        this.age = age;
    }
    //动物都有eat的行为,这里的eat实现了也没啥意义,因为不确定是什么动物
    //这就体现了父类方法的不确定
	public void eat(){
        System.out.println("这是一个动物,但是目前不知道吃什么");
    }
}

像图示代码中的eat()方法往往是Animal类的子类去重写,但是为了让子类去重写,父类也不得不写这样一个方法,这就很矛盾了,也就是父类方法的不确定性问题

简言之,当我们有一个类,其是父类,它有一些方法我们不能确定怎么去实现,我们又不想去实现怎么办?我们就可以把这个方法做成抽象方法,把这个类做成一个抽象类,这其实就是抽象类的一个来源

抽象方法?

抽象方法其实就是没有实现的方法,那什么又叫方法没有实现呢?其实就是指没有方法体;

public abstract void eat();//这其实就是一个抽象方法
//注意! 方法一旦声明成抽象方法之后,类也必须跟着声明成抽象类,
//也可以换种表述: 当一个类中存在抽象方法时,需要将该类声明为abstract类

小结:

  • 当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法,用abstract来修饰该类就是抽象类;
  • 一般来说,抽象类会被继承,有其子类来实现抽象方法

抽象类的使用细节

抽象类不能被实例化

抽象类不一定要包含abstract方法,也就是说,抽象类可以没有abstract方法

public class Journey {
    public static void main(String[] args) {
        //报错: 'A' is abstract; cannot be instantiated
//       	 new A();
    }
}
//同时注意,此时的A就是抽象类,但是没有abstract方法,也没有报出异常
//甚至A中还可以有实现的方法
abstract class A{
    public void hi(){
        System.out.println("hi");
    }
}

一旦一个类包含了abstract方法,则这个类必须声明为abstract

abstract只能修饰类和方法,不能修饰属性和其它的;

抽象类可以有任意成员【因为抽象类本质上还是类】,比如:非抽象方法(实现了的方法),构造器,静态属性等

public class Journey {
    public static void main(String[] args) {
        System.out.println("享受每一种体验!");
    }
}
abstract class A{
    public int youth = 679;
    public static String essence = "不赶路,慢慢感受路";
    //非抽象方法(实现了的方法)
    public void hi(){
        System.out.println("哦嗨哟");
    }
    //抽象方法
    public abstract void hello();
    //静态方法
    public static void Fun(){
        System.out.println("Enjoy my life!");
    }
}
///以上代码可以正常跑出结果“享受每一种体验”

抽象方法不能有主体,即不能实现

如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类

abstract class Life{
    public abstract void Fun();
}
//报错:Class 'Youth' must either be declared abstract or implement abstract method 'Fun()' in 'Life'
//给了你两个选择,要么自己也玩抽象,要么实现Life类中的Fun方法hhhh,二选一
class Youth extends Life{ }


//solution  1:   自己也玩抽象
abstract class Youth extends Life{ }
//solution  2:   实现父类中所有的抽象方法
class Youth extends Life{
    @Override
    public void Fun() {
        
    }
}

抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的

//这个抽象方法如果用private来修饰,那么子类继承了父类,也没有机会去实现;
//同样,如果加了final,final本意就是不希望子类来重写这个方法,同样也会导致子类没有机会去重写
//以及,static其本身就是和重写无关的一个关键字,写了也是肯定不行
public abstract void Fun();

练习

在这里插入图片描述
在这里插入图片描述

先写主要的抽象类

//抽象类---Employee
abstract class Employee{
    private String name;
    private int id;
    private double salary;
    //抽象方法work()
    public abstract void work();

    public Employee(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

接下来写继承抽象类的Manager类和CommonEmployee类

class Manager extends Employee{
    private double bonus;

    public Manager(String name, int id, double salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }

    @Override
    public void work() {
        System.out.println("经理"+getName()+"正在工作");

    }
}

class CommonEmployee extends Employee{
    public CommonEmployee(String name, int id, double salary) {
        super(name, id, salary);
    }

    @Override
    public void work() {
        System.out.println("普通工人"+getName()+"正在工作中");
    }
}

最后在main方法中测试下整体效果

public class Journey {
    public static void main(String[] args) {
        Manager manager1 = new Manager("kerwin", 111, 10000, 5000);
        manager1.work();
        CommonEmployee commonEmployee1 = new CommonEmployee("jason", 112, 8000);
        commonEmployee1.work();
    }
}

//最后的输出结果
经理kerwin正在工作
普通工人jason正在工作中

抽象类的最佳实践–模板设计模式

需求1:通过方法计算1+2+…800000;(要求,最大化地考虑代码复用性)

需求2:通过方法计算1 x 2 x 3 x … x 800000;(要求,最大化地考虑代码复用性)

本来可以写两个类,然后分别实现的,但仔细考虑会发现,二者除了核心的计算方法不同外,其余的步骤都相同,可以抽象出来,所以我们考虑模板设计模式在这之中的应用

//将两个计算需求的核心给分别实现
//计算任务1+.....+800000
public class AA extends Template{
    
    @Override
    public void job() {//实现了Template的抽象方法job
        long num = 0;
        for (int i = 1; i <= 800000; i++) {
            num+= i;
        }
    }
}
//计算任务1*2*3....*800000
public class BB extends Template{
    @Override
    public void job() {//这里也重写了Template的job方法
        long num = 0;
        for (int i = 1; i <= 800000; i++) {
            num*= i;
        }
    }
}

抽象出的模板类–这就是除了计算部分外的其他二者的可复用部分

//抽象类--模板设计模式
abstract public class Template {
    //抽象方法
    public abstract void job();

    //实现了的方法,调用了job()方法
    public void calculateTime(){
        //得到开始的时间
        long start = System.currentTimeMillis();
        job();//这里涉及到动态绑定机制,动态绑定机制中调用方法,要看运行类型是哪个类其中的对象调用的job()
        //得到结束的时间
        long end = System.currentTimeMillis();
        System.out.println("任务执行时间 "+(end - start));
    }
}

最后来写个测试类,测试下

public class TestTemplate {
    public static void main(String[] args) {
        AA aa = new AA();
        aa.calculateTime();

        BB bb = new BB();
        bb.calculateTime();

    }
}
//通过跑这个测试类代码,我们就可以动态地查看两个计算需求任务所耗费的时间(输出结果用时因为各自电脑配置不同而可能导致不同)

下篇文章见!小伙伴们

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值