目录
什么是面向对象
面向对象是一种编程思想,开发范式。除了面向对象,还有面向过程、指令式编程和函数式编程。在所有的编程范式中,我们接触最多的还是面向过程和面向对象两种。
为什么有面向对象
早期先有面向过程思想,随着软件规模的扩大,问题复杂性的提高,面向过程的弊端越来越明显,出现了面向对象思想并成为目前主流的方式。
怎么体现面向对象
面对对象跟面向过程的区别
面向对象:
- 面对对象的关注点是类。
- 对于每个事务的主要关注点是事务中的对象,对象拥有的属性和行为/功能。
面向过程:
- 面向过程的关注点是函数。
- 对于每个事务的主要关注点是事务执行的步骤。
例:
事务:小明开车去玩
面向对象:主要关注的是事务中存在了“小明”和“车”两个对象,两个对象存在什么样的属性和行为/功能。“小明”存在了开车和玩的两个行为。“车”存在了行驶功能。
面向过程:主要关注的是执行的步骤。小明先开车门、坐到车里、启动汽车、驾驶汽车去目的地、玩
注意点:
面向对象可以帮助我们从宏观上把握、从整体上分析整个系统。 但是,具体到实现部分的微观操作(就是一个个方法),仍然需要面向过程的思路去处理。
优缺点:
面对对象:适合解决复杂问题。代码扩展性强、可维护性高。
面向过程:适合解决简单问题。扩展能力差、后期维护难度较大。
面对对象的特性
封装性
概念:将事物封装成抽象的类,并且类内部的信息对信任的对象开放,对不信任的对象隐藏。通俗的讲,把该隐藏的隐藏起来,该暴露的暴露出来。
Java的体现:Java提供四种权限修饰符(从大到小:public、protected、缺省、private),来控制类和类内部成员的可见性范围。
修饰符 本类内部 本包内 其他包的子类 其他包非子类 private √ × × × 缺省 √ √ × × protected √ √ √ × public √ √ √ √
封装有好处是:高内聚,低耦合
- `高内聚`:类的内部数据操作细节自己完成,不允许外部干涉;
- `低耦合`:仅暴露少量的方法给外部使用,尽量方便外部调用
继承性
概念:子类继承父类,拥有父类的内部信息。
Java体现:使用关键字extends。Java只支持单继承
好处:
1、减少代码的冗余,提高代码的复用性
2、更有利于代码的扩展
3、是多态的前提
多态性
Java的体现:父类的引用指向子类对象
对象的多态:在Java中,子类的对象可以替代父类的对象使用。所以,一个引用类型变量可能指向(引用)多种不同类型的对象
- 多态的理解:
对于多态需要从两个 时期说明,编译时期和运行时期。在编译时期是声明的是父类类型的变量,但是不知道指向的实际对象的类型。只有在运行时期才能确定该变量所指向对象的具体类型。
- 多态的前提:
1、继承 2、方法的重写
- 好处和弊端
- 好处:变量引用的子类对象不同,执行的方法就不同,实现动态绑定。代码编写更灵活、功能更强大,可维护性和扩展性更好了
- 弊端:一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法。
类和对象
概念
类:具有相同特征的事物的抽象描述,是`抽象的`、概念上的定义。
对象:实际存在的该类事物的`每个个体`,是`具体的`,因而也称为`实例(instance)`。
类的内部成员
- 属性
所有变量的分类:
- 成员变量:实例变量、类变量(静态变量)
- 局部变量:形参、方法局部变量、代码块局部变量
成员变量跟局部变量的不同
- 在内存中存储的位置不同
- 实例变量:堆
- 局部变量:栈
- 生命周期
- 实例变量:和对象的生命周期一样,随着对象的创建而存在,随着对象被GC回收而消亡, 而且每一个对象的实例变量是独立的。
- 局部变量:和方法调用的生命周期一样,每一次方法被调用而在存在,随着方法执行的结束而消亡,而且每一次方法调用都是独立。
- 修饰符
- 实例变量:public,protected,private,final,volatile,transient等
- 局部变量:final
- 默认值
- 实例变量:有默认值
- 局部变量:没有,必须手动初始化。其中的形参比较特殊,靠实参给它初始化。
- 方法
方法(method、函数)的理解
方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程。
将功能封装为方法的目的是,可以实现代码重用,减少冗余,简化代码。
方法调用内存分析
方法没有被调用的时候,都在方法区中的字节码文件(.class)中存储。
方法被调用的时候,需要进入到栈内存中运行。方法每调用一次就会在栈中有一个入栈动作,即给当前方法开辟一块独立的内存区域,用于存储当前方法的局部变量的值。
当方法执行结束后,会释放该内存,称为
出栈
,如果方法有返回值,就会把结果返回调用处,如果没有返回值,就直接结束,回到调用处继续执行下一条指令。栈结构:先进后出,后进先出。
- 构造器
注意点
1. 当我们没有显式的声明类中的构造器时,系统会默认提供一个无参的构造器并且该构造器的修饰符默认与类的修饰符相同
2. 当我们显式的定义类的构造器以后,系统就不再提供默认的无参的构造器了。
3. 在类中,至少会存在一个构造器。
4. 构造器是可以重载的。
- 代码块
- 作用:对Java类或对象进行初始化
- 分类: 静态代码块、非静态代码块
关键字
abstract(抽象)
作用:
- 只能修饰类和方法。
- 当修饰类时,该类为抽象类。抽象类无法实例化,只能创建抽象类的子类,实例化子类。
- 当修饰方法时,该方法为抽象方法。抽象方法没有方法体。
- 类中存在抽象方法,该类必须为抽象类
说明:
1、抽象类不能创建对象
2、抽象类中,也有构造方法,是供子类创建对象时,初始化父类成员变量使用的。
3、抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
4、抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。
interface(接口)
概述:接口就是规范,定义的是一组规则。
接口的内部成员:
- jdk8之前:抽象方法、全局常量
- jdk8时:抽象方法、全局常量、默认方法、静态方法
- jdk9之后:抽象方法、全局常量、默认方法、静态方法、私有方法
注意点:Java是单继承,多实现。实现了接口的类叫实现类
enum(枚举)
概述:枚举类型本质上也是一种类,只不过是这个类的对象是有限的、固定的几个,不能让用户随意创建。
说明:enum是之后出现的
annotation(注解)
概述:Annotation 可以像修饰符一样被使用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明。 注解可以在类编译、运行时进行加载,体现不同的功能。
元注解:
- @Target:用于描述注解的使用范围
- @Retention:用于描述注解的生命周期
- @Documented:表明这个注解应该被 javadoc工具记录
- @Inherited:允许子类继承父类中的注解
this和super
this:指向调用该非静态内部成员的对象
super:指向父类的内部成员
static
可以修饰的成员:成员变量、方法、代码块、内部类
特点:
1、随着类的加载而加载
2、优先于对象存在
3、修饰的成员,被所有对象所共享
4、访问权限允许时,可不创建对象,直接被类调用
final
作用:表示最终的,不可修改的
可以修饰的成员:
- 类:表示这个类不能被继承,没有子类。提高安全性,提高程序的可读性
- 方法:表示这个方法不能被子类重写。
- 变量:final修饰某个变量(成员变量或局部变量),一旦赋值,它的值就不能被修改,即常量,常量名建议使用大写字母。