继承
- 继承解决的是代码冗余问题,实现代码的重用
1.1.什么是继承
- 使用 extends 关键字实现继承,两个类之间有 IS-A(是一个。。) 的关系的时候可以使用继承
- 子类(派生类)继承父类(基类)
- 子类自动拥有了父类所有所有成员,但是只能访问父类可访问的成员(成员变量和方法)
- 子类构造方法执行之前一定会执行父类的构造方法,默认是调用父类的无参构造;如果父类中没有无参构造方法,子类的构造方法中第一行代码一定要显示的去调用父类的构造方法
- new子类对象的过程中只是调用了父类构造而已 并没有new父类对象
- 自定义的类都会默认继承Object类,Object是根基类
- java中继承是单继承,子类只能有一个父类;
1.2.继承的实现
基类(父类)
public class Employee {
private int id;
private String name;
private char gender;
private double salary;
public Employee() {
}
public Employee(int id, String name, char gender, double salary) {
this.id = id;
this.name = name;
this.gender = gender;
this.salary = salary;
}
public int getId() {
return id;
}
// getter/setter方法
}
子类
public class SoftwareEngineer extends Employee {
private int hot;
public SoftwareEngineer() {
}
public int getHot() {
return hot;
}
}
练习
1.3. super关键字
super的使用 ,只是一个关键字而已,指代是调用父类的成员
1,在子类构造方法中去调用父类的构造方法,在第一行
2,当子类的成员和父类成员重名 的时候使用super来调用父类的;
public void run(){
System.out.println(super.age);
}
1.4.权限修饰符
- 修饰成员变量和方法, 修饰class目前只用到public/缺省)
修饰符 | 类内部 | 同一个包下面 | 子类 | 任意地方 |
---|---|---|---|---|
public | YES | YES | YES | YES |
protected | YES | YES | YES | |
缺省(包权限) | YES | YES | ||
private | YES |
1.5. 方法的重写
- 子类继承父类 的方法后,如果不满意可以重写;发生在继承关系中
- 方法名相同,参数列表相同;返回值类型不能大于被重写的返回值类型;重写方法不能比被重写方法有更严格的权限修饰符
重载(overload)和重写(overwrite)的区别
overload是同一个类中方法名相同,参数列表不同是重载
override/overwrite是继承关系中,子类重写了父类的方法;
父类方法实现
public class Animal{
private int age;
private String color;
protected Object run(int a) {
System.out.println("动物在跑");
return null;
}
public Animal() {
}
public Animal(int age, String color) {
this.age = age;
this.color = color;
}
// get/set
}
子类重写了父类的 run方法
public class Monkey extends Animal {
private int legNum;
public Monkey(int legNum, int age, String color) {
super(age, color);
this.legNum = legNum;
}
@Override
public Object run(int a) {
System.out.println("猴子在跑");
return "";
}
public int getLegNum() {
return legNum;
}
public void setLegNum(int legNum) {
this.legNum = legNum;
}
}
测试
public class Test {
public static void main(String[] args) {
Monkey monkey = new Monkey(4, 1, "yellow");
monkey.run(1);
}
}
练习题:
小镇上来了个马戏团,目前马戏团中只有大象,猴子,和老虎,他们都有name,age等属性和都会表演节目,大象会表演喷水,猴子会表演骑单车,老虎会表演跳火圈;
通过分析可知 马戏团这个类中拥有表演节目这个方法;如果上台的是猴子就让猴子表演骑单车,如果上台的是大象,就让大象表演喷水,如果上台的是老虎,就让老虎表演跳火圈;
狮子,狮子
多态
- 多态实现代码扩展问题 ; 对修改关闭,对扩展开放
- 多态的实现:继承(实现),重写,父类引用指向子类对象(向上转型),反之称为向下转型;
- 多态的体现是 根据运行过程中根据实际的对象类型,去调用该对象 的方法(重写后的方法)
- 父类引用不能访问子类新增 的成员
马戏团练习体
动物类
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void play() {
System.out.println("动物在表演");
}
// get /set 方法
}
子类 猴子类
public class Monkey extends Animal {
@Override
public void play() {
System.out.println("猴子表演骑单车");
}
}
马戏团类
public class Circus {
private String name;
private String address;
public Circus() {
}
public Circus(String name, String address) {
this.name = name;
this.address = address;
}
//使用多态
public void show(Animal animal) {
animal.play();
}
// get /set 方法
}
测试类
public class Test {
public static void main(String[] args) {
Circus circus = new Circus();
// 父类引用指向子类对象
Animal monkey = new Monkey();
Animal elephant = new Elephant();
Lion lion = new Lion();
circus.show(monkey);
// 对修改关闭,对扩展开发
}
}
抽象类
- 有些类是不应该有实例的,设计出来就是被继承的,这些类就应该是抽象类;抽象类是不能new 的
- 有些方法设计出来就是被重写的,要声明为抽象方法,抽象方法要被重写
- 使用abstract关键字修饰类或者方法就是抽象类/抽象方法
- 含有抽象方法的类一定要声明为抽象类;
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void play();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
继承:IS-A extends
抽象类:其实是一组类的模板,而且不需要有实例