1.面向对象 oop
一. 什么是面向对象
面向过程 与 面向对象
面向对象:将问题拆解为一个个步骤,依次实现调用
面向过程: 将问题步骤(属性,行为)抽象形成对象,通过不同对象之间的调用,组合解决问题
面向对象的三大特征 和 五大基本原则
三大特征 封装 继承 多态
- 封装 隐藏了不可信信息,提供不同级别的数据保护
- 继承 对基类扩展, 实现继承 和 接口继承(必须在子类实现)
- 多态 相同方法在不同情形下的不同表现 如 以父类对象做参数,传入子类
五大基本原则
- 单一性原则: 低耦合 高内聚
- 开放封闭原则:对扩展开放,对修改封闭
- Liskov替换原则:子类必须能够替换基类,保证扩展性,减少代码冗余
- 依赖倒置原则:依赖于抽象,基于接口编程
- 接口隔离原则:多个专门的小接口,不使用胖接口
平台无关性
java如何实现平台无关性
一次编译,多处运行 .class文件字节码 JVM的多平台,jvm只关心 class字节码
jvm 其他支持的语言
scala kotlin groovy scala jruby jython clojure rhino(js 调用java) ceylon(redhat)
值传递和引用传递
为什么说Java中只有值传递
实参 和 形参
实参:调用有参数方法的时候真正传递的内容
形参:用于解说实参内用的参数
值传递 和 引用传递
值传递: 调用函数时将实际参数复制一份, 参数修改不会影响实际参数
引用传递: 调用函数是将实际参数的地址传递到函数中,参数修改影响到实际参数
值传递 | 引用传递 | |
---|---|---|
根本区别 | 会创建副本 | 不创建副本,引用地址 |
现象 | 函数中无法改变原始对象 | 函数中可以改变原始对象 |
java中实际传递的都是值,只不过对于对象参数,值的内容是对象的引用
无论是值传递还是引用传递都是一种求值策略,严格意义上是共享传递,即调用参数是传递给函数的实参的地址的拷贝。当位于栈中,(常量等)拷贝该值;当位于堆中,先拿到堆中的地址,再做相关操作。
二. 封装 继承 多态
多态
同一操作作用于不同的对象,可以有不同的解,产生不同的执行结果
=> 多态是一种运行期的状态,又名动态绑定,需要满足的条件
- 类继承或接口实现
- 子类重写父类的方法
- 父类引用指向子类的对象
方法重写与重载
重载(Overloading) 和 重写(Overriding)
重载: 函数或方法具有相同的名称,单参数的集合不同,同名不同参
重写: 在子类与父类之间 同名且参数集合相同,子类的新方法将覆盖父类原有的方法
重载 VS 重写
1. 重载是编译期的概念, 重写是运行期间的概念
2. 重载在编译期已经确定, 是一种编译时多态,即静态多态
重载的条件
1. 被重载的方法必须改变参数集合
2. 被重载的方法可以改变返回类型(返回类型无关)
3. 被重载的方法可以改变访问修饰符(与可见性无关)
4. 被重载的方法可以声明新的或更广的检查异常
5. 方法在同一个类(同类重载) 或子类(子类重载继承自父类的方法)
继承与组合
继承、组合和代理 是面向对象编程中的 复用技术
继承
继承是类与类之间的层次模型 父类(父接口)与 子类(子接口)
继承是一种 is-a 关系
组合
组合是正义与部分拥有的关系, 即 has-a的关系
继承与组合的区别与类型
继承中, 父类细节 对 子类可见 => 白盒式代码复用 => 父类变化,派生类随之变化
组合中, 拼装享有对象产生新的、更负载的功能,内部细节不可见 => 黑盒式代码复用
继承,编译期确定具体的继承关系
组合,面向接口编程,在运行期确定具体的组合关系
组合和继承优缺点对比
组合关系 | 继承关系 |
---|---|
不破坏封装,松耦合 | 破坏封装,子类与父类耦合紧密 |
良好的可扩展性 | 支持扩展,复杂度提升 |
支持动态组合,运行时整体对象可以选择不同的局部对象 | 不支持动态组合 |
整体类可以包装局部类形成新的接口 | 子类不能改变父类的接口 |
整体类无法获取局部类接口 | 子类能自动继承父类的接口 |
创建整体时,需要创建所有局部对象 | 创建子类对象无需创建父类对象 |
确定需要使用子类向父类的向上转型选用继承,优先使用接口编程的组合关系,更安全简单灵活高效
构造函数
构造函数 特殊的方法 用于创建对象是初始化对象,为对象的成员变量赋初始值
一个类可以有多个构造方法,重载
构造器没有返回类型,不会被继承,承担初始化成员对象数据的任务
在没有专门编写,生成默认的构造函数, 成员变量会进行默认初始化,默认值 int -> 0 Integer -> null
类变量 成员变量 和 局部变量
类变量: 位于 JVM 方法区
成员变量: 位于 JVM 堆内存
局部变量: 位于 JVM 栈内存
成员变量和方法的作用域
修饰词 | 可见范围 |
---|---|
public | 所有类或对象可见,可访问 |
private | 私有方法变量,只有当前类可访问 |
protected | 受保护的,当前类及相同package目录下的其他类可见,子类可见 |
default | 只有当前类和同一package目录下的其他类可见,子类也不可见 |