面向对象-抽象类和抽象方法及练习

抽象类

  • 用abstract关键字修饰的类,叫做抽象类
  • 抽象类不能被实例化
  • 抽象类是用来被继承的
  • 抽象类的子类必须要重写父类的方法并提供方法体

抽象方法

  • 用abstract关键字来修饰的方法,叫做抽象方法
  • 抽象方法只有方法声明,没有实现方法,直接使用分号结尾,如:
public abstract void say();
  • 如果一个类中含有抽象方法,那么这个类必须被声明为抽象类

Tips:

  • abstract不能用来修饰变量、代码块和构造器
  • abstract不能用来修饰私有、静态、final方法和final类

模板方法设计模式

  • 通过子类继承抽象类,抽象类可以作为多个子类的通用的模板,每一个子类必须重写抽象类中的抽象方法,也可以进行拓展和改造,体现了一种模板模式的设计。
  • 通过这种方法,可以在编写一些部分内容很不确定容易改变的方法时,在父类中使用抽象方法写好,再在子类中将这些易变的方法具体化实现。

练习:

编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个
Employee对象的生日,则将该雇员的工资增加100元。
实验说明:
(1)定义一个Employee类,该类包含:
private成员变量name,number,birthday,其中birthdayMyDate类的对象;
abstract方法earnings();
toString()方法输出对象的name,numberbirthday
(2)MyDate类包含:
private成员变量year,month,day
toDateString()方法返回日期对应的字符串:xxxxxxxx
(3)定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处
理。该类包括:private成员变量monthlySalary
实现父类的抽象方法earnings(),该方法返回monthlySalary值;toString()方法输
出员工类型信息及员工的
name,number,birthday

(4)参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的
员工处理。该类包括:
private成员变量wagehour
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday
(5)定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各
类雇员对象的引用。利用循环结构遍历数组元素,输出各个对象的类
型,name,number,birthday,以及该对象生日。当键盘输入本月月份值时,如果本
月是某个Employee对象的生日,还要输出增加工资信息。
提示:
//定义People类型的数组People c1[]=new People[10];
//数组元素赋值
c1[0]=new People(“John”,“0001”,20);
c1[1]=new People(“Bob”,“0002”,19);
//若People有两个子类Student和Officer,则数组元素赋值时,可以使父类类型的数组元素指向子类。
c1[0]=new Student(“John”,“0001”,20,85.0);
c1[1]=new Officer(“Bob”,“0002”,19,90.5);

代码部分
Employee类
package Employee;

public abstract class Employee {
	//姓名
    private String name;
    //编号
    private String number;
    //生日
    private MyData birthday;

	//创建一个有参构造器
    public Employee(String name, String number, MyData birthday) {
        this.name = name;
        this.number = number;
        this.birthday = birthday;
    }

	//定义一个抽象方法earnings();
    public abstract double earnings();

	//使用get、set方法存取属性
    public String getName() {
        return name;
    }

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

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public MyData getBirthday() {
        return birthday;
    }

    public void setBirthday(MyData birthday) {
        this.birthday = birthday;
    }

	//toString()方法输出对象的name,number和birthday
    public String toString() {
        return "姓名: " + name +
                ", 编号: " + number +
                ", 生日: " + birthday;
    }
}
MyData类
package Employee;

public class MyData {
	//年
    private int year;
    //月
    private int month;
    //日
    private int day;

	//toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
    public String toDataString() {
        return year + "年" + month + "月" + day + "日";
    }

    public MyData(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

	//使用get、set方法存取属性
    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }
}

SalariedEmployee类
package Employee;

public class SalariedEmployee extends Employee{
	//每月工资
    private double monthlySalary;

    public SalariedEmployee(String name, String number, MyData birthday,double monthlySalary) {
        super(name, number, birthday);
        this.monthlySalary = monthlySalary;
    }

	//实现父类的抽象方法earnings(),该方法返回monthlySalary值
    public double earnings() {
        return monthlySalary;
    }
	//使用get、set存取每月工资属性
    public double getMonthlySalary() {
        return monthlySalary;
    }

    public void setMonthlySalary(double monthlySalary) {
        this.monthlySalary = monthlySalary;
    }

	//toString()方法输出员工类型信息及员工的name,number,birthday
    public String toString() {
        return "按月结算的员工: 姓名:" +this.getName()+"  编号: "+this.getNumber()+"  生日: "+ this.getBirthday().getYear() +"年"+this.getBirthday().getMonth()+"月"+this.getBirthday().getDay()+"日  月工资: "+ this.earnings() ;
    }
}

HourlyEmployee 类
package Employee;

public class HourlyEmployee extends Employee {
	//日结算工资
    private double hourlySalary;
    //每日工作时间
    private int hour;
    //每小时工钱
    private double wage;

    public HourlyEmployee(String name, String number, MyData birthday,int hour,double wage) {
        super(name, number, birthday);
        this.hour = hour;
        this.wage = wage;
    }

	//重写earnings方法返回每日工资
    public double earnings() {
        hourlySalary = wage * hour;
        return hourlySalary;
    }

	//使用get、set存取各项属性
    public double getHourlySalary() {
        return hourlySalary;
    }

    public void setHourlySalary(double hourlySalary) {
        this.hourlySalary = hourlySalary;
    }

    public int getHour() {
        return hour;
    }

    public void setHour(int hour) {
        this.hour = hour;
    }

    public double getWage() {
        return wage;
    }

    public void setWage(double wage) {
        this.wage = wage;
    }
	
	//toString()方法输出员工类型信息及员工的name,number,birthday
    public String toString() {
        return "按小时结算的员工: 姓名:" + this.getName() + "  编号: " + this.getNumber() + "  生日: " + this.getBirthday().getYear() +"年"+this.getBirthday().getMonth()+"月"+this.getBirthday().getDay()+"日  日工资: " + this.earnings();
    }
}

PayrollSystem类
package Employee;


import java.util.Scanner;

public class PayrollSystem {

    public static void main(String[] args) {
    	//创建Employee变量数组并初始化
        Employee[] employees = new Employee[10];

		//给数组元素赋值
        employees[0] = new SalariedEmployee("打工嘉禾", "0001", new MyData(2021, 01, 10), 10000);
        employees[1] = new SalariedEmployee("打工老王", "0002", new MyData(2021, 02, 11), 10005);
        employees[2] = new SalariedEmployee("打工大哥", "0003", new MyData(2021, 03, 12), 10001);
        employees[3] = new HourlyEmployee("打工万军", "0004", new MyData(2021, 04, 13), 9, 100);
        employees[4] = new HourlyEmployee("打工葡萄籽", "0005", new MyData(2021, 05, 14), 10, 1000);
        employees[5] = new HourlyEmployee("不打工的我,每天花一个小时看看别人打没打工", "0000", new MyData(2021, 06, 15), 1, 20000000);
        
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入当月月份:");
        int nowMonth = scanner.nextInt();
        System.out.println("公司员工有:");
        //循环遍历数组输出数组内容(员工信息)
        for (int i = 0; i < employees.length; i++) {
        	//数组为空不执行
            if (employees[i] == null) {
                continue;
            } else {
                System.out.println(employees[i].toString());
                //判断当月是生日,额外打印一行加工资的提示
                if (nowMonth == employees[i].getBirthday().getMonth()) {
                    System.out.println("恭喜" + employees[i].getName() + "这个B,在这个月有生日,给他加100比特币");
                }
            }
        }
    }
}

总结

通过该次练习,对抽象类和抽象方法的理解程度有了提升,对之后的代码学习有很大帮助。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没谱的曲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值