# day09 面向对象继承多态
- 学习目标
- 继承概念
- 继承的关键字 extends
- 继承后子类父类的特点
- 成员变量
- 成员方法
- 构造方法
- Java中继承的特点
- 继承的好处
- 对象的多态性
- 多态的必要因素
- 多态的语法格式
- 多态中成员的特性
- 多态中的转型
# 1. 继承
# 1.1 生活中的继承
生活中, 子继承父的遗产, 不是全部, 只能是部分
# 1.2 程序中的继承
在程序中, 也能出现继承的关系, 让一个类去继承另一个类.
比如 A类继承B类
- 出现继承的关系
- A类是B类的子类, 或者称为派生类
- B类是A类的父类, 或者称为超类, 基类
- 子类可以直接拥有父类的成员(不是全部)
# 1.3 继承的语法格式
继承使用关键字 extends, 表示继承的意思
注意: extend 本身含义, 扩展, 延伸
- 定义格式
class B{}
class A extends B{} // A 继承 B类
- 继承的入门案例 -- 子类拥有父类成员
/**
* 定义的是 Teacher和Manager类的共性内容
* 姓名年龄
*/
public class Person {
String name ;
int age;
}
/**
* 管理类,班主任类
*/
public class Manager extends Person{
}
/**
* 老师类
* 重复,只做一次
* 想法:
* String name;
* int age;
* 换一个地方定义(共性抽取)
* Teacher和Manager共用
* 使用Person中的成员
* Teacher继承Person
*/
public class Teacher extends Person{
}
public static void main(String[] args) {
/**
* 创建对象, Person的子类对象
* Person : Teacher,Manager
*/
Teacher teacher = new Teacher();
//teacher对象,调用成员变量
//teacher子类对象调用继承的成员变量
teacher.name = "张三";
teacher.age = 20;
Manager manager = new Manager();
manager.name = "李四";
manager.age = 22;
System.out.println("teacher.name = " + teacher.name);
System.out.println("teacher.age = " + teacher.age);
System.out.println("manager.name = " + manager.name);
System.out.println("manager.age = " + manager.age);
}
# 1.4 继承的好处
上面案例, 使用程序中的继承, 使用继承的好处:
减少代码量
复用性提高
继承的存在, 导致了面向对象的最后一个特征多态
继承有弊端: 类和类之间的紧密性更强.(扩展性越差)
# 2. 继承后成员特点
# 2.1 继承后成员变量特点
子类和父类中的成员变量同名
- 调用的使用: 子类自己有, 使用自己的, 子类没有, 使用父类
public class Fu{
String s = "父类";
}
public class Zi extends Fu{
String s = "子类";
}
public static void main(String[] args) {
//创建对象,子类对象
Zi zi = new Zi();
//子类对象,调用成员s
System.out.println(zi.s);
}
# 2.2 super关键字
super关键字是超级的意思, 在子类中调用父类的成员, 使用此关键字
super.变量 调用父的成员变量
super.方法() 调用的是父类的成员方法
this表示当前对象, super表示父类在内存中的存储空间, 不是对象
public class Fu{
String s = "父类";
}
public class Zi extends Fu {
String s = "子类";
public void print(){
String s = "方法";
System.out.println(s);
System.out.println(this.s);
System.out.println(super.s);
}
}
public static void main(String[] args) {
//创建子类对象,调用方法
Zi zi = new Zi();
zi.print();
}
# 2.3 继承后成员方法特点
**方法重写override:**子类父类出现了一模一样的方法, 称为子类重写了父类的方法. 又称为覆盖或者复写.
调用子类重写的方法, 假如子类没有重写, 调用父类的方法
public class Fu {
public void print(){
System.out.println("父类方法print");
}
}
public class Zi extends Fu {
/**
* 要重写父类的方法
* 直接复制
*/
public void print(){
System.out.println("子类方法print::重写");
}
}
public static void main(String[] args) {
//创建子类对象
Zi zi = new Zi();
zi.print();
}
# 2.4 方法重写的意义
继承本质是扩展的意思, 延伸的意思, 依靠方法的重写来实现
方法重写引入案例, 理解重写的意义
/**
* 定义手机类
* 早年代手机
*/
public class Phone {
/**
* 定义手机的来电显示功能
* 数字移动电话
*/
public void showingCall(){
System.out.println("来电显示号码");
}
}
/**
* 新手机:
* 功能变强,但是原有功能继续复用
* 继承和方法重写的思想
*/
public class Iphone extends Phone {
//重写父的方法
//方法名字不变,用户不需要重新知
public void showingCall(){
//复用显示号码功能,父类的方法中,已经完成了
//调用父类的方法
super.showingCall();
//新增的功能
System.out.println("显示大头像");
System.out.println("归属地");
System.out.println("意思推销");
}
}
public static void main(String[] args) {
//创建手机对象
Phone phone = new Phone();
phone.showingCall();
System.out.println("==========");
//创建新手机对象
Iphone iphone = new Iphone();
iphone.showingCall();
}
# 2.5 方法重写小问题
方法重写需要考虑权限的. 保证子类方法的权限要大于或者等于父类方法权限
- 父类的方法权限是public
class Fu{
public void print(){}
}
class Zi extends Fu{
public void print(){} //正确
protected void print(){} //错误,权限降低
void print(){} //错误,权限降低
private void print(){} //错误,权限降低
}
- 父类的方法权限是protected
class Fu{
protected void print(){}
}
class Zi extends Fu{
public void print(){} //正确
protected void print(){} //正确
void print(){} //错误,权限降低
private void print(){} //错误,权限降低
}
- 父类方法权限是默认
class Fu{
void print(){}
}
class Zi extends Fu{
public void print(){} //正确
protected void print(){} //正确
void print(){} //正确
private void print(){} //错误,权限降低
}
- 如果父类的方法权限是private, 子类不知道该方法的存在, 没有继承的说法
# 2.6 继承后构造方法特点
构造方法特点: 子类的构造方法中, 第一行存在隐式代码 (写不写都存在), 代码是**super(); ** 调用父类的无参数构造方法.
public class Fu {
public Fu(){
System.out.println("父类构造方法");
}
}
public class Zi extends Fu {
public Zi(){
super(); //调用父类的无参数构造方法.
System.out.println("子类构造方法");
}
}
- 子类的构造方法, 无论重载多少个, 第一行肯定也是super();
public class Zi extends Fu {
public Zi(){
super(); //调用父类的无参数构造方法.
System.out.println("子类构造方法");
}
public Zi(int a){
super(); //调用父类的无参数构造方法.
System.out.println("子类构造方法::重载的");
}
}
- 父类没有无参数构造方法, 子类的构造方法中, super(传递参数)
- 父类中存在多个构造方法, 子类的构造方法只要调用到其中的一个即可
public class Fu {
/**
* 父类的构造方法
* 加上参数,有参数的构造
*/
public Fu(int a){
System.out.println("父类构造方法" + a);
}
public Fu(String s){
System.out.println("父类构造方法" + s);
}
}
public class Zi extends Fu {
public Zi(){
//调用父类的无参数构造方法
//父类中没有无参数构造
//传递响应的参数
super(7);
}
public Zi(String s){
//调用父类构造方法,保证调用其中一个
super("字符串");
}
}
# 3. 继承特点
# 3.1 单继承
一个类只能继承一个类, 不允许同时继承多个类
class A extends B,C{} //不允许的行为
单继承存在局限性, 解决局限性问题, 接口的概念
# 3.2 多层继承
class A extends B{}
class B extends C{}
//多层继承,允许实现
//class C extends Object{}
A类可以同是拥有B和C的成员, B只能拥有C的成员
A类中super调用的是B类成员, 如果B类没有成员, 调用C成员
Object类是java中的皇帝, 所有的类都是Object子类