OOP(中级)——继承、封装、多态
一、包
1、包的作用
(1)区分相同名字的类
(2)当类很多时,很好的管理类
(3)控制访问范围
2、包的基本语法
package com.king;
(1)package 关键字,打包
(2)com.king;包名
3、实例:在不同的包中创建dog类
二、访问修饰符
1、四种访问修饰符
JAVA提供四种访问修饰符,用于控制方法和属性(成员变量)的访问权限
1.public(公开):对外公开
2.protected(保护):对子类和同一个包中的类公开
3.默认:同一个包的类公开
4.private:只有类本身可以访问,不对外公开
2、实例:访问修饰符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hf4ExX0B-1632900577496)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210924160500133.png)]
创建了四种修饰符的变量。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFOLRuqW-1632900577497)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210924160612857.png)]
同类下,四种均可以访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-49tzs4Ee-1632900577499)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210924161019070.png)]
同包下不同类,private无法访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sfASHhbe-1632900577500)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210924161100181.png)]
不同包下,只能访问public
3、修饰符细节
只有默认和public才能修饰类。
三、封装(encapsulation)
1、封装
封装:把数据和方法封装在一起,数据保护在内部,程序的其他部分只有通过被授权的方法,才能对数据进行操作。
封装的理解和好处:1.隐藏实现细节 2.可以对数据及进行验证,保证安全合理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m1MpwDsQ-1632900577501)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210924165620392.png)]
对于private,我们赋值和读取要调用set和get函数
2、封装与构造器
构造器可以绕过set方法,这样会导致程序的不稳定。我们可以在构造器中,加入set方法。这样使用构造器也逃不过验证。
四、继承(extend)
1、为什么要继承
继承提升了代码复用性,我们不用写一些重复的属性或者方法。
2、继承
当我们有多个类存在相同的属性和方法,我们可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法。而子类不需要定义这些属性和方法,只需通过**extend(继承)**父类即可,
语法: class 子类 extends 父类{ }
(1)子类(派生类)自动拥有父类定义的属性和方法
(2)父类(超类、基类)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FJ42UXZ-1632900577501)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210926164937444.png)]
3、子类的细节
(1)子类继承所有的属性和方法,但是私有属性不能在子类直接访问,要通过公共方法去访问。
(2)子类必须调用父类的构造器,完成父类初始化。(系统自动)
(3)用构造器创建子类对象,默认情况:调用父类的无参构造器;若父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父亲的哪个构造器完成对父亲的初始化操作。
(4)如果希望指定去调用父类的某个构造器,则显式的调用:super(参数列表)
(5)super在使用时,必须放在构造器的第一行。(super只能在构造器中使用)
(6)java所有类都是Object类的子类,Object是所有类的基类。
(7)父类构造器的调用不限于直接父类,将一直往上回溯到Object类(顶级父类)
4、练习
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWUjloXP-1632900577502)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210927103810771.png)]
(1)进入B的默认构造器,调用this(“abc”);
(2)跳到B(“string name”)构造器,构造器中默认有super();
(3)调用super()后,使用A的默认构造器,打印a、
(4)然后打印b name,最后打印 b;结果为 a b name b;
5、报错问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uAKjRnM-1632900577502)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210927105950130.png)]
继承时报错
原因:我在computer父类定义了一个有参构造器,此时没有默认无参构造器。
解决办法:写一个子类的构造器,并且在该构造器中调用super( )方法指向有参构造器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eoPhsvvB-1632900577503)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210927110242950.png)]
五、super
1、super
super:代表父类的引用,用于访问父类的属性、方法、构造器。
(1)super不能访问父类的私有属性。语法:super.属性名
(2)super不能访问父类的私用方法。语法:super.方法名()
(3)访问父类的构造器:super(参数列表);只能放在构造器第一句。
2、super细节
(1)调用父类构造器的好处。分工明确,父类属性由父类初始化,子类的属性有子类初始化。
(2)子类与父类成员有重名时,为了访问父类的成员,必须通过super。
(3)super的访问不限于直接父类,如果爷爷类或者本类中有同名成员,可以用super访问爷爷类的成员,
3、super和this的比较
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SoAxEeHw-1632900577504)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928091334338.png)]
六、方法复写(override)
1、方法复写
方法复写就是子类有一个方法。该方法与父类的某个方法名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法。
2、override细节
(1)子类的返回类型与父类返回类型一样 或者 是父类返回类型的子类。
例如父类返回类型是Object,子类是String
(2)子类方法不能缩小父类方法的访问权限。(可以扩大)
3、overload和override比较
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5DGfDruf-1632900577504)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928123637098.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tMrzUxFt-1632900577504)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928124602814.png)]
调用父类的say方法
七、多态(poly)
1、多态重点
(1)一个对象的编译类型和运行类型可以不一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-79IUxQ8a-1632900577505)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928190107305.png)]
图 7.1
图7.1,编译类型是Animal,但是运行类型是Dog。Animal是Dog的父类
(2)编译类型在定义对象的时候就确定了,不能改变。
(3)运行类型可以改变。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N6ziSt7f-1632900577505)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928192724543.png)]
图7.2 运行类型可以改变
(4)编译类型看 = 号的左边,运行类型看 = 号的右边。
2、多态入门
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-55fJiGSd-1632900577506)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928195829215.png)]
图7.3
图7.3 此时传入参数的编译类型是Animal类和food类。但是我们的运行类型可以根据不同的动物,不同的食物进行改变。这就是多态!!!
3、多态向上转型
前提:两个对象存在继承关系。
(1)本质:父类的引用指向了子类的对象
(2)语法:父类类型 引用名 = new 子类类型()
(3)特点:可以调用父类中的所有成员(遵守访问权限),不能调用子类的特有成员(在编译阶段,能调用哪些成员,是由编译类型来决定)。
(4)最终运行效果,得从运行类型开始。先查看子类有没有该方法,再看父类。
4、多态的向下转型
(1)语法:子类类型 引用名 = (子类类型)父类引用
(2)只能强转父类引用,不能强转父类对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9EBNTX5S-1632900577506)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928220203431.png)]
(3)要求父类的引用必须指向的是当前目标类型的对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t3OMBvOd-1632900577507)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928220517489.png)]
(4)属性没有重写之说,属性的值直接看编译类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McBmf2Wz-1632900577507)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928221352932.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TxNgUXbP-1632900577508)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928221523135.png)]
八、instandof 比较操作符
instandof 用于判断对象的运行类型是否为XX类型或XX类型的子类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jlMAhAor-1632900577508)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928222507529.png)]
九、动态绑定机制
(1)当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定。
(2)当调用属性时,没有动态绑定机制,哪里声明哪里使用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ql8tFnJq-1632900577509)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210928225203326.png)]
十、多态数组
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型。
十一、Object类
1、 == 与 equals
(1)== 既可以判断基本类型,又可以判断引用类型。
基本类型:判断值是否相等
引用类型:判断地址是否相等
(2)equals 只能判断引用类型
(3)equals默认判断的是地址是否相等,子类中往往重写方法,用于判断内容是否相等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FaZIxNho-1632900577509)(C:\Users\King\AppData\Roaming\Typora\typora-user-images\image-20210929103803580.png)]
2、hashCode
(1)返回对象的hash值,为了提高哈希表的性能
(2)两个引用,如果指向的是同一个对象,则哈希值一样的。反之不同。
(4)哈希值根据地址来算出来的,不能理解将哈希值等于地址
3、toString方法
(1)toString方法:默认返回:全类名 + @ + 哈希值的十六进制。
(2)子类往往重写toString方法,用于返回对象的属性信息。
(3)当直接输出一个对象时。toString方法会被默认调用
例如:System.out.println(person1); //默认调用person1.toString
4、finalize方法
当垃圾回收器,不存在该对象的更多引用时。由对象的垃圾回收器调用。
(1)当对象被回收时,系统自动调用该对象的finalize方法。
(2)回收:当某个对象没有任何引用时,则JVM就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁对象。
(3)垃圾回收机制的调用,是由系统来决定。也可也通过system.gc( )