栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

类、超类和子类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

类、超类和子类

定义子类

用extends关键字表明正在构造的新类派生于一个已存在的类。

这个已存在的类称为超类(super class)、基类(base class)或父类(parent class)

新类称为子类(subclass)、派生类(derived class)或孩子类(child class)

class Employee {
    private String name;
    private double salary;
    private LocalDate hireDay;

    public Employee(String n, double s, int year, int month, int day){
        name = n;
        salary = s;
        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;
    }
}

让Manager类继承Employee类(inheritance)

public class Manager extends Employee {
    private double bonus; // Manager 比 Employee多了bonus字段
    
    public void setBonus(double bonus) {
        this.bonus = bonus;    
    }                                            
}

Manager类自动继承了超类Employee中的getName等方法和name、salary等字段

设计类时,应当通用的方法抽取到超类

覆盖方法

超类的一些方法对子类并不一定适用,需要提供新的方法来覆盖(override)超类的方法

public class Manager extends Employee {
    private double bonus; 
    // ...
    // Manager的getSalary方法应该返回工资和奖金的总和
    public double getSalary() {
         double baseSalary = super.getSalary();
         return baseSalary + bonus;
    }                                
}

下面说明两种错误做法:

    直接return salary + bonus;

只有Employee方法能直接访问Employee类的私有字段。(private只有同类才能访问)

    double baseSalary = getSalary();

希望调用Employee类的公共方法getSalary,但这里由于覆盖了方法,将无限次调用自身

想调用超类Employee中的getSalary方法,可以用super关键字来调用超类的方法

子类构造器
public Manager(String name, double salary, int year, int month, int day) {
    super(name, salary, year, month, day);
    bonus = 0;
}

使用super调用超类的构造器,必须放在子类构造器的第一行

若子类构造器未显式调用超类的构造器,将自动调用超类的无参构造器

若超类没有无参构造器,且在子类的构造器中未显式调用超类的其他构造器,Java编译器就会报错

****this和super的对比****

关键字this两个含义:

    指示隐式参数的引用调用该类的其他构造器(需放在构造器的第一行)

关键字super两个含义:

    调用超类的方法调用超类的构造器(需放在构造器的第一行)
public class Test {
    public static void main(String[] args) {
        var staff = new Employee[3];
        Manager boss = new Manager("Carl", 8000, 1987, 12, 15);
        boss.setBonus(5000);
        staff[0] = boss;
        staff[1] = new Employee("Tom", 5000, 1989, 10, 1);
        staff[2] = new Employee("Mitch", 4000, 1990 ,3 ,15);

        for (Employee e : staff)
            System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay=" + e.getHireDay());
    }
}

这边在输出staff[0]的薪水时,e.getSalary()应该能够执行正确的getSalary方法。

尽管这边e声明为Employee类型,但实际上e既可以引用Employee类型的对象,也可以引用Manager类型的对象。虚拟机知道e实际引导的对象类型。

一个对象变量可以指示多种实际类型的现象称为多态(polymorphism)

在运行时能够自动地选择适当的方法,称为动态绑定(dynamic binding)

若程序运行并且用动态绑定调用方法,虚拟机必须调用与x所引用对象的实际类型对应的方法。假设x的实际类型是D,D是C类的子类。若D类定义了方法f(string),就会调用这个方法;否则将在D类的超类中寻找f(string)。

若是private方法、static方法、final方法或者构造器,编译器可以准确知道调用哪个方法,这称为静态绑定(static binding)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/755459.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号