面向对象:
1.类和对象的关系
2.创建对象
构建对象的过程:
1.栈区声明一个引用
2.new关键字在堆区申请内存空间,将模板中的数据复制一份到当前的申请的内存空间里,jvm会给复制进来的属性分配默认值
数据类型 | 默认值 |
---|---|
整数 | 0 |
浮点类型 | 0.0 |
bolean | false |
引用数据类型 | null |
3.jvm检查我们在类里面声明变量时有没有进行初始化操作,如果有的话那么这个初始化的值将覆盖jvm最开始分配的值
4.调用构造器对其当前构建好的对象中的属性进行初始化操作,覆盖掉类声明的时候给的初始值
5.对象构建成功,将对象的内存地址返回给前面声明的引用
3.this关键字
1.在实例变量局部变量同名的情况下用来区分局部变量和实例变量(注意,属性、实例变量、成员变量指的是同一种对象)
2.在当前类的非静态方法中调用当前类的其他普通方法,对this调用方法出现的位置没有要求,this.方法名(参数)
3.在当前类的构造器中调用其他构造器,this必须放在第一行,this(参数)
this关键字和new关键字的区分:
出现的位置:
new关键字调用构建器时不需要考虑出现在什么方法,也不需要考虑出现在方法的什么位置
而this关键字在调用构建器时只能出现在构造器中,而且必须出现在构造器的第一句
是否能够构建对象而言:
使用this这种语法来调用构造器,并不会产生新的对象,只有new关键字才能创建出新的对象,构造器本身就是一个方法,只是它算一个特殊的方法,用this的这种语言,单纯只是调用了这个构造器中的代码
内存地址:
new关键字会生成一个新的内存地址
this不会生成新的内存地址
能读取到新增的属性
3.封装
属性的封装
方法的封装
隐藏代码的实现细节
对于调用者来讲,很多时候,这个代码实现的细节,我们是没有必要、也不需要知道,我们只要知道这个方法叫什么名字,怎么去调用,调用的时候需要传什么参数,返回的结果是什么样子,以及调用的过程中可能会抛出什么异常,每种异常代表了什么情况等信息就可以了。也有一些情况,是方法/接口的提供提供者也不愿意让我们知道它们的实现细节,例如这些都是有商业用途的,或者软件不开源的等情况。
统一用户的调用接口
假如有三个用户:
user vip admin
查看当前的页面信息:
三个用户查看的到的内容是不同的,所以需要三个不同的方法针对这个三种用户,返回不同的信息
user showInfo_user()
vip showInfo_vip()
admin showInfo_admin()
可以进行封装:
public String showInfo_all(){
//根据当前调用者角色身份,来确定主要执行的代码
if(role == 0){
//执行对应的代码
}
else if(role == 1){
//执行对应的代码
}
else if(role == 2){
//执行对应的代码
}
return ...;
}
提高系统的可维护性
从封装后的结果来看,对于调用者,需要调用的接口变少了,调用的方式也变简单,提了的开发的效率,同时对于这些接口的提供者,我们维护接口的数量变少了,以前在很多地方编写的相同的代码,都封装起来,在其他地方进行调用,这样也减少了很多的维护工作量。
4.方法的重载(java定义的一个方法)
在【同一个类】中方法【名字相同】但是【参数列表不同】的方法称为方法的重载
参数列表的不同:
参数的个数
参数的类型
参数的顺序(两个 不同种类类型的参数位置做交换)
5.子类
子类 extends (扩展)父类
父类:
子类:
6.继承
一旦继承的关系确立,子类可以自动从父类中获取一些方法或者是属性,像使用自己内部定义的方法一样使用从父类中继承和方法。
要求:
私有的方法不能继承
构造器不能继承,只能调用
静态的方法不能继承(静态方法修饰的是类)
方法的重写:发生在子类和父类【两个类】之间,子类要从父类中【继承】到一些方法,然后觉得方法不满足要求,在子类中定义和父类相同的方法,并做一些修改,这种现象叫做方法的重写
方法的重写:
1.final修饰的方法不能被重写
2.static修饰的方法,子类中可以定义跟父类中同名的static方法,但是这种现象不叫方法的重写,如果父类中有static修饰的方法,你们子类可以定义和父类同名的方法,也必须使用static修饰
3.private修饰的方法不能被重写,我们可以在子类中声明与父类同名的私有方法,但这不叫作重写
?4.父类中使用abstract修饰的方法捡回来可以被子类重写为abstract修饰的,也可以重写为非抽象的方,同时父类中具体的方法也可以被子类重写为abstract修饰的
重写成功的标志:如果一个方法重写成功,那么不管使用父类的引用指向子类的对象,还是子类的引用指向子类的对象,或者是不管在父类还是子类中,是使用子类的对象调用的一定是子类重写过后的方法
一个子类继承了父类,那么就可以继承父类中的属性和方法,但是在子类中是否可以【直接】使用这些属性和方法,需要看这些属性和方法在父类中原有的访问权限修饰符是什么。
控制类、属性、方法是否可以被访问的修饰符有:public protected default private例如: 父类中的属性和方法使用了public修饰,那么在子类中就【可以直接】使用 父类中的属性和方法使用了private修饰,那么在子类中就【不可以直接】使用 注意,父类中无论是public修饰的还是private修饰的属性和方法,都是会被子类继承的,只是在子类中能不能直接访问这些属性和方法,就和这些修饰符有关系了。
7.super关键字
1.区分父类的属性和父类的方法
2.调用父类的构造器
为什么要用super去调用父类的构造器?
要么使用this,要么使用super
?
一旦两个类发生继承关系,那么父类的构造器是不能被子类继承的,但是父类的构造器在构建子类的对象的过程中是一定要被调用的,因此在子类的构造器必须有至少一个构造器内部隐式或者显示调用父类的构造器,如果父类中提供了无参构造器,那么在子类的构造器中只要没添加this,jvm默认都会添加super去调用父类的无参构造器,但是如果父类没有提供无参构造器,那么需要我们自己在子类的构造器中使用super显示调用父类的构造器
this和super:
相同点: 都能调用属性 方法 构造器
不同点:
1.this调用属性和方法调用自己类中的 super调用的是父类中的
2.this调用的是当前类中自己的其他构造器 this(参数)第一行
super调用的是父类中的构造器 (参数)第一行
子类为什么要去继承父类的构造器?
父类的构造器一般用来初始化父类中继承的属性
子类的构造器一般用来初始化子类自己内部声明的属性
8.多态
1.一定是发生在具有继承或者是实现类中间,类A继承类B,有可能发生多态,A是接口B是接口的实现类也可以发生多态
2.父类的引用指向子类的对象,调用子类重写父类的方法,实现不同的效果
9.类型转换**
隐式数据类型转换:把较小的数据类型用较大的数据类型接收
基本数据类型(数值):byte ->short/char int long float double
引用数据类型(能发生隐式数据类型转换的一定是两个类,要么继承关系,要么是实现的关系):
父类的引用指向子类的对象,
显示数据类型转换:把较大的数据类型用较小的数据类型接收
byte <-short/char int long float double