首页 > 其他分享 >超类与子类续1

超类与子类续1

时间:2024-10-31 11:22:36浏览次数:3  
标签:name int 子类 getSalary 超类 Employee new public

参考《Java核心技术卷1》

多态与动态绑定

Employee.java

package inheritance;

import java.time.LocalDate;

public class Employee {
    private final String name; // 姓名
    private double salary; // 薪水
    private final LocalDate hireDay; // 入职日期

    public Employee(String name, double salary, int year, int month, int day) {
        this.name = name;
        this.salary = salary;
        hireDay = LocalDate.of(year, month, day);
    }

    public String getName() {
        return name;
    }

    public double getSalary() {
        return salary;
    }

    public LocalDate getHireDay() {
        return hireDay;
    }

    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
}

经理.java

package inheritance;

public class Manager extends Employee {
    private double bonus; // 奖金

    public Manager(String name, double salary, int year, int month, int day) {
        super(name, salary, year, month, day);
    }

    public double getSalary() {
        double baseSalary = super.getSalary(); // 获取基本工资
        return baseSalary + bonus; // 薪水=基本工资+奖金
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
}

经理Test.java

package inheritance;

public class ManagerTest {
    public static void main(String[] args) {
        Manager boss = new Manager("张三", 8000, 2017, 12, 15);
        boss.setBonus(500);
        Employee[] staff = new Employee[3];
        staff[0] = boss;
        staff[1] = new Employee("李四", 5000, 2019, 10, 1);
        staff[2] = new Employee("王五", 4000, 2020, 3, 15);
        for (Employee e : staff) {
            System.out.printf("%s, %.2f\n", e.getName(), e.getSalary());
        }
    }
}

输出:

张三, 8500.00
李四, 5000.00
王五, 4000.00

这里的e被声明为Employee类型,却引用了Manager类型的对象!这是合法的。并且,观察执行结果,e.getSalary()会选出正确的getSalary方法。

进一步简化、改写代码:

package inheritance;

public class ManagerTest {
    public static void main(String[] args) {
        Manager boss = new Manager("张三", 8000, 2017, 12, 15);
        boss.setBonus(500);

        Employee e = new Employee("李四", 5000, 2019, 10, 1);;
        System.out.printf("%s, %.2f\n", e.getName(), e.getSalary());
        // => 李四, 5000.00

        e = boss;
        System.out.printf("%s, %.2f\n", e.getName(), e.getSalary());
        // => 张三, 8500.00
    }
}

实际上,e既可以引用Employee类型的对象,也可以引用Manager类型的对象。

当e引用Employee对象时,e.getSalary()调用的是Employee类中的getSalary方法;当e引用Manager对象时,e.getSalary()调用的则是Manager类中的getSalary方法。虚拟机知道e实际引用的对象类型,因此能够调用正确的方法。

一个对象变量(例如,变量e)可以指示多种实际类型,这一点称为多态(polymorphism)。在运行时能够自动地选择适当的方法,这称为动态绑定(dynamic binding)。

继承层次结构

秘书.java

package inheritance;

public class Secretary extends Employee {
    public Secretary(String name, double salary, int year, int month, int day) {
        super(name, salary, year, month, day);
    }

    @Override
    public double getSalary() {
        System.out.println("秘书类中定义的getSalary被调用了");
        return super.getSalary();
    }
}

总经理Test.java

package inheritance;

public class ExecutiveTest {
    public static void main(String[] args) {
        Employee[] staff = new Employee[3];
        staff[0] = new Secretary("小张三", 8000, 2024, 10, 10);
        staff[1] = new Programmer("李四儿", 20000, 2024, 10, 10);
        staff[2] = new Executive("小王五", 15000, 2024, 10, 10);

        for (Employee e : staff) {
            System.out.printf("%s, %.2f\n", e.getName(), e.getSalary());
        }
        // 上面循环语句的等价顺序语句是什么?写完后请改成等价的顺序语句

        // 一个对象变量可以指示多种实际类型即"多态"
    }
}

多态

package inheritance;

public class MyTest {
    public static void main(String[] args) {
        // 1 可将子类对象赋给超类变量
        Employee e;
        e = new Employee("张三", 1000, 2024, 9, 30); //"需要"一个员工类对象
        e = new Manager("李四", 1000, 2024, 9, 30); //把经理类放这边也可以

        // 2 当超类变量引用子类对象可以调用哪些方法?
        Manager m = new Manager("李大头", 1000, 2024, 9, 30);
        Employee aEmployee = m; //m与aEmployee引用了同一个对象!
        //但"编译器"只将aEmployee看成是一个Employee对象
        m.setBonus(500); //m是Manager类变量,调用Manager类中定义的方法是合法的!
        //aEmployee.setBonus(500); //这句合法吗?如果不合法是为什么?

        // 3 子类变量不能引用超类对象
        //Manager manager = new Employee("李大头", 1000, 2024, 9, 30);
        //上面代码能运行吗?如果如果不能原因是什么?
        //怎样解决该问题?前提是什么?
    }
}

PrimaryStudent练习

https://liaoxuefeng.com/books/java/oop/basic/inherit/index.html

public class Main {
    public static void main(String[] args) {
        Person p = new Person("小明", 12);
        Student s = new Student("小红", 20, 99);
        // TODO: 定义PrimaryStudent,从Student继承,新增grade字段:
        Student ps = new PrimaryStudent("小军", 9, 100, 5);
        System.out.println(ps.getScore());
    }
}

class Person {
    protected String name;
    protected int age;

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

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

    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}

class Student extends Person {
    protected int score;

    public Student(String name, int age, int score) {
        super(name, age);
        this.score = score;
    }

    public int getScore() { return score; }
}

class PrimaryStudent extends Student {
    protected int grade;

    public PrimaryStudent(String name, int age, int score, int grade) {
        super(name, age, score);
        this.grade = grade;
    }
}

 

标签:name,int,子类,getSalary,超类,Employee,new,public
From: https://www.cnblogs.com/xkxf/p/18515122

相关文章

  • 鸿蒙多语言智能输入法设计:动态切换子类型与实时翻译功能
    本文旨在深入探讨多语言智能输入法的设计与实现,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在全球化的今天,多语言智能输入法成为了人们跨语言交流的重要工......
  • 鸿蒙多语言智能输入法设计:动态切换子类型与实时翻译功能
    本文旨在深入探讨多语言智能输入法的设计与实现,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。在全球化的今天,多语言智能输入法成为了人们跨语言交流的......
  • 计算机网络(们)和 Internet (计算机网络的子类)
    计算机网络101计算机网络,属于网络的一种。网络通常指由多个节点和它们之间的连接关系构成的结构,强调连接、交互和通信。说明网络的主要目的是通信(交流)(通信)历史以前使用广播,不管是物理的还是无线电广播。特点:强调的是信息的单向传递。用户只能接收信息,而不能实时反馈。(这......
  • 说它是谁就是谁—Python语言中的鸭子类型
    鸭子类型(DuckTyping)是动态类型语言中的一种类型推断风格,尤其在Python语言中得到了广泛的应用。它的核心思想是:“如果它走起路来像鸭子,叫起来像鸭子,那么它就是鸭子”。这句话的意思是,我们不关心对象的类型是什么,而只关心对象的行为。只要对象具有所需的方法和属性,它就可以被视......
  • 【30】C++子类相关
    子类型关系什么是子类型公有继承时,派生类的对象可以作为基类的对象处理,派生类是基类的子类型。 #include<iostream>usingnamespacestd;classA{public: A(){} ~A(){} voidkill(){cout<<"Akill."<<endl;}};classB:publicA{public: B(){}......
  • C++之子类继承与父类构造
    C++之子类继承与父类构造文章目录C++之子类继承与父类构造1.问题引出2.原则3.解析3.1单一继承3.1.1父类无参构造函数3.1.1.1子类无定义构造函数3.1.1.2子类定义构造函数3.1.2父类存在无参构造函数和有参构造函数3.1.3父类仅存在有参构造函数3.2链式继承3.3多继承......
  • Map集合中的具体子类TreeMap
    一、TreeMap元素是一个键值对,可以去重并进行排序1.先编写一个Dog2类publicclassDog2{privateStringname;privateintage;publicDog2(){}publicDog2(Stringname,intage){this.name=name;......
  • Map中的具体实现子类HashMap
    一、HashMapHashMap<Student3,String>Map的唯一性指的是键的唯一性,HashMap中需要键的类型要重写hashCode()方法和equals方法二、HashMap的使用1.编写Student3类,里面需要重写hashCode()方法和equals方法importjava.util.Objects;publicclassStudent3{privateStrin......
  • Set集合的直接子类TreeSet
    一、TreeSet:底层数据结构是红黑树(自平衡二叉树),具备了可预测的排序1.自然排序通过实现comparable接口,重写里面的compareTo方法来进行排序1.编写一个Dog类,实现了Comparable接口,并重写里面的方法publicclassDogimplementsComparable<Dog>{privateStringname;pri......
  • Set集合具体实现子类HashSet的子类LinkedHashSet
    一、LinkedHashSet集合的特点:底层数据结构是哈希表和双链表。哈希表保证元素唯一,双链表保证元素有序,元素唯一二、LinkedHashSet集合的使用场景他保持了HashSet集合的特点,所以当我们传入一个对象想要进行去重的时候需要重写里面的hashCode方法和equals方法。publicclassLinke......