巩固Java基础,基于韩顺平老师的课程,Java的封装、继承、多态、super()、this()、重载与重写的区别......,下面我们一点点来巩固练习。
(1)继承
继承细节1:子类无法继承父类的私有
图1
我们定义一个父类father,里面有四个属性sample分别用public、protect、private、缺省四种修饰符来定义。用一个son去继承father。如图我们可以看见子类继承了父类所有属性和方法,但私有的却不能直接访问,如下例的sample4,如果要访问则用父类的公有方法去访问(设set和get方法)。
图2
继承细节2:子类必须调用父类的构造器
对于第二点:子类必须调用父类的构造器,创建每个子类时其实都会调用父类的构造器完成初始化,如果我们不写就会自动调用的默认构造函数,所有很多时候我们没有调用父类构造,并不是不调用也可以,而是不写它就会自动调用父类的默认构造函数。
图3
对于第三点我们继续举例说明:
如果我们在father中重载构造函数,在子类的构造函数中又没有调用则就会出现错误。有两种解决方法。
图4
第一种方法,我们除了重载构造函数,还要加上默认的构造函数fathter()。
图5
第二种方法:在子类的构造函数中用super调用父类重载后的构造函数
图6
继承细节3:使用super的注意事项
对于第四点较为简单,在子类中想调用父类的构造器则直接用super即可。
图7
对于第五点,super必须在函数的第一句 ,否则就会报错。
图8
对于第六点,super()和this()语法都要放在构造函数的第一句,所有super()和this()不能同时出现。
图9
继承细节4:object是所有类的父类
图10
继承细节5:一个父类可对应多个子类,但一个子类只能对应一个父类
在继承关系中,我们要注意is-a的逻辑关系,一个父类可以有多个子类,但一个子类只能对应一个父类。如同一个父亲可以有多个孩子,但是每个孩子都只能对应一个父亲。
图11
(2)super的语法
图12
在子类的方法中,我们可以用super去访问父类的属性或者是方法,但需要注意的是私有的属性和方法是无法访问到的。
图13
(3)super和this的比较
图14
(4)多态:对象的多态
多态细节1:编译类型和运行类型
图15
我们结合例子来说明情况,我们先定义父类为Aniaml,两个子类分别为Dog、Cat。在main函数中分别new三个animal对象,在例子中的animal1和animal2编译类型都是Animal对象,运行类型却为两个子类。可以得出编译类型和运行类型可以不一致,编译类型一旦定义就不能改变,但运行类型可以变化。
图16
多态细节2:向上转型
图16
图17
结合例子(图17),Animal为父类,Dog和Cat为子类。特别需要注意的是,利用向上转型时,当一个方法同时存在于父类和子类时(重写),调用该方法会遵循就近原则(图18)(例子图19),也就是调用子类的该方法,没有再向上层父类寻找。
图18
图19
当使用向上转型的时候的时候,如果一个方法只存在于子类而不存在于父类,则无法调用。必须同时存在于父子类才能调用。
图20
多态细节3:向下转型
图21
通过上面向上转型的学习我们可以知道,向上转型编译类型为父类,运行类型为子类,无法调用子类的所有方法。利用向下转型我们可以调用子类的所有成员(图22)。
图22
(5)方法的重载和重写
重载和重写的区别还是有很多的,如下图。
图23
特别需要注意的是:
(1)重载的参数列表是不同的,而重写则必须相同
(2)重写的返回类型子类型要和父类型一致或者是父类型其子类(小于等于)
父子类返回类型相等
图24
子类返回对象为父类的返回对象的子类
图25
(3)重写中子类的修饰符访问范围不能比父类小(大于等于)
子类修饰符范围和父类修饰符范围相同
图26
子类修饰符范围比父类修饰符范围大
图27