继承已存在的类就是复用这些类的方法,而且可以怎家一些新的方法和字段,使新类能够适应新的方法和字段
1、定义子类
public class Manager extends Employee
{
private double bonus;
/**
* @param name the employee's name
* @param salary the salary
* @param year the hire year
* @param month the hire month
* @param day the hire day
*/
public Manager(String name, double salary, int year, int month, int day)
{
super(name, salary, year, month, day);
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b) // 这个setBonus就是Manager特有的,Employee对象就不能使用这个方法
{
bonus = b;
}
}
- 已经存在的、被继承的类是超类;继承超类的是子类
- 子类拥有比超类拥有更多的功能
2、覆盖方法
- 可以在子类中提供新的实现覆盖超类中的这个方法
- 区分超类的方法,可以使用super关键字
public double getSalary(){
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
3、子类构造器
- 子类可以这样调用超类构造器
public Manager(String name, double salary, int year, int month, int day){
super(name, salary, year, month, day); // 调用超类中有这些参数的构造器
bonus = 0;
}
- 如果子类的构造器没有显式地调用超类的构造器,将自动地调用超类的无参数构造器。
4、多态
Manager boss = new Manager("Marker", 80000, 1987, 12, 15);
var staff = new Employee[3];
staff[0] = boss;
staff[1] = new Employee("harry", 5000, 1989, 20, 1)
for (Employee e : staff)
System.out.println(e.getName() + " " + e.getSalary());
- 系统会自动地识别这个e是Employee对象还是Manager对象
- 一个对象变量可以指示多种实际类型的现象称为多态,在运行时能够自动地选择适当的方法,称为动态绑定。
- "替换原则",出现超类对象的任何地方都可以使用子类对象替换。
- 但是子类是不能引用父类对象,子类比父类可能多了一些东西。可以理解成子类可以替代父类,但是父类不能替代子类(https://tieba.baidu.com/p/3624167141?red_tag=0895168372)
- 类型强制转换的时候,也是父类对象引用子类,这时候才可以做强制转换。
5、final修饰符
不允许扩展的类被称为final类。
子类不可覆盖的方法被称为final方法。
- 使用final可以确保不会在子类中改变语义,比如String是一个final类,没办法扩展它的子类。
- 使用final是静态绑定,开销会小一些。
6、强制类型转换
- 强制类型转换要暂时忽视对象的实际类型,之后使用对象的全部功能
- 如果将一个子类的引用赋给超类变量,编译器允许;将一个超类引用赋给子类变量,承诺过多,必须使用强制类型转换。
- 但是如果超类对象不是对子类的引用,是不能强制转换的。(只有父类对象本身就是用子类new出来的时候, 才可以在将来被强制转换为子类对象 https://www.cnblogs.com/ooo0/p/9308583.html)
public class EmployeeTest {
public static void main(String args[]){
Manager boss = new Manager("Marker", 80000, 1987, 12, 15);
Employee[] staff = new Employee[3];
staff[0] = boss;
staff[1] = new Employee("harry", 5000, 1989, 20, 1);
System.out.println(staff[1] instanceof Manager); // false
System.out.println(staff[1] instanceof Employee); // true
System.out.println(staff[0] instanceof Manager); // true
System.out.println(staff[0] instanceof Employee); // true
Manager m = (Manager) staff[1]; // Exception in thread "main" java.lang.ClassCastException
// 这种情况再用强制类型转换,因为要用manager里的setBouns
Manager b = (Manager) staff[0];
b.setBonus(199);
}
}
class Employee
{
// 字段
private String name;
private double salary;
// 构造器
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
}
// 封装的实现,通过get set方法操作字段
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}
class Manager extends Employee
{
private double bonus;
/**
* @param name the employee's name
* @param salary the salary
* @param year the hire year
* @param month the hire month
* @param day the hire day
*/
public Manager(String name, double salary, int year, int month, int day)
{
super(name, salary, year, month, day);
bonus = 0;
}
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b) // 这个setBonus就是Manager特有的,Employee对象就不能使用这个方法
{
bonus = b;
}
}
网友评论