面向过程的优点是性能比面向对象高,不需要面向对象的实例化;缺点是不容易维护、复用和扩展。面向对象的优点是具有封装、继承、多态的特性,因而容易维护、复用和扩展,可以设计出低耦合的系统;缺点是由于需要实例化对象,因此性能比面向过程低。
~
本篇主要记录内容包括:面向对象的概念、封装、继承、多态
- 上一篇内容:Java基础:Java类与对象
- 下一篇内容:Java基础:Java抽象接口
- 更多知识学习:全网最全的 Java 技术栈内容梳理(持续更新中)
文章目录
- 一、面向对象的概念
- 1、面向对象和面向过程的区别
- 2、对象和类
- 3、面向对象的一般步骤
- 二、特性:封装
- 1、概述
- 2、访问控制符
- 三、特性:继承
- 1、概述
- 2、继承的特点
- 3、方法的重写(覆盖)
- 四、特性:多态
- 1、概述
- 2、注意事项
- 3、编译时多态(方法重载`overload`)与方法签名
- 4、运行时多态
- 5、向上转型与向下转型
一、面向对象的概念
1、面向对象和面向过程的区别
- 面向过程:将问题分解成步骤,然后按照步骤实现函数,执行时依次调用函数。数据和对数据的操作是分离的。
- 面向对象:将问题分解成对象,描述事物在解决问题的步骤中的行为。对象与属性和行为是关联的。
面向过程的优点是性能比面向对象高,不需要面向对象的实例化;缺点是不容易维护、复用和扩展。
面向对象的优点是具有封装、继承、多态的特性,因而容易维护、复用和扩展,可以设计出低耦合的系统;缺点是由于需要实例化对象,因此性能比面向过程低。
Java面向对象的三大特性:封装,继承,多态
2、对象和类
- 对象是现实世界中可以明确标识的实体,对象有自己独有的状态和行为。对象的状态由数据域的集合构成,对象的行为由方法的集合构成。
- 类是定义同一类型对象的结构,是对具有相同特征的对象的抽象。类是一个模板,用来定义对象的数据域和方法。可以从一个类创建多个对象,创建对象称为实例化。
3、面向对象的一般步骤
- 先按照名词提炼问题领域中的对象
- 对对象进行描述,其实就是在明确对象中应该具备的属性和行为
- 通过
new
的方式,创建该事物的具体对象(对象实例化) - 通过该对象调用它以后的功能
二、特性:封装
1、概述
封装(Encapsulation
)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法,也可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问,要访问该类的代码和数据,必须通过严格的接口控制。
外部调用者无需修改或者关心内部实现,内部细节对外部调用透明,外部调用无需修改或关心内部实现
封装的优点: 隐藏细节、减少耦合、便于理解与维护、加强了代码的安全性等
2、访问控制符
Java 提供了三种访问权限,准确的说还有一种是默认的访问权限,加上它一共四种。
private
: 在当前类中可访问,使用对象:变量、方法。 注意:不能修饰类(外部类);default
:在当前包内和访问,不使用任何修饰符。使用对象:类、接口、变量、方法;protected
: 在当前类和它派生的类中可访问,使用对象:变量、方法。 注意:不能修饰类(外部类);public
: 公众的访问权限,谁都能访问,使用对象:类、接口、变量、方法
修饰符 | 访问级别 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
public | 公开 | O | O | O | O |
protect | 受保护 | O | O | O | X |
default | 默认 | O | O | X | X |
private | 私有 | O | X | X | X |
三、特性:继承
1、概述
继承: 从一个已知的类中派生出一个新的类,新类可以拥有已知类的行为和属性,并且可以通过覆盖/重写来增强已知类的能力,子类共性的方法或者属性直接采用父类的,而不需要自己定义,只需要扩展自己的个性化
通过 extends 关键字,可以声明一个子类继承另外一个父类,子类可以直接访问父类的非私有化成员变量,访问父类的私有化成员变量可以使用super.方法()
,
继承的优点:提高代码的复用性、提供了多态的前提、为多态做铺垫等
继承的初始化顺序:父类的静态代码块 -> 子类的静态代码块 -> 父类的构造代码块 -> 父类的无参构造方法 -> 子类的构造代码块 -> 子类的无参构造方法
2、继承的特点
- 通过子类对象既可以调用自身的非
private
修饰的成员,也可以调用父类的非private
修饰的成员 - 父类不可以访问子类特有成员,即使是共有的
- 子类的对象调用成员变量的时候,子类自己有,使用子类,子类自己没有则调用父类,出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用
super
关键字 - 子类的对象调用方法的时候,子类自己有,使用子类,子类自己没有调用的父类,出现与父类一模一样的方法时,会出现覆盖操作,也称为
override
重写、复写或者覆盖
3、方法的重写(覆盖)
有继承关系的子类 中, 子类覆盖父类的方法
方法覆盖的前提是,参数列表、方法名必须相同,返回值类型如果是基本数据类型则必须相同,如果是引用数据类型,则可以时返回值父类方法的返回值的子类类型
注意:
- 方法的重写(override)需方法名相同,参数类型相同
- 子类返回类型小于等于父类方法返回类型;
- 子类抛出异常小于等于父类方法抛出异常;
- 子类访问权限大于等于父类方法访问权限;
- 如果父类方法访问修饰符为private则子类不能重写该方法;
- final 修饰的方法不允许在子类中覆盖;
- 父类被覆盖的方法的参数列表中被声明为 final 的参数,在子类的覆盖方法的中可以不必指定为 final;
- 静态方法不能被覆盖,只能被隐藏;
四、特性:多态
1、概述
多态: 是指对象的多种形态,封装和继承几乎都是为多态而准备的。
Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变量赋值,最终多态体现为 父类引用变量可以指向子类对象
多态调用的三种格式:
- 普通类多态定义的格式:
父类 变量名 = new 子类();
- 抽象类多态定义格式:
抽象类 变量名 = new 抽象类子类();
- 接口多态定义的格式:
接口 变量名 = new 接口实现类();
多态的优点:提高代码的可维护行、提高代码的扩展性
2、注意事项
- 多态分为编译时多态和运行时多态,Java中的多态一般是运行时多态;
- 必须有子父类关系或者类实现接口关系,否则无法完成多态;
- 同一个父类的方法会被不同的子类重写。在调用方法时,调用的为各个子类覆盖后的方法;
- 当变量名指向不同的子类对象时,由于每个子类覆盖父类方法的内容不同,所以会调用不同的方法
- 多态中成员访问的特点:编译看左边,运行看左边
3、编译时多态(方法重载overload
)与方法签名
因为对于方法重载而言,虽然多个方法的方法名相同,但是我们的编译器,可以根据方法调用代码推断出,所要调用的那个方法的方法签名,从而根据方法签名(jvm
唯一的),确定要调用的方法
注:方法签名: 方法名+方法参数列表
4、运行时多态
因为在编译器编译的时候,无法知道,具体调用的是哪个方法的代码,只有当jvm
具体真正执行到调用代码的地方,jvm
才能知道调用的究竟是哪个方法
实现运行时多态:继承、方法覆盖/重写(override)、父类引用指向子类对象
5、向上转型与向下转型
# 向上转型
- 当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。(也叫:隐式转型、自动转型);
- 格式:
父类类型 变量名 = new 子类类型();;
- 什么时候使用:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作,这时就可以使用向上转型
# 向下转型
- 一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的;
- 格式:
子类类型 变量名 = (子类类型) 父类类型的变量;
; - 什么时候使用:当要使用子类特有功能时,就需要使用向下转型;
- 向下转型的好处:可以使用子类特有功能;
- 但是弊端是需要面对具体的子类对象;
- 在向下转型时容易发生
ClassCastException
类型转换异常。在转换之前必须做类型判断
# instanceof 关键字
- 作用: 可以通过
instanceof
关键字来判断是否能够对象转化。也就是,一个引用型的变量,是不是这个类型的对象,提高向下转型的安全性; - 格式:
boolean b = 对象 instanceof 数据类型;
,返回true / false
注意:
null instanceof <类名>
结果永远是false