(1)介绍
将数据和具体实现封装在一起 用户只需要通过简单的行为就可以操作数据。
(2)封装的理解和好处
① 隐藏实现细节;方法(连接数据库)<–调用(传入参数)
② 可以对数据进行验证,保证安全合理。
(3)封装实现的步骤
① 将属性进行私有化private 【不能直接修改属性】;
② 提供一个公共的(public)set方法,用于对属性判断并赋值;
③ 提供一个公共的(public)get方法,用于获取属性的值;
便捷方法:
alt + insert 键 弹出框,选择Getter and Setter即可。
(4)案例
- 为了避免构造器破环私有访问属性的隐私,可以将set方法在构造器内调用即可。
(1)介绍
- 继承可以解决代码复用
- 当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类种定义这些相同的属性和方法。
- 所有的子类不需要重写定义这些属性和方法,只需要通过extends来声明继承父类即可。
(2)继承的基本语法
① 子类就会自动拥有父类定义的属性和方法;
② 父类又叫超类,基类;
③ 子类又叫派生类。
(3)案例
- 输出
(4)细节
① 子类访问父类的私有属性和方法
- 子类继承了所有的属性和方法,父类的私有属性和方法不能在子类直接访问,要通过父类提供的公共的方法去访问;
② 子类必须调用父类的构造器
- 子类必须调用父类的构造器,完成父类的初始化
- 结果
③ 子类用super(形参列表)调用父类构造器
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器
- 如果父类没有提供无参构造器,则必须在子类的构造器种用去指定使用父类的哪个构造器=>完成对父类的初始化工作。
- 否则,编译不会通过;
④ super的放置限制
-
super在使用时,必须放在子类构造器的第一行;(super只能在构造器中使用)
-
super()和this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器;
⑤ object类
java所有类都是Object类的子类,Object是所有类的基类;
⑥ super多层继承时的调用顺序
-
父类构造器的调用不限于直接父类,将一直往上追溯直到Object类(顶级父类),从上向下依次调用;
-
即:A是B的父类,B是C的父类,那么C可以调用A
-
并且在构造器里,会从顶级类一层层往下调用
-
即:A构造器被调用->B构造器被调用->C构造器被调用
⑦ 单继承机制
- 子类最多只能继承一个父类(指直接继承),即java中是单继承机制;
思考:如何让A类继承B类和C类?
答:可以让A类继承B类,B类继承C类,则A可以用B和C中的方法,相当于让A继承了B和C;
⑧ 继承必须满足逻辑关系
不能滥用继承,子类和父类之间必须满足is - a(包含) 的逻辑关系;
(5)继承的本质分析⭐⭐⭐⭐⭐
- 案例
//访问顺序(调用属性或者方法的顺序)
- 查看子类是否有该属性
- 如果子类有这个属性,并且可以访问,则返回信息
- 如果子类没有,就看父类,如果有,并且可以访问,就返回信息
- 一直从下级往上级找,直到object或者找到后返回了信息
- 如果要查找的属性在中间层级是私有的,在高层级是公有的。不会跳过中间层级,而会报错
(6)练习
- 编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息
- 编写PC子类,继承Computer类,添加特有属性【品牌brand】
- 编写NotePad子类,继承Computer类,添加特有属性【color】
- 编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值,以及从Computer类继承的属性赋值,并使用getInfo方法打印输出信息
(1)引入
解决代码的复用性
(2)基本介绍
方法和对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承的基础上的。
(3)具体表现
- 方法的多态
- 方法的重载体现多态
- 方法的重写体现多态
- 对象的多态⭐⭐⭐⭐⭐
- 一个对象的编译类型和运行类型可以不一致;
- 编译类型在定义对象时,就确定了,不能改变;
Animal animal = new Dog();
animal类型是Animal不能改变
- 运行类型是可以改变的;
animal = new Cat();
即:对象引用的指向是可以改变的,不指向Dog对象,指向Cat类型
编译类型看定义时 = 号的左边,运行类型看 = 号的右边
(3)例子
(4)多态注意事项和使用细节
多态的前提是:两个对象(类)存在继承关系;
- 多态的向上转型:
- 本质:父类的引用指向(接收)了子类的对象;
- 语法:父类类型 引用名 = new 子类类型();
- 特点如下:
- 可以调用父类中的所有成员(需要遵循访问权限);
- 不能调用子类的特有的成员,因为在编译阶段,能够调用哪些成员,是由编译类型来决定的;
- 最终运行效果看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法,然后调用,规则和前面讲的方法调用规则一致。
- 多态的向下转型
- 语法:;
- 只能强转父类的引用,不能强转父类的对象;
- 要求父类的引用必须指向的是当前目标类型(即等号前的子类类型)的对象;
相当于animal原来指向一个Cat对象 现在创建了个新名字(新引用),还是指向Cat(通过animal来引用)
-
当向下转型后,可以调用子类类型中所有的成员。
-
属性没有重写(覆盖)之说,属性的值看编译类型;
也就是只会查找父类的
- instanceof 比较操作符:用于判断对象aa的运行类型是否为BB类型或者BB类型的子类型。aa是否包含于BB。返回值为true/false
例如:aa extends BB
则aa instanceof BB => true;
(5)练习
例子2:
- 子类对象向上转型为父类对象,OK
- 父类对象再想向下转型,只能转为原先的子类对象或者子类对象的子类对象。(只能往更低处转,不能同级转也不能往高处转)
(6)多态的应用
① 多态数组
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型。
实例:现有一个继承结构如下,要求创建1个Person对象,2个Student对象和2个Teacher对象,统一放在数组中,并调用每个对象的say方法。
② 多态参数
-
定义员工类Employee,包含姓名和月工资【private】,以及计算年工资getAnnual的方法。普通员工和经理继承了员工,经理类多了奖金bonus属性和管理manage方法,普通员工类多了work方法,普通员工和经理类要求分别重写getAnnual方法;
-
测试类中添加一个方法showEmpAnnual(Employee e),实现获取任何员工对象的年工资,并在main方法中调用该方法;
-
测试类中添加一个方法,testWork,如果是普通员工,则调用work方法,如果是经理,则调用manage方法。
-
Employee.java
- ComEmployee.java
- Manager.java