Java 学习笔记 05:面向对象
Java 学习笔记 05:面向对象
1 概述
1.1 面向过程&面向对象
面向过程思想:
步骤清晰简单,第一步做什么,第二步做什么……
面对过程适合处理一些较为简单的问题。
面向对象思想
物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
面向对象适合处理复杂的问题,适合处理需要多人协作的问题。
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对现象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
1.2 什么是面向对象
- 面向对象编程(Object-Oriented Programming , OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的组织封装数据。
- 抽象
- 三大特性:
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
2 “方法”回顾
- 方法的定义
- 修饰符
- 返回类型
- break和return的区别
- 方法名
- 参数列表
- 异常抛出
- 方法的调用
- 静态方法
- 非静态方法
- 形参和实参
- 值传递和引用传递
- this关键字
3 类与对象的关系
类是一种抽象的数据类型,它是对某一类事物整体描述、定义,但是并不能代表某一个具体的事物
对象是抽象概念的具体实例
1 | package com.oop.demo02 |
4 构造器详解
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
类中的构造器,也称为构造方法,是再进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
示例代码:
1 | package com.oop.demo02; |
5 封装
- 该露的露,该藏的藏
我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉。低耦合:仅暴露少量的方法给外部使用。
- 封装(数据的隐藏)
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 记住:属性私有,get/set
示例代码:
1 | public class Student { |
6 继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是“扩展”。子类是父类的扩展。
JAVA中类只有单继承,没有多继承。
继承是类和类之间的一种关系。除此之外,类和类之间的关系还有以来,组合,聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
子类和父类之间,从意义上讲应该具有“is a”的关系。
- object类
- super
- 方法重写
示例代码:
1 | public class Person { |
- 子类拥有父类的全部 public 方法。
- 在 Java 中,所有的类都默认继承 Object 类。
- super:父类的上下文,子类通过super访问父类的属性以及方法,private 的属性及方法无法通过 super 访问。
- 声明一个对象,先调用父类构造器,再调用子类构造器,显式地调用父类的构造器必须放在子类的第一行。
方法的重写
- 重写都是方法的重写,子类重写父类的方法。
- 方法名必须相同,参数列表必须相同,方法体不同(必须是同一个方法)。
- 静态方法和非静态方法区别很大,静态方法与引用的类型有关,重写只跟非静态方法有关。
- 修饰符:范围可以扩大(public > protected > default > private)
- 抛出的异常:范围可以被缩小,但不能扩大
为何需要重写?
父类的功能,子类不一定需要,或者不一定满足。# 7 多态
7.1 多态
多态,即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的 ,但可以指向对象的引用的类型有很多。
多态存在的条件:
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
注意:多态是方法的多态,属性没有多态性
一个对象的实际类型是确定的
1 | new Person(); |
一个对象可以指向的引用类型是不确定的
1 | Student S1 = new Student(); |
对象能执行哪些方法,主要看引用的类型,和创建对象的构造函数关系不大。
例如,S1能调用的方法都是自己的或继承父类的,S2不能直接调用Student中特有的方法,但若调用子类中重写了的父类方法,则执行子类的方法。
若使S2调用子类独有的方法:
1 | ((Student)S2).eat(); |
注意:
- static属于类,不属于实例
- final是常量
- private方法不能被重写
7.2 instanceof关键字
判断两个类之间是否存在父子关系
1 | Object object = new Student(); |
7.3 类型转换
- 父类引用指向子类的对象。
- 把子类转换为父类,向上转型。
- 把父类转换为子类,向下转型:强制转换。
- 方便方法的调用,减少重复的代码。
8 static 关键字
1 | //静态导入包 |
9 抽象类
- abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法,如果修饰类,那么该类就是抽象类。
- 抽象类中可以没有抽象方法,但是由抽象方法的类一定要声明为抽象类,抽象类中可以写普通方法。
- 抽象类不能使用new关键字来传播关键对象,它是用来让子类继承的。
- 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
- 抽象类没有构造器(大概)
示例代码
1 | //抽象类 |
10 接口
接口只有规范,自己无法写方法。
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。
- 接口的本质是契约。
- OOP的精髓,是对对象的抽象,最能体现这一点的就是接口。
接口声明的关键字是interface
1 | public interface UserService { |
接口的作用:
- 约束
- 定义一些方法,让不同的人实现。
- public abstract
- public static final
- 接口不能被实例化。
- implements可以实现多个接口。
- 必须要重写接口中的方法。
11 内部类
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
示例代码
1 | public class Outer { |
内部类可以访问外部类的一些私有属性。