首页 > 编程语言 >【Java】—— Java面向对象高级:抽象类与抽象方法(或abstract关键字)

【Java】—— Java面向对象高级:抽象类与抽象方法(或abstract关键字)

时间:2024-09-12 22:24:02浏览次数:10  
标签:Java name int abstract number birthday 抽象类 方法 public

目录

6. 抽象类与抽象方法(或abstract关键字)

6.1 由来

6.2 语法格式

6.3 使用说明

6.4 注意事项

练习:工资系统设计

(1)MyDate类包含:

(2)定义一个Employee类,该类包含:

(3)定义SalariedEmployee类继承Employee类,

(4)参照SalariedEmployee类定义HourlyEmployee类,

(5)定义PayrollSystem类,

具体实现

​运行实例


6. 抽象类与抽象方法(或abstract关键字)

6.1 由来

举例1:

        随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

举例2:

        我们声明一些几何图形类:圆、矩形、三角形类等,发现这些类都有共同特征:求面积、求周长。那么这些共同特征应该抽取到一个共同父类:几何图形类中。但是这些方法在父类中又无法给出具体的实现,而是应该交给子类各自具体实现。那么父类在声明这些方法时,就只有方法签名,没有方法体,我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类必须是抽象类

6.2 语法格式

  • 抽象类:被abstract修饰的类。

  • 抽象方法:被abstract修饰没有方法体的方法。

抽象类的语法格式

[权限修饰符]   abstract   class   类名{
    
}
[权限修饰符]   abstract   class   l类名   extends   父类{
    
}

抽象方法的语法格式

[其他修饰符]   abstract   返回值类型   方法名([形参列表]);

注意:抽象方法没有方法体

代码举例:

public abstract class Animal {
    public abstract void eat();
}

public class Cat extends Animal {
    public void eat (){
          System.out.println("小猫吃鱼和猫粮"); 
    }
}

public class CatTest {
      public static void main(String[] args) {
        // 创建子类对象
        Cat c = new Cat(); 
       
        // 调用eat方法
        c.eat();
      }
}

此时的方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法

6.3 使用说明

  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象

    理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

    抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。

  2. 抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。

    理解:子类的构造方法中,有默认的super()或手动的super(实参列表),需要访问父类构造方法。

  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。

    理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

6.4 注意事项

  • 不能用abstract修饰变量、代码块、构造器;

  • 不能用abstract修饰私有方法、静态方法、final的方法、final的类。

练习:工资系统设计

编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个Employee对象的生日,则将该雇员的工资增加100元。

实验说明:

(1)MyDate类包含:

        private成员变量year,month,day ;

        提供必要的构造器        

        toDateString()方法返回日期对应的字符串:xxxx年xx月xx日

(2)定义一个Employee类,该类包含:

        private成员变量name,number,birthday,其中birthday 为MyDate类的对象;

        提供必要的构造器      

        abstract方法earnings();

        toString()方法输出对象的name,number和birthday。

(3)定义SalariedEmployee类继承Employee类,

        实现按月计算工资的员工处理。该类包括:private成员变量monthlySalary;

        提供必要的构造器      

        实现父类的抽象方法earnings(),该方法返回monthlySalary值;

        toString()方法输出员工类型信息及员工的name,number,birthday。

(4)参照SalariedEmployee类定义HourlyEmployee类,

        实现按小时计算工资的员工处理。该类包括:

        private成员变量wage和hour;

        提供必要的构造器      

        实现父类的抽象方法earnings(),该方法返回wage*hour值;

        toString()方法输出员工类型信息及员工的name,number,birthday。

(5)定义PayrollSystem类,

创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日。当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。

具体实现


MyDate类

package exer3;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *
 *      2)MyDate类包含:
 *      private成员变量year,month,day ;
 *      提供必要的构造器
 *      toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
 *
 * @Author zyjstart
 * @Create:2024/9/12 16:59
 */
public class MyDate {
    private int year;
    private int month;
    private int day;

    //构造器
    public MyDate() {
    }

    public MyDate(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;
    }

    public String toDateString(){
        return year + "年" + month + "月" + day + "日";
    }
}

Employee类

package exer3;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *       (1)定义一个Employee类,该类包含:
 *     private成员变量name,number,birthday,其中birthday 为MyDate类的对象;
 *     提供必要的构造器
 *     abstract方法earnings(),返回工资数额
 *     toString()方法输出对象的name,number和birthday。
 *
 * @Author zyjstart
 * @Create:2024/9/12 16:57
 */
public abstract class Employee {
    private String name;
    private int number;
    private MyDate birthday;

    // 构造器
    public Employee() {
    }

    public Employee(String name, int number, MyDate birthday) {
        this.name = name;
        this.number = number;
        this.birthday = birthday;
    }

    // get、set方法
    public String getName() {
        return name;
    }

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

    public int getNumber() {
        return number;
    }

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

    public MyDate getBirthday() {
        return birthday;
    }

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

    // abstract方法earnings(),返回工资数额
    public abstract double earnings();

    // toString()方法输出对象的name,number和birthday。
    public String toString(){
        return "name = " + name + ", number = "+ number + ", birthday = " + birthday.toDateString();
    }
}
SalariedEmployee类
package exer3;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处理。
 *      该类包括:private成员变量monthlySalary;
 *      提供必要的构造器
 *      实现父类的抽象方法earnings(),该方法返回monthlySalary值;
 *      toString()方法输出员工类型信息及员工的name,number,birthday。
 * @Author zyjstart
 * @Create:2024/9/12 17:09
 */
public class SalariedEmployee extends Employee{
    private double monthlySalary;   //月工资
    // 构造器
    public SalariedEmployee() {
    }

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

    // get  set 方法
    public double getMonthlySalary() {
        return monthlySalary;
    }

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

    // 实现父类的抽象方法earnings(),该方法返回monthlySalary值;
    @Override
    public double earnings() {
        return monthlySalary;
    }

    // toString()方法输出员工类型信息及员工的name,number,birthday
    public String toString(){
        return "SalariedEmployee[" + super.toString() + "]";
    }
}
HourlyEmployee类
package exer3;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。
 *      该类包括:private成员变量wage和hour;
 *      提供必要的构造器
 *      实现父类的抽象方法earnings(),该方法返回wage*hour值;
 *      toString()方法输出员工类型信息及员工的name,number,birthday。
 * @Author zyjstart
 * @Create:2024/9/12 17:19
 */
public class HourlyEmployee extends Employee{
    private double wage;    // 单位小时的工资
    private  int hour;      // 月工作小时数

    // 构造器
    public HourlyEmployee() {
    }

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

    // get、set方法
    public double getWage() {
        return wage;
    }

    public void setWage(double wage) {
        this.wage = wage;
    }

    public int getHour() {
        return hour;
    }

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

    // 实现父类的抽象方法earnings(),该方法返回wage*hour值;
    @Override
    public double earnings() {
        return wage * hour;
    }

    // toString()方法输出员工类型信息及员工的name,number,birthday。
    public String toString(){
        return "HourlyEmployee[" + super.toString() + "]";
    }
}
PayrollSystem类
package exer3;

import java.util.Scanner;

/**
 * ClassName:IntelliJ IDEA
 * Description:
 *      定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。
 *      利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,
 *      当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
 * @Author zyjstart
 * @Create:2024/9/12 17:24
 */
public class PayrollSystem {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);


        //1、创建Employee变量数组并初始化
        Employee[] emps = new Employee[2];
        // 这里使用到多态
        emps[0] = new SalariedEmployee("林一",1001,new MyDate(2002,8,02),18000);
        emps[1] = new HourlyEmployee("林二",1002,new MyDate(1998,12,19),18,240);

        System.out.println("请输入当前的月份:");
        int month = sc.nextInt();

        // 2、用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday
        for (int i = 0; i < emps.length; i++) {
            System.out.println(emps[i].toString());
            System.out.println("工资为:" + emps[i].earnings());

            // 3、当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
            if(month == emps[i].getBirthday().getMonth()){
                System.out.println("生日快乐! 加薪200");
            }
        }
        sc.close();

    }

}
​运行实例

标签:Java,name,int,abstract,number,birthday,抽象类,方法,public
From: https://blog.csdn.net/weixin_63106307/article/details/142186336

相关文章

  • JAVA基础知识
    JAVA版本(Oracle甲骨文)标准版(JZSE)微缩版(JZME)企业版(JZEE)JAVA特性跨平台、安全、简单、面向对象(封装、继承、多态)、动态特性、分布式JDK(JAVA开发工具)---JRE(JAVA运行环境)---JVE(JAVA虚拟机)JVM是可运行java字节码的假想计算机基于下层操作系统和硬件平台功能:执行代码、管理内......
  • Java面试笔记记录6
    1.Spring是什么?特性?有哪些模块?Spring是一个轻量级、非入侵式的控制反转Ioc和面向切面AOP的框架。特性:1.Ioc和DISpring的核心就是一个大的工厂容器,可以维护所有对象的创建和依赖关系,Spring工厂用于生成Bean,并且管理Bean的生命周期,实现高内聚低耦合的设计理念。2.AOP编程Sp......
  • JavaScript语法入门五 常量
    常量声明一个常量就是声明一个常数。声明之后就不能修改(不能通过重新赋值进行修改)。使用const关键字。该关键字是ES6新增加的关键字。用const声明常量时,必须初始化。例子1:constmyBirthday='18.06.1981';例子2:<script> constPERSON='jack' {   constPERSON='tom' ......
  • JavaWeb
    课程学习路线,重点在后端。学习可以掌握能力Web工作流程,不同的浏览器,内核不同,对于相同的前端代码解析的效果会存在差异。Web标准HTML:负责网页的结构。CSS:负责网页的表现。JS:负责网页的行为。HTML、CSS快速入门在文件夹中新建一个后缀为html的文本文件,输入以下代码,就能在浏览器打开......
  • java方法:什么是方法?
    java方法是语句的集合,它们在一起执行一个功能:方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用例如:即______()是方法设计方法的原则:方法的本意时功能块,就是实现某个功能块,就是实现某个功能的语句块的集合,所以最好保持方法的......
  • 基于java+ssm+vue的大学生社团活动管理微信小程序
    项目介绍随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了基于大学生社团活动管理的微信小程序的开发全过程。通过分析大学生社团活动管理的不足,创建了一个计算机管理基于大学生社团活动管理的微信小程序的方案。文章介绍了基......
  • 基于java+springboot+vue的校园失物招领系统
    ......
  • 关于java学习基础路线的分享【javaSE】
    成长路上不孤单......
  • java学习第一天
    java定义指针ctrl+a全选classhellword(//class 定义一个类名,类名和文件名可以不一样//写了多少个class类,就有多少个class文件 publicstaticvoidmain(string[]args){ System.out.println("hello,world")})​```编译刷时候要有后缀名```classdemo{ publ......
  • Java 假设有一个对象list 有4列,4和3比较name 如果name不相同则记录4的version值string
    可以使用传统循环或Java8的流(Stream)API来实现这一逻辑。以下是这两种方法的示例代码:1.使用传统循环importjava.util.List;publicclassMain{publicstaticvoidmain(String[]args){List<MyObject>list=...;//初始对象列表String......