【继承多态练习】一个小型公司,职员有2类,第一类是按月领取薪水,第二类按照周领取薪水,请计算公司每年需要支付的员工薪水的总额

 题干

根据上述需求,程序设计公司类Company、职员类Employee、按月领取工资的员工类MonthWorker以及按周领取工资的员工类WeekWorker类,具体说明如下:

(1)Employee类:是从所有的员工抽象得到的父类。

   a)一个用protected修饰的String类型的name属性,描述员工的姓名;

   b)一个无参的构造方法;

   c)一个用于设定name属性的带参数的构造方法 Employee(String name);

   d) name属性的修改器和访问器;

   e)一个公共的计算员工年薪的方法earnings(),返回值类型为double;

   f)一个公共的toString()方法,用于输出员工的信息,返回值类型为String。

(2)MonthWorker类:按月领取薪水的员工,父类是Employee。

   a)一个私有的double类型的monthSal属性,描述员工每月的薪水;

   b)一个无参的构造方法;

   c) 一个用于设定姓名和每月薪水的带参数的构造方法 MonthWorker(String name,double monthSal);

   d) monthSal属性的修改器和访问器;

   e)重写父类的earnings()方法,计算员工的年薪;

   f)重写父类的toString():输出员工的信息。

(3) WeekWorker类:按周领取薪水的员工,父类是Employee。

   a)一个私有的double类型的weekSal属性,描述员工每周的薪水;

   b)一个无参的构造方法;

   c) 一个用于设定姓名和每周薪水的带参数的构造方法 WeekWorker(String name,double weekSal);

   d) weekSal属性的修改器和访问器;

   e)重写父类的earnings()方法,计算员工的年薪,假设一年52个周;

   f)重写父类的toString():输出员工的信息。

(4) Company类:公司类.

   a)一个私有的Employee对象数组,用于存放公司员工,数组中的元素可以是MonthWorker对象,也可以是WeekWorker对象;

   b)一个私有的用于记录员工人数的数据域numberOfWorkers,初始值为0;

   c)一个无参的构造方法; 

   d)一个公共的用于计算公司每年需要支付的员工薪水总额的方法 computeTotalSal(),返回值为double;

   e)一个公共的用于添加单个员工的方法 addEmployee(Employee e),无返回值;

   f)一个公共的toString()方法,返回公司员工信息和每年需要支付的员工薪水总额。

【试题输入输出】

(1) 编写测试类TestCompany,要求如下:

   a) 创建公司对象;

   b)创建一个MonthWorker对象和一个WeekWorker对象,从键盘读入两个员工的姓名和薪水;

   c)将两个员工添加至公司。

(2) 按照如下样例输出结果:


遇到的问题及解决方法

1.一个公共的toString()方法,用于输出员工的信息,返回值类型为String
public double earnings() {
                 return  0.0;
              }

2.一个私有的Employee对象数组,用于存放公司员工,数组中的元素可以是MonthWorker对象,也可以是WeekWorker对象
 private Employee[] workers;

只要给个名字就可以啦~

3.一个公共的用于计算公司每年需要支付的员工薪水总额的方法 computeTotalSal(),返回值为double

3.1

return MonthWorker[] * 12 * monthSal + WeekWorker[] * 52 * weekSal ;

问题是:

[1]. 将MonthWorker和WeekWorker视为数组,而实际上它们应该是代表公司中的员工类型。
[2].没有明确地计算每种类型员工的数量,而是直接将它们当做数组来处理 
[3].混淆了员工的工作时间单位(月薪和周薪)和员工的数量,这导致了计算错误。
 workers[i].earnings();

在这段代码中,workers是一个数组,存储了公司中的所有员工对象。而earnings()则是一个方法,用于计算每个员工的薪水。通过workers[i]表示获取数组中第i个位置的员工对象,然后调用该员工对象的earnings()方法来获取该员工的薪水。

利用了面向对象编程的特性,将数据和操作封装在对象中,通过对象的方法来访问和操作数据

正确的:

public double computeTotalSal() {
        double total = 0.0;
        for (int i = 0; i < numberOfWorkers; i++) {
            total += workers[i].earnings();
        }
        return total;
    }

3.2

for(int i=0 ; i < numberOfWorkers ; i++)
        {
            totel += workers[].earnings ;
        }

问题是:

[1]在workers[].earnings中使用了一个空的方括号[]。在这里,应该使用方括号来指定具体的索引值,以访问workers数组中的每个员工对象。例如,可以使用workers[i].earnings来访问数组中的第i个员工的薪水。

[2]应该是earnings方法,要有()

4.一个公共的用于添加单个员工的方法 addEmployee(Employee e),无返回值
[1]将传入的员工对象e赋值给workers[numberOfWorkers],即将员工对象放入员工数组的下一个位置。
[2]numberOfWorkers变量的值加1,表示员工数组中的员工数量增加了一个。

[3] Employee e是一个参数名。在方法addEmployee(Employee e)中,Employee e表示该方法接受一个Employee类型的参数,这个参数的名称是e。在方法被调用时,可以传入一个Employee对象作为参数。

通过这个方法,您可以将新的员工对象添加到员工数组中,并通过numberOfWorkers变量来跟踪员工数量。请确保在使用这个方法之前,已经正确地初始化了workers数组和numberOfWorkers变量

例如,在调用addEmployee(Employee e)方法时,可以传入一个Employee对象:

Employee employee1 = new Employee("John Doe", 1000);
addEmployee(employee1);

在这个例子中,employee1是一个Employee对象,通过调用addEmployee(employee1)方法将这个员工对象添加到员工数组中。

5.一个公共的toString()方法,返回公司员工信息和每年需要支付的员工薪水总额

   添加一个换行符和描述性文本“每年需要支付的员工薪水总额: ”到StringBuilder中,然后调用computeTotalSal()方法计算公司每年需要支付的员工薪水总额,并将其添加到StringBuilder中:

 public String toString() {

 // 创建一个StringBuilder对象
StringBuilder info = new StringBuilder();

// 添加描述性文本和换行符到StringBuilder中
info.append("每年需要支付的员工薪水总额: ").append("\n");

// 调用computeTotalSal()方法计算薪水总额并添加到StringBuilder中
double totalSalary = computeTotalSal();
info.append("总额: ").append(totalSalary).append("\n");

// 将StringBuilder对象转换为字符串并返回
return info.toString();
    }
StringBuilder

在Java中,StringBuilder类用于处理字符串的可变性,即在字符串被创建之后,可以对其内容进行更改。在toString()方法中使用StringBuilder通常是为了拼接多个字符串,并且避免创建多个不必要的String对象,提高性能。

在这个具体的情况下,toString()方法需要返回一个包含公司员工信息和每年需要支付的员工薪水总额的字符串。由于这个字符串是通过拼接多个部分组成的,而且每个部分都可能会动态改变(比如员工数量可能会变化,薪水总额也会改变),使用StringBuilder是一个很好的选择。

当需要动态拼接多个字符串并且不想频繁地创建新的String对象时,StringBuilder就是一个很好的选择。它提供了append()方法,可以高效地将新内容添加到当前字符串的末尾。

因此,在toString()方法中使用StringBuilder是为了拼接并构建一个包含员工信息和薪水总额的字符串,同时保持性能和效率。

对于不熟悉Java编程语言的人来说,StringBuilder可能会有些陌生。让我用更简单的话来解释一下:

在Java中,StringBuilder是一个用来处理字符串的工具,它可以让我们方便地拼接多个字符串片段成一个完整的字符串。在这种情况下,我们使用StringBuilder来构建一个包含员工信息和薪水总额的字符串。

StringBuilder info = new StringBuilder(); 这行代码的意思是:创建一个名为info的StringBuilder对象,用来存储我们要构建的字符串。这个对象可以不断地添加新的内容,并最终将它们组合成一个完整的字符串。

简而言之,StringBuilder是一个用来构建字符串的工具,通过不断添加内容,最终得到一个完整的字符串。

在Java的StringBuilder类中,append()方法用于将指定内容添加到StringBuilder对象的末尾。这个方法可以接受多种类型的参数,比如字符串、字符、数字等,将其转换为字符串形式并添加到StringBuilder对象的末尾。

在代码中,info.append(workers[i].toString()).append("\n");这行代码中的append(workers[i].toString())表示将当前遍历到的员工对象的信息(通过调用其toString()方法转换为字符串形式)添加到info StringBuilder对象的末尾。而.append("\n")则表示在员工信息之后再添加一个换行符,用于确保每个员工的信息都单独占据一行。

总而言之,append()方法是用于在StringBuilder对象中添加内容的方法,可以将不同类型的数据转换为字符串并追加到当前字符串的末尾。

在Java的StringBuilder类中,toString()方法用于将StringBuilder对象转换为一个字符串。当我们在StringBuilder对象上调用toString()方法时,它会返回一个包含StringBuilder对象中所有内容的字符串。return info.toString();这行代码表示将之前构建好的包含员工信息的StringBuilder对象info转换为一个字符串,并将该字符串作为方法的返回值。换句话说,这行代码的作用是将之前拼接好的员工信息字符串返回给调用该方法的地方。

总之,toString()方法用于将StringBuilder对象转换为字符串,使得我们可以将StringBuilder对象中的内容以字符串的形式输出或返回。

  1. workers[i]表示一个员工对象数组中的第i个员工对象。

  2. workers[i].toString()表示将这个员工对象转换为字符串形式。

  3. info.append(workers[i].toString())表示将上一步得到的员工信息字符串添加到StringBuilder对象info的末尾。

  4. .append("\n")表示在刚刚添加的员工信息字符串之后再添加一个换行符,即换行到下一行。

因此,这行代码的作用是将第i个员工对象的信息转换为字符串并添加到StringBuilder对象info的末尾,同时在每个员工信息后面添加一个换行符,确保每个员工的信息都单独显示在一行上。

NEXT DAY

【1】StringBuilder忘记了

【2】循环是为了每一个人的信息独占一行

【3】循环之后要用append连接文本+数字;

6.调用父类的toString方法
在Java中,toString()方法是Object类中的一个方法,用于返回对象的字符串表示形式。

super.toString()调用了父类ObjecttoString()方法,以获取默认的对象字符串表示形式。然后,使用字符串拼接的方式,将一些额外的员工信息添加到父类的字符串表示形式中。

重写toString()方法的目的是为了方便调试和输出对象信息,使得输出的信息更加有意义和易读。通过自定义toString()方法,可以根据具体的需求来定义对象的字符串表示形式,以便更好地满足程序的需求。

public String toString() {
        return super.toString() + "\n周薪为 " + weekSal + "\n年薪为 " + earnings();
    }
7.关键字super
[1]   调用父类构造方法
class Animal {
    public Animal() {
        System.out.println("Animal constructor");
    }
}

class Dog extends Animal {
    public Dog() {
        super(); // 调用父类的构造方法
        System.out.println("Dog constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}

在上面的示例中,Dog类继承自Animal类,通过super()调用了父类Animal的构造方法。

[2]   调用父类成员方法
class Animal {
    public void sound() {
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    public void sound() {
        super.sound(); // 调用父类的成员方法
        System.out.println("Dog sound");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();
    }
}

在上面的示例中,Dog类继承自Animal类,通过super.sound()调用了父类Animalsound()方法。

[3] 访问父类成员变量
class Animal {
    protected String name = "Animal";
}

class Dog extends Animal {
    public void showName() {
        System.out.println("Parent class variable: " + super.name);
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.showName();
    }
}

在上面的示例中,Dog类继承自Animal类,通过super.name访问了父类Animalname成员变量。

8.创建一个MonthWorker对象和一个WeekWorker对象,从键盘读入两个员工的姓名和薪水

 创建新的要有关键字【new】 并且  要建立新的对象【weekWorker】

WeekWorker weekWorker = new WeekWorker(name2,weekSal);

总结

addEmployee(Employee e)

StringBuilder

append方法


代码如下

import java.util.Scanner;

class Employee {
    protected String name;

    public Employee() {}

    public Employee(String name) {
        this.name = name;
    }

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

    public String getName() {
        return name;
    }

    public double earnings() {
        return 0.0;
    }

    public String toString() {
        return "姓名 " + name;
    }
}

class MonthWorker extends Employee {
    private double monthSal;

    public MonthWorker(String name, double monthSal) {
        super(name);
        this.monthSal = monthSal;
    }

    public void setMonthSal(double monthSal) {
        this.monthSal = monthSal;
    }

    public double earnings() {
        return monthSal * 12;
    }

    public String toString() {
        return super.toString() + "\n月薪为 " + monthSal + "\n年薪为 " + earnings();
    }
}

class WeekWorker extends Employee {
    private double weekSal;

    public WeekWorker(String name, double weekSal) {
        super(name);
        this.weekSal = weekSal;
    }

    public void setWeekSal(double weekSal) {
        this.weekSal = weekSal;
    }

    public double earnings() {
        return weekSal * 52;
    }

    public String toString() {
        return super.toString() + "\n周薪为 " + weekSal + "\n年薪为 " + earnings();
    }
}

class Company {
    private Employee[] workers;
    private int numberOfWorkers;

    public Company() {
        workers = new Employee[10];
        numberOfWorkers = 0;
    }

    public double computeTotalSal() {
        double total = 0.0;
        for (int i = 0; i < numberOfWorkers; i++) {
            total += workers[i].earnings();
        }
        return total;
    }

    public void addEmployee(Employee e) {
        workers[numberOfWorkers] = e;
        numberOfWorkers++;
    }

    public String toString() {
        StringBuilder info = new StringBuilder();
        for (int i = 0; i < numberOfWorkers; i++) {
            info.append(workers[i].toString()).append("\n");
        }
        info.append("\n公司年工资总额 ").append(computeTotalSal());
        return info.toString();
    }
}

public class TestCompany {
    public static void main(String[] args) {
        Company company = new Company();
        @SuppressWarnings("resource")
        Scanner scanner = new Scanner(System.in);

        String name1 = scanner.next();
        double monthSal = scanner.nextDouble();
        String name2 = scanner.next();
        double weekSal = scanner.nextDouble();

        MonthWorker monthWorker = new MonthWorker(name1, monthSal);
        WeekWorker weekWorker = new WeekWorker(name2, weekSal);

        company.addEmployee(monthWorker);
        company.addEmployee(weekWorker);

        System.out.println(company);
    }
}

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-24 22:24:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-24 22:24:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-24 22:24:03       87 阅读
  4. Python语言-面向对象

    2024-04-24 22:24:03       96 阅读

热门阅读

  1. neo4j的Cypher的语法记录

    2024-04-24 22:24:03       35 阅读
  2. 模拟LinkedList实现的链表(无哨兵)

    2024-04-24 22:24:03       34 阅读
  3. cuda总结

    2024-04-24 22:24:03       34 阅读
  4. GitLab 查看版本信息

    2024-04-24 22:24:03       36 阅读
  5. 002 fanout

    2024-04-24 22:24:03       35 阅读
  6. jh7110 visionfive2 linux uboot debian

    2024-04-24 22:24:03       38 阅读
  7. k8s的网络组件有哪些,他们的作用分别是什么

    2024-04-24 22:24:03       34 阅读
  8. Python语言第五章之字符串

    2024-04-24 22:24:03       36 阅读
  9. 5359: 【图论】有向图连接边数(图的遍历前置)

    2024-04-24 22:24:03       29 阅读