面向对象 三大特征2 --- 继承

封装 继承 多态

面向对象思想,有 3大特性,封装,继承,多态
个人认为,这 3大特性,是整个 面向对象思想的核心和精髓,深刻理解和掌握这 3大思想,是好好掌握 Java语言的关键

1 概述

父类是 不断地从子类向上抽取而来的,继承可以 提高代码的 复用性
继承的优点:

  • 提高了代码的复用性
  • 让类与类之间,产生了关系,给第三个特征 — 多态 的出现,提供了前提

2 单继承与多重继承

Java支持单继承,不直接支持多继承,但是,可以通过 多实现 的方式,实现多继承

要使用一个继承体系时
1 查看该体系中的 顶层类,了解该体系的基本功能
2 创建体系中的 最子类对象,完成功能的使用

定义继承
当类与类之间,存在着所属关系时,就定义继承
A 是 B 的一种,A extends B
所属关系: is a

3 子父类中成员特点

子有不找父,局部有不找成员,先找自己内存空间的,再找外部内存空间的

在子父类中,成员的特点体现

1 成员变量
2 成员函数
3 构造函数

3.1 成员变量

a 区分

子父类中的成员变量同名,用 super 区分父类
本类的成员变量和局部变量同名,用 this 区分

this:代表一个本类对象的引用
super:代表一个父类空间

this 代表子类对象,super 不代表父类对象,仅代表父类空间
在代码 Zi z = new Zi() 中,有子类对象,没有父类对象,子类为什么能够获得父类对象的内容,因为,子类持有父类的引用 super

b 子父类成员变量的内存图解

这里写图片描述
代码分析:
Zi z = new Zi(); 加载子类 Zi,因为 子继承父,class Zi extends Fu,父先进来,父类是没有对象的,那么父类的属性 num,就存储到了子类内存中。
怎么存储的:
子一继承父,就意味着子多了一个属性 num,子的 num,默认为 0,父的 num,默认为 0,然后分别进行初始化,5,4
在实际开发中,这种情况基本没有

因为子类继承父类,那么父类中的属性,一定是公用的,不需要修改的, 如果有,说明父类写的不够好
num 一般都定义为 private,对外提供 set , get 方法,进行获取和修改
子类不能直接访问父类中的私有内容,但是可以间接访问,比如通过 set get 方法

3.2 成员函数

覆盖

当子父类中出现成员函数一模一样的情况,会运行子类的函数,这成为函数的覆盖

函数的两个特性

  1. 重载 — 同一个类中 (override)
  2. 覆盖 — 子类中 — 也成为 重写,覆写 (override)

覆盖注意事项

  1. 子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限
  2. 静态只能覆盖静态,或被静态覆盖

覆盖的应用 — 什么时候使用

当对一个类,进行子类的扩展时,子类需要保留父类的功能声明,但是要定义子类中,该功能的 特有内容时,就使用覆盖操作

不建议对原代码进行修改,把原代码的功能进行继承,自己添加新的功能

3.3 构造函数

子父类构造函数的特点:
子类中所有的构造函数,默认都会访问,父类中的空参构造函数

class Fu
{
    int num ;
    Fu()
    {
        num =10;
        System.out.println("A fu run");
    }
    Fu(int x)
    {
        System.out.println("B fu run..."+x);
    }
}
class Zi extends Fu
{
    int num;
    Zi()
    {
        //super();//调用的就是父类中的空参数的 构造函数。
        System.out.println("C zi run"+num);
    }
    Zi(int x)
    {
        this();  // 有this(),就没有super(); 怎么访问父类?
        // 通过 this(),访问 Zi(){} 通过Zi(){}中的 默认super()访问父类
        // super();
        //super(x);  --- 父类是带参构造函数,子类可以指定参数,super(x)
        System.out.println("D zi run "+x);
    }
}

class  ExtendsDemo4
{
    public static void main(String[] args) 
    {
        new Zi(6);  
        // new Zi(6) 这个怎么走
        // 首先找到子类构造函数 Zi( int x); 这个构造函数的第一句是默认的 super();
        //所以去找父类的空参构造函数,如果没有,报错,不是去找 父类的带参构造函数Fu(int x);
    //如果想使用指定的构造函数,必须手动指定 super(x);

    }
}
class Demo//extends Object
{
    /*

    Demo()
    {
        super();   --- Java面向对象,对象就有共性,Java将所有对象进行抽取,抽取出一个最顶层的类 Object
        --- 所以,创建的任何对象,都是 Object的子类,所以 class Demo 等于 class Demo extends Object
        return;
    }
    */
}

1 为什么子类实例化的时候,要访问父类中的构造函数

因为子类继承父类,继承了父类的内容(属性和方法),所以在使用父类内容之前,要先看看,父类是如何对自己的内容进行初始化的
为了完成这个必须的动作,就在子类的构造函数中,加入了 super() 语句

2 如果父类中,没有定义空参构造函数,那么子类的构造函数,必须用 super(),明确要调用父类中的哪个构造函数;同时,子类构造函数中如果使用 this调用了本类的构造函数时,那么 super 就没有了。因为 super 和 this,都只能定义一行,所以只能有一个。
但是,可以保证的是,子类中肯定会有其他的构造函数访问父类的构造函数。若没有,初始化不了

super 语句,必须要定义在子类构造函数的第一行
因为 父类的初始化动作,要先完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值