目录
面向对象
面向过程(执行者) 面向对象(指挥者)
例如:你把大象装入冰箱中
面向过程:
打开冰箱门
存储大象
关闭冰箱门
你是一系列动作的执行者。
面向对象:
先把冰箱看作一个对象
冰箱被打开
冰箱存储大象
冰箱被关闭
你是指挥者,让别的对象,帮助你完成具体功能。
面向对象三种特性:封装性、继承性和多态性。
封装:
私有化属性,提供公共方法获取以及设置属性值,不允许外界随意访问。
继承:
主要涉及三部分(成员变量、成员方法、构造函数)
成员变量可直接调用,但重名子类覆盖父类
成员方法,可直接调用,也可覆盖重写父类方法,但必须保证该方法与父类的方法一模一样,只有函数主体不同
构造函数使用super关键字调用
this与super
this:代表当前对象,用于在方法中访问对象的成员(成员变量、成员方法和构造函数)
注意:
1.只能在构造方法中使用this调用其他构造方法,不能在成员方法中使用
2.在构造方法中,使用this调用构造方法的语句必须位于第一行,且只能出现一次
3.不能在一个类的两个构造方法中使用this互相调用
super: 代表父类对象,用于在方法中访问父类对象的成员(成员变量、成员方法和构造函数)
注意:
1.子类所有的构造函数默认第一行都有一条隐式的语句super();
2.通过super调用子类构造方法的语句必须位于子类构造方法中的第一行,并且只能出现一次。
总结:
- this和super关键字使用方法基本相同
- this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
- this和super不能同时出现在一个构造函数里。因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
扩展:
子类为什么一定要访问父类中的构造函数:
因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类在对象初始化时,要先访问父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句来指定。
重载和重写区别
重载:在同一个类中,同名函数参数列表不同,返回类型可以相同也可以不同。即为重载。
重写:在子类对父类关系下,函数一模一样,包括返回值类型,参数列表,只有函数主体(内容)进行重新编写,即为重写。
总结:方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
扩展:方法的递归是指在一个方法的内部调用自身的过程。为避免死循环递归必须也要有结束条件。
final
最终,修饰符
- 可以修饰类、函数和变量。
- 被final修饰的类不可以被继承,不可以被子类重写功能。
- 被final修饰的方法不可以被重写。
- 被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,也可以修饰局部变量。常量书写规范:所有字母大写,如果由多个单词组成,单词间通过_连接。
- 内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
抽象
应用:当多个类中出现相同功能,但是功能主体不同,这时,可以进行向上抽取,只抽取函数定义,而不抽取函数主体。
抽象(abstract):看不懂,所不能确定的。
特点
- 抽象方法一定在抽象类中,但抽象类中不一定全是抽象方法,抽象类中也可以没有抽象方法,让该类不能建立实例化对象。
- 抽象方法和抽象类都必须被abstract关键字修饰。
- 抽象类不能被实例化,即抽象类不能用new创建对象,因为调用抽象方法没意义,抽象方法没有方法体。
- 抽象类中的抽象方法要被使用,必须由子类重写所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
模板方法:
在定义功能时,功能的一部分是确定且不可更改(public final)的,但是有一部分是不确定(abstract),而确定且不可更改(public final)的部分在使用不确定(abstract)的部分,那么这时就将不确定的部分暴露出去(public abstract),有该类的子类去完成。
接口
class用于定义类
interface用于定义接口
初步理解:接口是一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
接口定义格式特点:常量、抽象方法
常量:public static final
抽象方法:public abstract
注意:
- 接口中的成员都是public的。
- 接口是不可以创建对象的,因为有抽象方法。
- 接口需要被子类实现,子类对接口中的抽象方法全部覆盖(重写)后,子类才可以实例化,否则子类是一个抽象类(继承)。
类、接口关系
类是单继承,多实现,接口与接口还可以实现多继承。
类与接口之间是实现(implements)关系,而且类可以继承一个类的同时实现多个接口
接口与接口之间可以有继承关系
继承是is a,所属关系;接口是like a,扩展关系。
多态:
可以理解为事物存在多种体现形态。
体现形式
父类的引用指向自己的子类对象。
详解:使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。
前提条件
类与类之间要存在一定的关系:要么继承(extends),要么实现(implements),通常还有一个前提,类中的成员(变量、函数)存在覆盖或重写。
好处
多态的出现大大的提高程序的扩展性和可维护性。
弊端
只能使用父类的引用访问父类中的成员(变量、函数),即所有子类所共有的成员属性,每个子类所独有的成员属性不能被父类的引用所访问。
向上转型/向下转型
Animal a=new Cat(); // 类型提升,向上转型
a.eat(); // 父类的引用访问父类中的成员函数,所有子类所共有的eat()方法
Cat c=(Cat)a; // 强制将父类的引用,转成子类类型,向下转型
a.catchMouse(); // 调用子类所独有的catchMouse()方法
父类引用指向自己子类对象时,该引用可以被提升(向上转型),也可以被强制转换(向下转型)
多态自始至终都是子类对象在做着变化
多态中成员特点
成员函数
在编译时期:参阅引用型变量所属的类中是否有被调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
总结:成员函数在多态调用时,编译看左边,运行看右边。
成员变量、静态成员函数
无论编译和运行,都参考左边(引用型变量所属的类)。
istanceof
判断一个对象是否为某个类(或接口)的实例(或者子类实例)。