面向对象编程1(OOP)
面向对象编程(OOP)
* 面向对象概念
* 方法回顾和加深
* 对象的创建分析
* 面向对象的三大特性
* 抽象类和接口
* 内部类及OOP实战
面向过程 & 面向对象
什么是面向对象
面向过程考虑步骤,第一步做什么,第二步做什么
面向对象,适合处理复杂问题,先对解决问题需要哪些来分类。然后对这些分的类进行单独思考,分类下的细节进行面向过程思考
以类的方式组织代码,以对象的组织(封装)数据
三大特性
- 封装
- 继承
- 多态
从认识论角度考虑先有对象,然后对其特征进行抽象形成类
从代码角度先有类作为模板,然后建立对象
方法
类方法static和类一起加载的,非static对象方法只有在类实例化后才存在的方法。
静态方法不能直接调用非静态方法,一个已经存在的方法是不能调用一个不存在的方法的。必须用对象来调用对象方法
创建与初始化对象
创建对象
使用new关键字创建对象,此时分配内存空间,给创建好的对象进行默认构造器初始化或者调用自定义构造器初始化。
this指针表示当前类(对象)
注: 一个项目应该只存在一个main方法,写一个单独的类专门用来测试。
IDEA里分屏左右两边同时显示两个文件,用来对照。在想跟平显示的文件上右键->Split Virtically/Horizontally
构造器
- 类即使什么都不写,也会有个默认构造器方法,编译后会自动给类加上该默认构造器。
可以通过查看.class文件,看见默认构造器.
默认构造器,是无参构造器,空方法 - 自定义构造器:
要求构造器和类同名,没有返回值且不写void - 一旦定义了有参构造器,默认无参构造器就失效了,如果想要使用无参构造器,需要显示手动写出来
IDEA里alt+insert会自动生成构造器
![]()
内存分堆和栈,栈里放方法和对象的引用,堆又分出一个特殊的部分方法区,存放类和常量的地方和静态方法区。
封装(private)
-
"高内聚,低耦合"
高内聚:类内部的数据操作细节自己完成,不允许外部干涉
低耦合:仅暴露少量的方法给外部使用
封装即数据的隐藏,不直接访问数据,通过接口来访问。
私有只能在类内访问(如类内的方法),外部不能通过对象访问
实现方式:属性私有,get/set -
封装的意义:
- 提高程序的安全性,保护数据
- 隐藏代码实现细节
- 统一接口
- 增强系统的可维护性
属性封装可以在方法里对属性做约束处理,防止外部随意更改值
例
private age;
public voide setAge(int age){
if(age>120 || age< 0 ){ //不合法
this.age=3;
System.out.println("超过合理年龄,变成三岁")
}else{
this.age = age;
}
}
使用时如果s1.setAge(1000)就会变成三岁
继承
- extend,表示类和类之间的父子关系, java只有单继承
(组合是把其他类对象作为属性包含进来,除此之外还有依赖聚合等)
访问权限范围public>protected>default>private,私有的方法不能被继承
在java中默认所有的类都默认直接或间接继承object. - super
- 子类初始化时,会先初始化父类再初始化子类。
- 子类构造器第一行默认调用父类无参构造器super(). 所以当我们类里写了有参数构造器时,一定第一步要显示手写无参构造,否则子类继承默认调用无效的父类无参构造器容易报错。
- 构造器也可以通过this()调用本身类的其他构造器,同样也不必须将this()放在第一行.因此一个构造器不能同时调用父类构造器,又调用子类构造器
-
方法的重写
重写需要有继承关系,而且是方法的重写和属性无关
特点:- 方法名和参数列表必须相同,方法体不同
- 修饰符,范围可以扩大但是不能缩小.public>procted>Default>private
- 抛出的异常,范围可以被缩小,但是不能被扩大:ClassNotFoundException(小)-->Exception(大)
-
父类的引用可以指向子类对象。
静态方法和非静态方法区别很大,只有非静态的方法才有重写.
对于静态方法重的调用只和引用变量的数据类型有关
![]()
对于非静态方法,调用方法被子类重写,只和调用的new的对象有关
![]()
-
为什么要重写?
父类的功能,子类不一定需要,或者不满足。Alt+Insert
多态
同一个方法可以根据发送对象的不同而采用多种不同的行为方式
1. 动态编译,运行前是不能确定类型的。
一个对象的实际类型new出来的是确定的,但引用类型就不确定了.父类的引用可以指向子类对象.
Son s1 = new Son;
Parent s2 = new Son;
对象能执行哪些方法,主要看对象左边的类型和右边关系不大.
指向子类的父类引用只能调用左边也有的方法,如果子类覆盖了该方法,实际执行的是子类方法,否则调用的是父类里写的方法。注意父类引用不能调用子类特有的方法。
这也符合动态编译,执行前写的是Parent那么里面就只能调用Parent里的方法,而动态编译后对象赋值成Son自然就调用Son里复写的方法了。
2. 多态注意事项
- 多态是方法的多态,属性没有多态
- 父类和子类,有联系,否则类型转换异常ClassCastExxception
- 存在条件:继承关系,方法需要重写,父类引用指向子类对象
不能重写的方法- static 类方法不属于实例
- final 常量
- private 方法
3. instanceof + 强制转换
X instanceof Y, 判断X是不是Y类型的,是该类型或者子类型的实例
动态实例结合instanceof使用,判断实际传递过来的参数具体是什么类型
Object>Parent>Son 父类对象可以转换为子类对象
1.父类引用指向子类对象
2.把子类转换为父类,向上转型 直接赋值就好
3.把父类转换为子类,向下转型 强制转换
4. 方便方法的调用,减少代码重复率




浙公网安备 33010602011771号