封装

封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

封装的内容对我们来说,就是一个黑箱子,我们并不需要知道其内部是如何实现的,仅仅知道“进去什么,出来什么”即可。

继承

java中只支持单继承。不直接支持多继承
因为多个父类中有相同成员,会产生调用不确定性.
在java中是通过”多实现”的方式来体现多继承的特征的。


单继承使用方法:

Class A{} Class B extends A{}



当要使用一个继承体系时(继承体系指多重继承的拓扑图)
应该按照这个步骤:
1,查看该体系中的顶层类,了解该体系的基本功能。
2,实例化该体系中的最低层的子类对象,完成功能的调用。

方法的重载

子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作.
重写以后,当创建子类对象时,通过该子类对象调用子父类中的同名同参数的方法时,实际执行的是子类中的方法。(优先级)

  • 子类重写的方法与父类被重写的方法的函数名、形参列表与返回值都应该相同
  • 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
  • 静态只能覆盖静态,或被静态覆盖。

特殊情况:子类不能重写父类中声明为private权限的方法

super关键字


当子父类中都出现相同的变量时,可以使用super区分父类
super的用法跟this很相似(this用来区分成员变量和局部变量)


但是不同之处在于:

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



    父类构造函数的自加载

    封装、继承、多态 - 图1

  • 子类的实例化过程:子类中所有的构造函数会默认访问父类中的空参数的构造函数。

  • 如果子类需要访问父类中带参数的构造函数,需要手动指定,也就是重写super(形参)
  • supre语句必须要定义在子类构造函数的第一行.因为父类的初始化动作要先完成(如果没覆盖,那么默认覆盖父类的无参构造函数)




    一个对象实例化的过程:
    Person p =new Person();

    1,JVM会读取指定的路径下的Person.class文件,并加载进内存,
    并会先加载Person的父类(如果有直接的父类的情况下).
    2,在堆内存中的开辟空间,分配地址。
    3,在对象空间中,对对象中的属性进行默认初始化(0或null).
    4,然后调用对应的构造函数进行初始化。
    5,在构造函数中,第一行会先到 [ super( ) ]调用父类中构造函数进行初始化。
    6,父类初始化完毕后,在对子类的属性进行显示初始化。
    7,再进行子类构造函数的特定初始化。
    8,初始化完毕后,将地址值赋值给引用变量.


    封装、继承、多态 - 图2

  • 子类实例化对象在super()之后才进行特定初始化






多态

多态:某一类事物的多种存在形态(一个对象,多种形态)

多态的体现:父类的引用指向了不同的子类对象
可以理解为:父类的方法根据子类对象的不同,体现的形式也不同。

体现多态需要两个前提条件:

  1. 继承父类
  2. 重写该父类的方法

封装、继承、多态 - 图3

关于多态的现象


封装、继承、多态 - 图4

  • 如类变量和静态方法,是没有跟对象绑定的(存放在堆中),那么访问的结果就是“谁调用我,我返回什么”
  • 如方法,在子类中已经被重写,是跟特定对象绑定的,那么访问的就是依据对象进行调用的(不同对象调用该方法,就会体现不同的效果,这就是多态的一种体现)

向上转型和向下转型


封装、继承、多态 - 图5

  • 此时,通过对象a并不能调用Cat类的方法、属性,因为编译器认为,这声明是一个Animal。
  • 那么此时,我们如何调用子类的方法或属性呢? 答案是转型

转型:子类对象在做着类型的转换

向上转型(即多态): 限制对特有功能的访问
向下转型(即特定对象转型):实现使用子类的特有方法,或特有属性。向下转型时,可以用instanceof关键字来判断是否为子类,避免类名转换异常