第四章 继承和多态
第四章
面向对象特征之二:继承
继承
从现有类创建子类(衍生)过程, 子类要继承父类的所有成员
继承原因
父类不够用, 需要功能更强的子类
继承方法
class 子类 extends 父类 {}
继承内容
子类 继承 父类的所有成员. 构造器除外
-
属性描述事物特征, 方法描述事物的行为动作.
-
什么东西能被继承 : 只有具有描述性的东西才继承.
-
属性,方法和内部类可以继承(因为它们是成员)
-
静态块,非静态块, 构造器不能继承(因为它们不是成员) *
-
只有非静态方法具有多态性. *
-
static 关键字和多态是背道而驰.
思考
如果A类被B类继承,B类又被C类继承, 在所有类中都有一个方法test(), 创建C类对象,调用test()方法,执行的是哪个类的方法? 在C类中有几个test()方法?
执行的是C类中的方法, 因为在C类中重写了.
-
从测试类角度, 看待C类, 只有一个
-
从C类的内部角度看, 有2个test()方法, 一个是this.test(), 另外一个是super.test()
-
从继承的概念来看, C类中有3个test()方法.
/**
* 继承 : 从现有类创建子类, 现有类称为父类, 基类(子类在父类的基础上进行扩展), 超类(因为在子类使用super关键字限定父类成员, 官方叫法).
* 子类一旦继承父类, 会继承父类的所有成员!!!!(构造器除外)
* 为什么要继承所有成员? 因为子类必须是一个完整的父类.
*
* 为什么要继承 ? 因为父类不够用, 需要子类扩展一下, 再来使用.
*
* 父类中的私有成员, 也可以被子类继承, 但是私有成员只允许在本类中访问,
* 子类不是本类, 所以在子类中不能直接访问继承来的私有属性
* 必须在父类中提供公共的get/set方法, 让子类继承后通过get/set来间接访问\\
*
* 多重继承 : 一个子类有多个直接父类, java不支持, 因为有可能出现方法冲突!!!
* 多层继承 : 一个子类有一个直接父类, 若干间接父类. java支持
*
* 方法覆盖(override) : 子类中重写父类继承来的方法, 因为父类方法不好用.
* 条件 :
* 1) 方法签名要完全一致, 包括返回值类型, 方法名, 参数列表(类型一致, 个数一致, 顺序一致)
* 2) 子类方法的访问控制修饰符要大于等于父类的.(因为子类是父类的扩展, 父类该有的特征和行为,
* 在子类中也必须要全部具备)
*
* super 关键字 : 用于标识从父类继承的成员.
*
* @Override // 注解 : 特殊的注释, 特殊在于可以被编译器和JVM识别.
* // @Override注解的作用就是说明这个方法是要覆盖, 请编译器帮助我们作方法覆盖条件的检查.
* // 如果有问题, 请提前编译出错.
*/
public class Person {
private String name;
private int age;
private String gender;
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void eat(String some) {
System.out.println("吃" + some);
}
public String say() {
return "姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender;
}
}
******************************************************************
public class Student extends Person {
/*
String name;
int age;
String gender;
*/
String school;
/*
public void eat(String some) {
System.out.println("吃" + some);
}
public String say() {
return "姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender;
}
*/
public void study() {
//System.out.println(name + "学生在上课"); // 虽然父类私有属性继承了, 表达了所有权, 但是没有直接使用权
System.out.println(this.getName() + "学生在上课"); // this.表明子类真的继承了, 为我所有