本章讲述面向对象程序设计概念:继承与反射
5.1 类、父类和子类
示例:
经理:薪水+奖金
雇员:薪水
经理是雇员,满足(is-a)关系,同时增加了新特性奖金。使用 extends 关键字来标识
示例代码:
public class Employee {private int id;
private double salary;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
public class Manager extends Employee {
private double bonus;
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
测试代码:
public class Main {public static void main(String[] args){
Main solution = new Main();
Manager m = new Manager();
m.setId(1);
m.setSalary(5000);
m.setBonus(500);
System.out.println(m.getId()+" "+m.getSalary()+" "+m.getBonus());
}
}
继承特性:
有时候子类对父类不完全是(is-a)的关系,也可以是(like-a)关系。这时候可以通过父类方法来实现。如下:
public class Manager extends Employee {private double bonus;
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
@Override
public double getSalary() {
return super.getSalary()+bonus;
}
}
public class Main {
public static void main(String[] args){
Main solution = new Main();
Manager m = new Manager();
m.setBonus(500);
m.setSalary(5000);
Employee e = m;
System.out.println(e.getSalary());
}
}
输出信息,结果如下:
这种使用@Override进行标识,子类实现父类同名方法的方式,叫做方法覆盖或者方法重写。
Super.getSalary(); 这种使用super的形式,可用于指代父类对象。
继承能做什么:
- 添加全局变量
- 进行方法覆盖
- 使用父类方法
- 添加自己方法
super(n,s,year,month,day); 表调用父类构造
特殊地,如果子类不写构造,而父类未定义无参构造,则会报错。因为子类默认构造,无法确定用超类的哪个构造,从而产生错误。
this:指代隐式参数、其他构造
super:指代父类方法,父类构造
类似下面,使用父类对象,调用父类方法的方式,叫做多态,运行时自动调用相应方法的方式叫做动态绑定
Employee e = m;
System.out.println(e.getSalary());
5.1.1 继承层次
子类继承父类,使用箭头指向父类的方式,叫做继承。将鼠标光标定位在类上,然后在IDEA使用CTRL+SHIFT+ALT+U的方式,进行定位,可以查询类的继承关系。
如上图是StringBuffer的继承关系。
5.1.2 多态
表名子类对象也属于父类对象,如经理都是雇员。可将子类对象复制给父类。
Employ e;e = new Employ();
e = new Manager();
但是进行多态操作后,丢失了子类的特有的方法调用,类似于:经理是雇员,雇员不一定有奖金,所以这种情况Java无法识别。
public class Main {public static void main(String[] args){
Main solution = new Main();
Manager m = new Manager();
m.setBonus(500);
m.setSalary(5000);
Employee e = m;
System.out.println(e.getSalary());
System.out.println(m.getBonus());
System.out.println(e.getBonus());
}
}public class Main {
public static void main(String[] args){
Main solution = new Main();
Manager []m = new Manager[10];
Employee []e = m;
e[0] = new Employee();
m[0].setBonus(1000);
System.out.println(m[0].getBonus()); }
}
参见Java库bug:
Bug ID: JDK-6260652 (coll) Arrays.asList(x).toArray().getClass() should be Object[].class
Bug ID: JDK-6515694 (coll) Arrays.ArrayList.toArray() does not return Object[] always
参考文章:
JDK1.6集合框架bug:c.toArray might (incorrectly) not return Object[] (see 6260652)_aty
处理方法参考源码:ArrayList
系列内容:
《Java 核心技术 卷1》 笔记:第一章 Java程序设计概述
《Java 核心技术 卷1》 笔记:第二章 Java程序设计环境
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(1)
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(2)
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(3)
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(4)
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(5)
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(6)
《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(7)大数处理、数组、多维数组、控制台传参
《Java 核心技术 卷1》 笔记 第四章:类与对象
《Java 核心技术 卷1》 笔记 第四章:类与对象(2) GregorianCalendar 与 类的基本组成
《Java 核心技术 卷1》 笔记 第四章:类与对象(3) 构造器全局私有方法
《Java 核心技术 卷1》 笔记 第四章:类与对象(4) 静态字段+静态方法+工厂方法
《Java 核心技术 卷1》 笔记 第四章:类与对象(5) 形参与实参 构造器的默认值与默认构造
《Java 核心技术 卷1》 笔记 第四章:类与对象(6) 构造器调用与初始化块
《Java 核心技术 卷1》 笔记 第四章:类与对象(7) 注释、JavaDoc与类设计
喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。
关注公众号,互相学习:钰娘娘知识汇总