Java 语言-6 面向对象编程
6.1 认识面向对象
- 面向过程 & 面向对象
- 面向过程的思想:步骤清晰简单;合适处理一些较为简单的问题
- 面向对象的思想:以分类的思维模式处理问题;合适处理复杂的问题,适合处理多人协助问题
- 对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。到了具体微观操作,我们仍需要面向过程的思路去处理问题
- 面向对象编程(Object Oriented Programming,OOP)
- 本质:以类的方式组织代码,以对象的组织(封装)数据
- 编程思想:抽象
- 三大特性:封装、继承、多态
- 设计思想的要点
- 认为客观世界由各种对象组成
- 程序的分析和设计都围绕着:有哪些对象类;每个类有哪些属性、方法;类之间的关系(继承、关联……);对象之间发送消息(调用方法)等进行
- 理解:
- 从认识论角度考虑是先有对象后有类
- 从代码运行角度考虑是先有类后有对象
6.2 面向对象三大特征
6.2.1 封装
-
封装:是类对象的状态和方法,就是将字段和方法封装在一个类中
-
封装:主要是模块化和信息隐藏两个方面
- 模块化:将属性和行为封装在类中,程序定义多个类
- 信息隐蔽:将类的细节部分隐藏起来,用户只通过保护的接口访问某个类
-
封装可用于完成程序设计要追求的“高内聚,低耦合”
- 高内聚:类的内部操作细节,不允许外部干涉
- 低耦合:仅暴露少量方法给外部
-
方法:使用 private 关键字对类或者成员进行封装,再使用 setXXX() 和 getXXX() 方法对类的属性进行存取,分别称为 setter 和 getter
-
示例:
class Person{ private int age; public void setAge(int age){ if(age>0 && age<200)this.age = age; } pubilc int getAge(){ return age; } } -
简单记忆:属性私有,get/set
-
-
实现快速封装快捷键(IDEA):
Alt+Insert -
意义:
- 更好的封装和隐藏,使外部类不能随意存取修改,提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 增加系统的可维护性
6.2.2 继承
-
继承:指父类和子类之间共享的数据和方法
- 子类(subclass),父类或超类(superclass)
- 父类包括所有直接或间接被继承的类
- 除此之外类和类之间还有依赖、组合、聚合等关系
- 子类(subclass),父类或超类(superclass)
-
Java 中类只有单继承,没有多继承
- 接口可以多继承
-
意义:
- 子类可以继承父类的状态和行为
- 可以修改父类的状态或者重载父类的行为
- 可以添加新的状态和行为
-
作用
- 更好进行抽象和分类
- 增强代码的复用率,提高开发效率和可维护性
-
Java 实现继承是通过 extends 关键字,意思是“扩展”
-
例如:
public class Student extends Person{ …… } -
如果没有 extends 子句,则默认为继承于 java.lang.Object
- 所有的类都是直接或者间接继承 Object 类
-
-
继承关系:相当于 is 关系
-
字段
- 字段的继承:子类可以继承父类的所有字段
- 字段的隐藏:子类重新定义一个从父类那里继承来的变量完全相同的变量,称为域的隐藏
- 在实际应用中较少
- 字段的添加:在定义子类时,加上新的域变量
- 在实际应用中较多
-
方法
- 方法的继承:父类非私有方法也可以被子类自动继承
- 方法的覆盖:也称为方法重写,子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖
- 方法的添加:子类可以新加一些方法
- 方法重载是特殊的方法的添加
-
判断两个对象之间的关系使用 instanceof 关键字
-
如果有继承关系返回 True,否则返回 False
-
示例:
object instanceof Student
-
-
查看继承关系快捷键(IDEA):
ctrl+H -
在子类访问父类属性和方法使用 super 关键字
-
例如:调用父类 name 属性
super.name -
注意点:
- super 调用父类方法,必须位于构造方法第一行
- super 只能出现在子类的方法或者构造方法中
- super 和 this 不能同时调用构造方法
-
与 this 对比
super this 代表对象 代表父类对象的应用 代表调用者这个对象 前提 只能在继承条件下使用 没有显式继承条件也可以使用 构造方法 父类的构造 本类的构造
-
-
方法重写
- 是重写方法,与属性无关
- 在 JDK 1.5 后可以使用 @Override 标注表示进行了方法重写
- 重写后父类调用该方法,是实现的子类的方法,而不是父类的方法
- 重写快捷键(IDEA):
Alt+Insert - 要求:
- 需要有继承关系,子类重写父类的方法
- 方法名、参数列表必须相同,方法体不同
- 修饰符范围:可以扩大,不能缩写
- \(pubilc>protected>default>private\)
- 抛出异常范围:可以缩小,不能扩大
- \(ClassNotFoundException<Exception\)
- 用途:
- 父类的功能子类不一定需要或不一定满足
6.2.3 多态
- 多态是指不同对象收到同一个消息(调用方法)可产生不同的效果,其实现的细节则由对象自行决定
- 多态可实现动态编译,增强可扩展性
- 实现要求:
- 父类与子类有继承关系
- 方法需要重写
- 有些方法不能重写:static、final、private
- 父类引用指向子类对象
- 注意点:
- 多态是方法的多态,属性没有多态
- 父类与子类有关系
- 如果没有关系会发生类型转换异常:\(ClassCastException\)
6.3 super 的使用
-
使用 super 访问父类的变量和方法
-
也可以使用 this 来访问父类的域和方法
-
例如:假设有一个类的父类有 age() 方法 ,在该类中使用 age()
void testThisSuper(){ int a; a = age; a = this.age; a = super,age; }这三种访问结果均相同
-
为什么有了 this 还需要使用 super
- 有些时候为了明确地指明父类的变量和方法
- 访问被子类所隐藏的同名变量
- 当覆盖父类方法的同时,又需要调用父类的方法
-
-
使用父类的构造方法
-
构造方法与类名相同,是不能继承的
- 不能说父类(例如:Person)有一个构造方法(Person())子类(例如:Student)也自动有一个构造方法(Student())
-
但是可以通过 super 来调用父类的构造方法
-
例如:父类 Person 的构造方法 Person(String name, int age),子类调用
public Student(String name, int age,String school) { super(name,age); this.shool = school; } }使用时,super() 语句必须放在第一句
-
6.4 类型转化
-
这里是指父类对象与子类对象的转化,与基本数据类型的转换类似
-
子类对象可以被视为其父类的一个对象
- 例如:一个 Student 对象可以被视为一个 Person 的对象
-
父类对象不能视为子类对象
-
-
“低”转“高”自动转换:如果一个方法的形式参数定义的是 父类对象,那么调用这个方法时,可以使用子类对象作为实际参数
-
“低”指父类级别,“高”指子类级别
-
例如:Person 是 Student 的父类
Person student = new Student();
-
-
“高”转“低”强制转换:如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以使用强制类型转换成为子类的引用
-
转换方法与基本类型类型转换类似:在对象前添加
() -
例如:
Person student = new Student(); Stuednt obj = (Student) sutdent;- 可能会丢失一些本来的方法
-
存在意义:方便方法调用,减少重复代码,简洁
-
-
类型转换条件
- 父类引用指向子类对象
- 把子类转换为父类,向上转型,自动转换
- 把父类转化为子类,向下转型,强制转换
6.5 接口
-
接口就是规范,定义的是一组规则;
- 本质就是契约;OO 的精髓,是对对象的抽象最能体现的一点
- 也是一种引用类型
-
接口 & 普通类 & 抽象类
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有
- 接口:只有规范
-
声明接口使用 interface 关键字,声明之后的方法都自动是 public abstract
-
定义的时候 public、abstract 两个关键字是可以省略的
-
声明类的关键字是 class
-
例如:接口的简单操作
public interface UserService{ void add(String name); void delete(String name); void update(String name); void query(String name); }在接口中很多东西是看不见的,所以可以直接用返回值类型、方法名以及参数列表即可定义
-
-
使用 implements 实现接口。实现接口,就必须要实现接口全部的方法
-
实现类一般命名以 Impl 结尾
-
例如:实现接口 UserService
pubilc class UserServiceLmpl implements UserService{ …… } -
接口可以多继承,从而侧面实现多继承
-
-
要点:
- 约束
- 可以实现不相关类的相同行为,而,不需要考虑这些类之间的层次关系。一定意义上实现多继承
- 接口不能被实例化,接口中没有构造方法
- 可以实现多个接口
- 实现接口必须重写全部方法
-
接口中的常量
-
接口中主要是抽象方法,但是也存在常量
-
格式:
type NAME = value;type:可以为任意类型
NAME:为常量名,通常为大写
value:为常量值
-
在接口定义的常量可以被实现该接口的多个类共享
- 与 C 中 #define 和 C++ 中的 const 定义的常量相同
-
接口中定义的常量具有 public、static、final 属性,通常省略
-
-
在 java 8 中的接口
- 在Java 8 中新添加了 static 方法
- 具有实现体的方法(default 方法)
- 默认方法的用途:提供了一个默认实现。子类在 implements 可以不用重新写实现方法

浙公网安备 33010602011771号