类,超类,子类

1,定义子类

下面是由继承Employee类来定义Manager类的格式,关键字 extends 表示继承。(is-a规则)

public class Manager extends Employee
{
添加方法和域
}

关键字extends表明正在构造的新类派生于一个已存在的类。已存在的类称为超类(superclass),基类(base class)或父类(parent class);新类称为子类(subclass),派生类(derived class)或孩子类(child class)。
尽管Employee 类是一个超类, 但并不是因为它优于子类或者拥有比子类更多的功能。实际上恰恰相反,子类比超类拥有的功能,更加丰富。
如下代码作为例子:

import java.time.LocalDate;
//带有public修饰符的共有类,只有一个
public class j {
    public static void main (String[] args) {
        Manager boss = new Manager("Cal Cracker", 8000, 1987, 12, 15);
        Employee[] staff = new Employee[3];
        staff[0] = boss;
        staff[1] = new Employee("Harry", 50000, 1989, 10,1);
        staff[2] = new Employee("Tony Tester", 40000, 1990, 3, 15);

        for (Employee e : staff) {
            e.raiseSalary(5);
        }
        for (Employee e : staff)
            System.out.println("name=" + e.getName() + ",salary=" + e.getsalary() + ",hireDay=" + e.getHireDay());
    }
}
//类Employee,为非共有类,非共有类可以有任意个
class Employee//包含一个构造器和四个方法
{
    //三个实例域用来存放将要操作的数据
    //关键字private确保只有Employee自身的方法能够访问这些实例域,而其他类不能读写这些实例域
    private String name;//有两个实例域本身就是对象:name域是String类的对象
    private Double salary;
    private LocalDate hireDay;//hireDay域是LocalDate类的对象
//这个类的所有方法都被标记为public,关键字public意味着任何类的任何方法都可以调用这些方法。
    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;
        this.salary += raise;//this是一个隐式参数,能将实例域salary与局部变量明显的分开
    }
}

class Manager extends Employee
{
    private double bonus;

    public Manager(String n, double s, int year, int month, int day)
    {
        super(n, s, year, month, day);
        bonus = 0;
    }

    public double getSalary()
    {
        double getSalary = super.getsalary();
        return getSalary + bonus;
    }

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

//在构造Employee对象时,构造器会运行,以便将实例域初始化为所希望的状态
// 创建类的实例:  Employee[] staff = new Employee[3];
//Employee类中的构造器就会运行: public Employee(String n, double s, int year, int month, int day)
/*
在有些时候,需要获得实力域的值,因此,应该提供下面三项内容:
1,一个私有的数据域 (例如:private String name;)
2,一个公有的域访问器方法  (例如:public String getName())
3,一个公有的域更改器方法  (例如: public void raiseSalary())
 */

Manager 类的getSalary 方法不能够直接地访问超类的私有域。也就是说,尽管每个Manager 对象都拥有一个名为salary 的域, 但在Manager 类的getSalary 方法中并不能够直接地访问salary 域。只有Employee 类的方法才能够访问私有部分。如果Manager 类的方法一定要访问私有域, 就必须借助于公有的接口, Employee 类中的公有方法getSalary 正是这样一个接口,即调用超类的方法来访问超类的私有域。(149覆盖方法)

子类构造器

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

语句super(n, s, year, month, day) ;是“ 调用超类Employee 中含有n、s、year, month 和day 参数的构造器” 的简写形式。
由于Manager 类的构造器不能访问Employee 类的私有域, 所以必须利用Employee 类的构造器对这部分私有域进行初始化, 我们可以通过super 实现对超类构造器的调用。使用super 调用构造器的语句必须是子类构造器的第一条语句。如果子类的构造器没有显式地调用超类的构造器, 则将自动地调用超类默认(没有参数)的构造器。如果超类没有不带参数的构造器, 并且在子类的构造器中又没有显式地调用超类的其他构造器,则Java 编译器将报告错误。

关键字this 有两个用途: 一是引用隐式参数, 二是调用该类其他的构造器, 同样,super 关键字也有两个用途:一是调用超类的方法,二是调用超类的构造器。在调用构造器的时候, 这两个关键字的使用方式很相似。调用构造器的语句只能作为另一个构造器的第一条语句出现。构造参数既可以传递给本类( this ) 的其他构造器, 也可以传递给超类(super ) 的构造器。

你可能感兴趣的:(类,超类,子类)