概念
- 面向对象的三大特征:
- 封装(Encapsulation)
- 继承(Inheritance)
- 多态(Polymorphism)
- 面向对象(Object Oriented)是一个编程思想:将事件看成事件(过程)的集合还是物体(对象)的集合
- 类是对象的抽象
- 对象是类的实例
- 对象拥有两类内容:
- 成员变量:属性(Property, Member Variable, Field)
- 成员函数(方法):功能(Member Function, Method)
- 对象的引用性质:Java中的对象名只是一个引用(指针),或者是一个遥控器,并不代表其实际占据内存,只有通过"."号才能访问到其真实内存中的数据
成员变量和成员函数
成员函数
- 目的:复用代码
参数传递方式:
- 简单数据类型采用值传递
- primitive类型
- 引用数据类型采用引用传递
- 对象的引用,数组
函数重载(Overload)
- 允许多个函数名字相同,但是要满足要求
- 参数个数不同
- 个数相同,类型不同
- 个数相同,类型相同,但是不同类型的参数出现的顺序不同
- 函数的返回值不能作为重载的条件
- 函数重载也叫静态多态(Static Polymorphism)
构造函数(Constructor)
- 构造函数也是一种函数,为了强制对象初始化,但必须满足:
- 函数名与类相同
- 不含返回类型(并不是void)
- 特点:
- 对象实例化时自动调用一次
- 可以被重载
- 如果一个类没有定义任何构造函数,系统自动为其分配一个空的,不带参数的默认构造函数,如果定义了构造函数,默认构造函数自动失效(不会自动创建)
析构函数(Destructor)
- 对象结束其生命周期时或者该对象没有被引用,系统会执行析构函数
- 在java中,对象的内存在哪个时刻回收,取决于垃圾回收器何时运行
静态变量和静态函数
静态变量
- 默认情况下,各个成员都有自己独有的成员变量,占据不同内存。
- 而静态变量是该类所有对象公用的变量
- 访问方式:“对象名.变量名”,“类名.变量名”(推荐)
静态函数
- 静态函数只能访问静态变量,不能访问类中的普通成员变量。
- 建议用“类名.函数名”访问。
- 作用:一般情况下可以用来执行一些不隶属于任何一个特定对象的公共的工作。
封装(Encapsulation)
- 隐藏对象的属性和实现细节,仅对外公开接口
最大层面的封装:包
- 用包来管理类
- 如何把类放入包中
在文件头声明类所在的包:package 包名;- Java中,包名一般名词,首字母小写;
- 如果包中还含有包,用.号隔开
- 如何使用包中的类
- 同一个包中的类直接使用
- 不同包中的类不能直接使用,需以下操作:
- import 另一个包中的类
- import 类路径;
- import 包路径.*; 表示导入包中所有类(不含子包中的类)
- 被使用的类是一个public类
- public类对包外可见,非public类只能在包内可见;public-类的类名必须与所在文件名相同
- 一个文件中,最多只能有一个public类
- import 另一个包中的类
细节层面的封装:访问区分符
-
有些成员不适合其他类直接调用,这不安全。用访问区分符来管理成员的访问权限
-
在成员定义前面加上访问区分符:public,protected,default,private
-
访问权限如下:
访问权限 本类 同包类 外包子类 外包类 public √ √ √ √ protected √ √ √ × default √ √ × × private √ × × × -
以上访问区分符适合成员变量和函数
-
default是一种包访问,外包不能访问
-
一般情况下,成员变量定义为私有(private),成员函数定义为公有(public),如果涉及到继承,可以将成员定义为保护型
-
如果需要读取成员变量或者修改成员变量怎么做:
- setXXX函数和getXXX函数
- 也叫做setter和getter函数
继承(Inheritance)
概念
- 原因:通过继承,降低代码量,提高可维护性;定义共同协议
- 实现方式:extends关键字
- 性质:
- 不允许多重继承,一个类只能extends一次
- 所有的成员都可以被继承,但是要考虑访问区分符:
- 父类的private成员不能被继承
- 父类的default成员,不能被包外子类继承
- 成员变量可以被继承,作为子类的成员变量直接使用(属性)
- 成员函数可以被继承,作为子类的成员函数直接使用(功能)
- 本质:实例化子类对象时,系统会首先实例化父类对象
- 如果父类没有默认构造函数,子类必须用super()显式调用(必须写在第一行)
- 调用本类的其他构造函数this()也必须写在第一行,且不能与super()同时使用,因为this()中也会调用super(),使父类对象构造的两次
成员的覆盖(Override)
-
子类中重定义父类的成员,方法(参数一致,返回类型兼容)
-
覆盖是表现多态特性的具体做法
-
子类对象调用成员时,自动调用子类成员,父类成员不被调用。一定要调用父类成员,可以用super关键字。
-
super和this是相对的两个关键词,一个指代父类;一个指代自己
使用 执行 super. 调用父类的成员 super(参数列表) 调用父类构造函数 this. 调用本类中成员 this(参数列表) 调用本类中另一个构造函数 -
覆盖不允许缩小访问权限
-
Java中有一个类:Object类,是所有成员的父类
- 常见方法:equals(Object obj),toString()
多态(Polymorphism)
概念
- 多种形态:某个东西,在不同情况下呈现出不同形态
- 动态多态的理论基础是:父类引用可以指向子类对象。
- 当父类引用调用被覆盖的成员时,调用的是子类成员,从子类向上找
- 作用:
- 函数形参为父类类型,实参为子类对象
- 函数返回类型是父类类型,函数中实际返回子类对象
父类和子类的类型转换
- 子类转化为父类
- 可以直接赋值
- 父类转化为父类
- 严格来说,无法转换
- 特殊情况:该父类原本是子类的对象,使用强制类型转换
- “对象名 instanceof 类名” 可以判断对象类型
抽象(abstract)
- 抽象函数:将函数体去掉,定义为抽象函数
- 特点:必须在子类中被重写,否则报错,除非子类也是抽象类
- 含有抽象函数的类叫抽象类,必须用abstract修饰
- 特点:
- 抽象类必须用abstract修饰,抽象类不能被实例化,只能被继承
- 抽象类中含有抽象函数(包括继承的,也可以不含有),也可以含有普通函数(便于子类调用)
- 抽象函数必须在子类中被重写(注意权限不能缩小),否则报错,除非子类也是抽象类
- 抽象类中不一定都是抽象函数,但是含抽象函数的类一定是抽象类
- 抽象类不能被实例化,但是它有构造函数(因为子类中会使用super()调用父类构造函数)
接口(interface)
- 特点:
- 全部是public抽象函数,默认public,abstract(可省略)
- 因此实现接口的类中重写方法必须是public,因为权限不能缩小
- 接口中定义的“变量”只能是静态public常量,系统默认使用public,static,final修饰,可以省略
- 一个类继承抽象类–>实现(implements)接口
- 一个类继承一个父类同时实现多个接口
- 全部是public抽象函数,默认public,abstract(可省略)
抽象类和接口的区别
参数 | 抽象类 | 接口 |
---|---|---|
方法 | 可以有正常方法 | 只有抽象方法 |
实现 | extends | implements |
构造 | 可以有 | 不能有 |
正常类 | 只有不能实例化 | 完全不同类型 |
修饰符 | public、protected和default | 默认修饰符是public,不能使用其他 |
main | 可以有main且可以运行 | 不能有 |
- 接口可以extends接口,但不能implements接口,不能extends类
- 抽象类可以implements接口,也可以extends实体类(这个类必须有明确的构造函数),因为抽象类也可以有实体函数
final关键字
- 修饰类:不能被继承
- 修饰函数:不能被重写
- 修饰成员变量:不能被改变(哪怕是同一个值),用来定义常量