书籍:《Java核心技术卷I 基础知识》
内容:第五章5.1
主要内容:超类与子类
笔记:
C5.java
import java.time.LocalDate;
/继承/
/*阻止继承:final类,声明如下
* public final class Executive extends Manager
* {
* ...
* }
* 类中特定方法也可以被声明为final.这样子类就不能覆盖这个方法
* */
public class C5 {
public static void main(String[] args) {
System.out.println("EXAMPLE #1:");
Manager boss = new Manager("Mizuki",114514,1919,8,10);
boss.setBonus(5000);
Employee[] staff = new Employee[3];
staff[0] = boss;
staff[1] = new Employee("Kal'tsit",50000,-114514,1,1);
staff[2] = new Employee("Exusiai",23333,1990,4,15);
for(Employee e:staff){
System.out.println("name = "+e.getName()+", salary = "+e.getSalary());
}
System.out.println();
System.out.println("EXAMPLE #2:");
//抽象类
Person[] people = new Person[2];
people[0] = new Employee("Mostima",1919,2004,4,15);
people[1] = new Student("Texas","Computer Science");
for(Person p:people){
System.out.println(p.getName()+","+p.getDescription());
}
}
}
//类型强制转换: Manager boss = (Manager) staff[0];
//将一个子类的引用赋给一个超类变量,编译器是允许的.但将一个超类的引用赋给一个子类变量,必须进行类型转换.
/*
* 在继承链上由上到下转换,并谎报有关对象包含的内容
* Eg. Manager boss = (Manager) staff[1]; -->会报错
* 所以应该用instanceof操作符检查一下是否成功转换
* Eg. if (staff[1] instanceof Manager)
* {
* boss = (Manager) staff[1];
* }
* 如果转换不可能成功,编译器就不会进行这个转换。
* */
//受保护访问
/*任何标记为private的域都是不可见的,对子类亦是如此,所以为了超类中某些方法能被子类访问或者子类方法能访问超类的某个域,需要声明为protected
*/
Person.java
/* abstract 抽象类
* 为了提高程序的清晰度,包含一个或多个抽象方法的类本身必须被声明为抽象的。
* Eg. Person = { Employee, Student }
* 抽象类中包含抽象方法,也可包含具体数据和具体方法
* 抽象方法充当着占位的角色,它们的具体实现在子类中。
* 扩展抽象类可以有两种选择.一种是在抽象类中定义部分抽象类方法或不定义抽象类方法,这样就必须将子类也标记为抽象类;另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了.
* */
public abstract class Person {
public abstract String getDescription();
private String name;
public Person(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
Employee.java
import java.time.*;
//类:Employee
public class Employee extends Person {
private final LocalDate hireDay; // 类中没有方法能更改此值,所以使用final
private double salary;//private确保只有只有Employee类自身的方法可以访问这些实例域
public Employee(String n, double s, int y, int m, int d) {
super(n);
this.salary = s;
hireDay = LocalDate.of(y, m, d);
}// 构造器,与类同名
public double getSalary() {
return salary;
}
public LocalDate getHireDay() {
return hireDay;
}
public String getDescription(){
return String.format("an employee with a salary of $%.2f",salary);
}
public void raise_salary(double per) {
double raise = salary * per / 100;
salary += raise;
}
}
// 该类可以派生出多个类,组成一个继承层次
//判断是否该设计继承关系的规则:"is-a"规则,它表明子类的每个对象也就是超类的对象。“is-a”规则也可表示为置换法则,表明程序中出现的超类对象的任何地方都可以被子类对象置换
Student.java
public class Student extends Person {
private String major;
public Student(String name, String major) {
super(name);
this.major = major;
}
public String getDescription() {
return "a student majoring in" + major;
}
}
Manager.java
//Manager为Employee的子类,在Employee的基础上增加了新的方法等
public class Manager extends Employee {
//extends关键字表示继承
private double bonus;
public Manager(String n, double s, int y, int m, int d) {
super(n, s, y, m, d);
bonus = 0;
} //子类构造器
/*由于Manager类的构造器不能访问Employee类的私有域,所以必须利用Employee类的构造器对这部分私有域进行初始化,我们可以通过super实现对超类构造器的调用.使用super调用构造器的语句必须是子类构造器的第一条语句.*/
/*如果子类的构造器没有显式地调用超类的构造器,则将自动地调用超类默认(没有参数)的构造器.如果超类没有不带参数的构造器,并且在子类的构造器中又没有显式地调用超类的其他构造器,则Java 编译器将报告错误。*/
// Manager在超类中继承了name,salary,hireDay这三个域
public void setBonus(double b) {
bonus = b;
}
public double getSalary() //覆盖方法
{
double base_salary = super.getSalary();//此处调用的是超类Employee中的getSalary
return base_salary + bonus;
}
}
有错误还请dalao指正Orz