面向对象编程(中级)
快捷键
- alt + insert 生成构造器
- ctrl + h 查看类的继承关系
- ctrl + b 找到类
- .var 直接在 new 后面创建变量名
- 20.fori 快速写循环
模板
- main
- sout System.out.println();
- fori 模板快捷键
包
- 共同开发一个java项目,想定义同样一个名字的类
- 包的三大作用
- 解决包重名
- 更好管理包
- 包可以控制访问范围
- 包的基本语法
- package com.zhx
- 关键字 package
- com.zhx 包名
- package com.zhx
- 包的本质
- 包对应文件目录
- 包的命名
- 命名规则
- 只能包含数字、字母、下划线、小圆点、但不能数字开头、不能是关键字、保留字
- demo.class.exec1 错
- demo.12a // 错 12a数字开头
- demo.ab12.oa
- 只能包含数字、字母、下划线、小圆点、但不能数字开头、不能是关键字、保留字
- 命名规范
- 小写字母+小圆点一般是
- com.公司名.项目名.业务模块名
- com.sina.crm.user
- 命名规则
- 常用的包
- java.lang.* // lang 是基本包,不用引入
- Java.util.* // 系统工具包,使用Scanner
- Java.net.* // 网络开发
- java.awt.* // 界面开发
- 如何导入包
- import java.util.Scanner; // 表示只会引入 Scanner 推荐方式
- import java.util.*; // 导入 java.util下的所有 类
- 注意事项和细节
- package 的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一句package语句
- import 放在 类的定义下面,可以有多条没有先后顺序
访问修饰符
-
基本介绍 java 提供四种
- public 对外公开
- protected 受保护,对子类和同一个包中的类公开
- 默认级别,没有修饰符,向同一个包的类公开
- 私有级别,private修饰,只有本类可以使用
-
四种访问修饰符的访问范围
-
访问级别 访问控制修饰符 同类 同包 子类 不同包 公开 public √ √ √ √ 受保护 protected √ √ √ × 默认 没有修饰符 √ √ × × 私有 private √ × × × -
使用的注意事项
- 修饰符可以用来修饰类中的属性,成员方法以及类
- 只有默认的和public才能修饰类
- 成员方法的访问规则和属性完全一致
-
封装
- encapsulation 把抽象出来的数据[属性]和对数据的操作封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作,才能对数据进行操作
- 对电视机的操作就是典型的封装
- 封装的理解和好处
- 隐藏实现细节方法 <– 调用(传入参数)
- 可以对数据进行验证,保证安全合理
- Person {name, age} 对数据进行验证
- 封装的实现步骤
- 将属性私有化 [不能直接修改属性]
- 提供一个公共的set方法,用于对属性判断并赋值
- public void setXxx() {// 数据验证的业务逻辑}
- 提供一个公共的get方法,用于获取属性的值
- public 数据类型 getXxx() {// 权限判断}
- 构造器与setXxx结合
- 在构造器中使用setXxx,保证业务逻辑
继承
-
为什么需要继承
- 继承,提高代码的复用性
-
基本介绍和示意图
- 多个类存在相同属性和方法时,可以抽象出父类,子类继承 extends
-
继承的基本语法
- class 子类 extends 父类 {}
- 子类拥有父类的属性和方法
- 父类又叫超类
- 子类又叫派生类
- class 子类 extends 父类 {}
-
继承带来的遍历
- 复用性
- 提升了扩展性和维护性
-
继承的深入讨论/细节问题
- 子类继承了所有的属性和方法,但是私有属性不能直接在子类访问,要通过(父类提供的)公共的方法取访问。非私有的属性和方法可以直接访问
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类子类对象时,不管使用子类的哪个构造器,默认都会调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
- 如果希望指定去调用父类的某个构造器,则显示调用,super(参数列表)
- super在使用的时候,必须放在构造器的第一行(super只能在构造器里使用)
- super() 和 this() 都只能放在第一行,因此两个方法不能共同存在于一个构造器
- java的所有类都是Object类的子类
- 父类构造器的调用不限于直接父类!将一直往上追溯到object类
- 子类最多继承一个父类(指直接继承),即java是单继承机制
- 不能滥用继承,子类和父类必须满足 is-a 的逻辑关系
-
继承的本质分析 重要
- 创建子类对象时,内存的变化:子类创建好后,简历查找关系
- new class 首先加载父类信息到方法区,依次递归到最低的子类、
- 在堆中分配内存空间,先创建父类的空间,再创建子类空间,名字冲突也不要紧
- 查找规则,首先看子类是否有该属性,如果子类有该属性,并且可以访问,则返回信息,如果子类没有该属性,就看父类有没有该属性,如果父类有该属性,可以访问,就返回信息,如果父类没有递归向上找,直到Objecte
- 创建子类对象时,内存的变化:子类创建好后,简历查找关系
-
super 关键字
-
基本介绍 代表父类的引用,用于访问父类的属性、方法构造器
-
基本语法
- 可以访问父类的属性,但是不能访问父类的private属性 super.属性名
- 可以访问父类的方法,不能访问父类的private方法 super.方法名
- 访问父类的构造器 super(参数列表) 只能放在构造器的第一句,只能是第一句
-
super的好处与细节
- 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类完成子类的初始化)
- 当子类有和父类的成员重名时,为了访问父类的成员,必须使用super
- super的访问不限于父类,如果爷爷类也有同名的原则,也可以使用super去访问爷爷类的成员
-
super和this的比较
区别点 this super 1 访问属性 访问本类中的属性,如果本类没有此属性则从父类中继续查找 从父类开始查找属性 2 调用方法 访问本类的方法,如果本类没有方法则继续从父类中查找 直接访问父类中的方法 3 调用构造器 调用本类构造器,必须放在构造器的首行 调用父类构造器,必须放在父类构造器的首行 4 特殊 表示当前对象 子类访问父类对象
-
方法重写
-
基本介绍
- 方法覆盖就是子类的一个方法和父类的某个方法名称返回参数,返回类型都一样,我们就说子类的这个方法覆盖了父类(也有可能是爷爷类)的方法。
- 快速入门
-
方法重写的注意事项和注意细节
- 子类的方法的参数,方法名称,要和父类方法的参数,方法名称完全一样
- 子类方法的返回类型要和父类返回类型一样,或者是父类返回类型的子类
- 子类方法不能缩小父类方法的访问范围
-
名称 发生范围 方法名 形参列表 返回类型 修饰符 重载 本类 必须一样 类型,顺序,个数至少一个不同 无要求 无要求 重写 父子类 必须一样 相同 子类重写的方法返回类型和父类一样,或者是其子类 子类方法不能缩小父类方法的访问范围
多态 polymorphic
-
传统的问题复用性不高,并且不利于代码维护。需要使用多态
-
基本介绍
- 方法或对象具有多种形态,建立在封装和继承基础之上的
- 多态的具体表现
- 方法的多态:重写和重载体现了多态,传入不同的参数,就会调用不同的方法
- 对象的多态(核心,困难,重点)
- 一个对象的编译类型和运行类型可以不一致
- Animal animal = new Dog(); [animal 的编译类型是 Animal, 运行类型是Dog]
- animal = new Cat(); [animal 的运行类型变成了Cat,编译类型仍然是Animal]
- 编译运行在定义对象时就确定了不能改变
- 运行类型是可以变化的
- 编译类型看 = 号的左边,运行类型看 = 号的右边
- 一个对象的编译类型和运行类型可以不一致
-
多态的注意事项和使用细节
-
多态的前提是:两个类存在继承关系,
-
多态的向上转型
-
本质:父类的引用指向了父类的对象
-
语法:父类类型 变量名 = new 子类类型()
-
特点:编译类型看左边,运行类型看右边。
-
不能调用父类中的所有成员(需要遵循访问权限)
不能调用子类的特有成员
最终运行效果看子类的具体实现,即调用方法时,按照从子类开始查找
-
-
-
多态的向下转型
- 语法 子类类型 引用名 = (子类类型) 父类引用
- 强转父类的引用,不能强转父类的对象
- 要求父类的引用必须指向的是当前目标类型的对象
- 当向下转型后,可以调用子类类型中的所有成员
-
属性没有重写之说!属性的值看编译类型
-
instanceOf比较操作符,用于判断对象的运行类型是否是XX类型或者XX类型的子类型,不是函数
-
java的动态绑定机制(非常非常重要)
- 当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定
- 调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
-
多态的应用
- 多态数组
- 定义:定义类型为父类类型,里面保存的实际元素为子类类型
- 多态参数
- 方法定义的形参类型为父类类型,实参类型允许为子类类型
- 应用实例:主人喂动物
- 多态数组
-
Object 类详解
- equals方法
- == 和 equals 的对比
- == 是一个比较运算符
- == : 既可以判断基本类型,也可以判断引用类型
- == :如果判断基本类型,判断的是值是否相等
- == :如果判断引用类型,判断的是地址是否相等,即判断是不是同一个对象
- equals 只能判断引用类型
- 默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等
- == 是一个比较运算符
- == 和 equals 的对比
- hashCode
- 提高具有哈希结构的容器的性能
- 两个引用如果指向同一个对象,哈希值一样
- 两个引用不同,hash值不一样
- 哈希值主要根据地址号来,但不等价于地址号
- 如果需要也会重写hashCode
- toString方法
- 基本介绍
- 默认返回 全类名+@+哈希值的十六进制。子类往往重写toString方法,用于返回对象的属性信息
- toString方法,打印对象或者拼接对象属性,往往会重写(快捷键)
- 直接输出一个对象,默认会调用toString
- 基本介绍
- finalize方法
- 基本介绍
- 对象回收时,自动调用对象的finalize方法,子类可以重写该方法,做释放资源操作
- 当某个对象没有任何应用时,jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制销毁该对象,在销毁该对象前,会先调用finalize方法
- 垃圾回收器,系统调用,有自己的GC算法,可以通过System.gc()主动调用
- 实际开发中几乎不会使用 finalize 方法,更多就是为了应付面试
- 基本介绍
- equals方法
-
断点调试
- 在断点调试过程中,是运行状态,是以运行类型来执行的,看不了编译类型
- 出错时会调试到出错代码行
- 断点调试也能帮助查看java底层代码,提高java水平
- F8 逐行执行
- F7 进入,如何退出?回到主方法的下一行shift + F8
- 执行到下一个断点F9, 支持动态下断点
- 可以查看动态绑定机制的工作方式
-
作业
- homework6 this和默认调用的访问权限一致
-
本章总结
- idea介绍,JB产品,最好的Java开发工具
- 包
- 应用场景。包的三大作用。包的基本语法。包的本质时不同文件夹
- 访问修饰符
- 4种
- 访问范围
- 面向对象编程三大特征
- 封装
- 步骤 私有化,set get
- 构造器和setter
- 继承
- super
- 方法的重写
- 多态
- 多态的前提是存在继承关系
- 向上转型
- 向下转型
- java的动态绑定机制
- 多态数组,多态的参数
- Object类详解
- 封装
房屋出租系统
- 实现基于文本界面的房屋出租系统。增删查改,显示信息
- 项目设计-程序框架图
- 分层模式,使用的模式管理
- 框架图,有哪些类【文件】,明确类与类的调用关系HouseView.java
- 分类houserent view service domain utils
- 类直接调用方法,而没有创建对象,当一个方法是static时,就是静态方法,静态方法可以直接通过类名调用
- House有哪些属性?通过给出的界面分析得到
- 编号 房主 电话 地址 月租 状态(未出租,已出租)
- id name phone address rent state setter getter
- 方便输出对象信息,使用toString方法
- 显示主菜单和完成退出软件
- 化繁为简(一个一个功能实现)
- 完成功能,思路分析,代码完成
- mainMenu
- do while 属性 loop, key 接收用户选择
- 1.新 增 房 源
- 2.查 找 房 屋
- 3.删 除 房 屋 信 息
- 4.修 改 房 屋 信 息
- 5.显 示 房 屋 信 息
- 6.退 出
- 请求输入选择(1-6)
- switch 先输出语句
- 测试整个系统
- HouseView().mainMenu()
- do while 属性 loop, key 接收用户选择
- 化繁为简(一个一个功能实现)
- 显示房屋列表
- 需要编写HouseView和HouseService
- HouseSevice中使用House数组,指定数组的大小,自己创建数据
- 编写list方法
- listHouses()显示房屋信息
- 房屋列表
- 显示
- 房屋显示完成
- 编写方法add,将新的house对象添加到houses数组中,返回是否成功
- 界面显示
- 获得姓名,电话,地址,月租,状态
- id按自增长的方法添加
- 需要一个属性houseNumber记录当前有多少个房屋信息
- 如果不行提示无法添加
- 设计一个id自增长方式,idCounter
- 界面显示
- 删除房源
- 删除房源()功能说明 输入判断是否是大写的Y/N,readConfirmSelection
- del编写,找到要删除的下标
- 不存在怎么处理,如果找到了怎么处理。当前存在的最后一个房屋置空
- 删除房屋失败,是否成功
- 退出确认
- 查找房屋信息
- 修改房屋信息的功能
- 修改原有的信息
- update
- 修改房屋
- readInt()默认-1
- 需求分析
- 设计