Table of Contents
一、面向过程和面向对象
面向过程:主要针对过程(步骤)去解决问题
面向对象:主要解决对象(别人)去解决问题
举例一、
自身研发 亲力亲为 面向过程
三方组件 Spring全家桶 面向对象
举例二、
贵公司因为业务需要,委派您来招聘各项指标达标的合适人选,解决公司的业务,公司上级和您之间,公司上级便是在面向对象,您是在面向过程。然而在我们受招聘的人和您之间就是您在面向对象,我们在面向过程了。
自己的理解:在这个世界中,除亲力亲为之外的任何事情,在最终被解决的前提下,我认为都是面向对象和面向过程的结合。
注释:不可能有纯粹的面向对象,但可以有纯粹的面向过程,现实生活中一般都是面向过程和面向对象的结合。
二、对象与类
1、举例
按模子来制造物品,模子可以近似看成类,物品可以看成对象
为什么说是近似看成?
答:模子做出来的物品都是完全一模一样,类和对象之间还具有有限的多样性,类相比于模子更灵活,类主要是表示一类事物,模子是表示一个事物。
2、定义
类:具有相似特征和行为的一类事物的统称
对象:对象是由类所描述出来的具体的事物
我们如何去定义一个类呢?
主要定义其特征和行为
特征:变量
行为:函数
3、面向对象三大特点:封装 继承 多态
封装:循环 函数 类
继承:
多态:+ 重载
三、对象的创建流程
1、main函数进栈
2、执行new 类名();在堆内存中创建一个空间存储这个对象,并为这个空间随机分配一个地址
3、再在这个空间中开辟成员变量的空间,并对各个成员变量进行默认初始化
(1)基本数据类型:整型(0) 浮点型(0.0) 布尔型(false) 字符型('0')
注:字符0的ASCII码为48,字符数字转整型数字会用到。
(2)引用数据类型(null)
4、在进栈的函数中开辟一个变量空间存储的是匿名对象在堆内存中的地址。
四、private私有化关键字
1、对成员变量的影响:
private修饰成员变量时,此成员变量只能在类中被调用,不能允许外部访问
可以设置访问入口:在类中提供getter和setter方法分别对私有的成员变量进行访问和改值。
2、对成员方法的影响:
private修饰成员方法,该成员方法不能在外界被调用;一般用来修饰构造方法,在单例模式中使用,使外界不能随意创建对象,限制对象的产生个数。
3、对类的影响:只能修饰内部类,不能修饰外部类,且内部类中方法只能是static的,因此,内部类也要声明为静态的!
五、this关键字
this表示的是调用该函数的对象的地址
如何做区分? 区分哪个对象调用的本函数 每个函数下面都会有一个this只是不显示出来。
六、成员变量初始化
初始化总共有三种:默认初始化、显式初始化、针对性初始化
无论是引用数据类型还是基本数据类型的成员变量,刚被创建出来的时候都会进行默认初始化,
七、构造函数(构造器)
一个类中总有一个隐藏的默认无参、函数名和类名相同的函数,这个函数我们把它叫做构造函数。
权限修饰符 类名(参数列表){
return; //无返回值
}
对象创建流程(升级版):
1.在堆内存中开辟一个空间,分配地址
2.对成员变量进行默认初始化
3.相应的构造函数进栈,此时先进行显示初始化
4.接着在执行构造函数中的内容 针对性初始化
5.构造函数执行完毕弹栈
6.将对象的地址传给相应的变量
构造函数和成员函数有什么区别?
从下面四个方面讨论:
1、外界调用角度
构造函数:只能在创建对象时调用,对象创建完毕之后不能已创建的对象调用
成员函数:只能在对象创建之后调用,可以重复的
2、返回值
构造函数:不需要返回值
成员函数:可需可不需
3、权限修饰符
构造函数:可以用任意权限修饰符
成员函数:也可以用任意权限修饰符
4、内部调用
(1)构造函数能否调用成员函数?
可以
但是这个成员函数一般不会当做对象行为去看待
(2)构造函数能否调用构造函数?
可以
this(参数列表) 调用当前类中的其他构造函数
构造函数之间不能相互调用 无限递归
而且this(...)必须在第一句!防止值的覆盖
(3)成员函数能否调用成员函数?
可以
(4)成员函数能否调用构造函数?
不能 但是可以new
(构造函数可以和成员函数重名!)
如果一旦定义出其他的构造函数 则默认的无参构造函数不存在了!
所以建议一般把无参构造函数都写出来
八、成员变量和局部变量
成员变量:对象的特有属性
局部变量:函数中所创建的变量
1.存储位置
成员变量:存在于堆内存中对象的所属空间里
局部变量:存在于栈内存中函数的所属空间里
2.生命周期
成员变量:随着对象的创建而存在,随着对象销毁而消失
局部变量:随着函数的进栈而存在,随着函数弹栈而消失
3.初始化
成员变量:有默认初始化-显式初始化-针对性初始化
局部变量:必须初始化才能被调用
注:必须初始化才能被调用是不是说局部变量就没有默认初始化?
答:局部变量中不存在默认初始化。Int[] array;、int a;这些都没有默认初始化,但在成员变量中有默认初始化为null和0;需要注意的是我们的语句:new int[10];这个是个匿名对象数组,这是有默认初始化的。在java源码中进行初始化了。
4.作用域
成员变量:全局可用
局部变量:在其最近的一对{}里面
for(int i=0;i<n;i++){
}
九、静态变量和成员变量区别
1.存储位置
静态变量在静态方法区中类所属的空间里
成员变量在堆内存中对象的所属空间里
2.生命周期
静态变量随着类(.class文件)的加载而存在,随着程序的结束而结束
成员变量随着对象的创建而存在,随着对象的消亡而消失
3.调用方式
静态变量可以对象调用 类调用
成员变量只能对象调用
4.别名
静态变量属于类的 也叫类成员
成员变量属于对象的 也叫对象特有属性
十、Static、final关键字
Static修饰的成员变量叫做静态成员变量
Final修饰的成员变量中存储的地址不能变,详解如下:
从基本数据类型来看:
注:我想过能不能将常量池中0x111地址所对应的10这个值给改了,但这个应该是底层的东西了。问过很多技术大牛好像是不能改的。
结论:final修饰基本数据类型,相当于就把变量值给锁死了。
从引用数据类型来看:
final修饰引用数据类型和基本数据类型的区别:
虽然0x222不能变,但是数组可以使用角标修改里面的数据:,array[1]=5,只要还是原来这个数组就能行。但是扩容这些都是偷天换日,数组其实是改变了的,所以不行。
特殊的引用数据类型(String):
String这个引用数据类型,在java源码中就限制死了的,String只要一被创建出来,便不准改变其中的内容,String这个类的所有方法都是新创建了个String对象对其进行修改。如果加上final,那么String的内容从java源码被锁死,String的地址又被final限制死了,整个String就不准改变了。
重点:
有多少个对象就有多少份成员变量
成员函数的个数和对象的个数无关 始终一个
静态成员变量无论你有多少个对象,它都只有一个,所有对象都指向这个静态成员变量的地址空间。所以静态成员变量被定义为对象的共有的不变属性。所以一般static修饰的变量会加final关键字,final修饰的变量
十一、对象创建流程(终极版)
1.javac 编译 Main.java 生成两个字节码文件
Main.class Person.class
2.java 运行 Main.class
将Main.class和Person.class文件加载进JVM
具体加载进了那里?方法区
内存:
寄存器 :直接与CPU进行数据交互
本地方法区:主要临时存储OS的可执行代码
方法区:主要临池存储App的可执行代码
栈:函数栈 用于运行函数
堆:对象堆 主要存储对象数据
3.方法区中分为
静态方法区 主要存放 静态变量 静态函数
非静态方法区主要存放 构造函数 成员
4.java Main
让虚拟机在静态方法区中的Main所属空间里找主函数
5.将主函数加载进栈,开始运行
6.执行主函数中的第一句
Car car=new Car();
在堆内存中开辟空间并随机分配地址
在这个空间中,创建Car这个类中的所有成员变量,并给予默认初始化,
7.调用相应的构造函数,从非静态方法区中的相应的类空间里
读取并加载进栈
8.构造函数刚进栈 则进行成员变量的显式初始化
9.开始执行构造函数中的代码,针对性初始化
为了区分哪个对象调用的这个函数 this
10.构造函数执行完毕弹栈,将对象的地址赋予左边
11.在主函数中创建Person类型的p变量空间
空间里存的是该对象的地址
12.p对象调用speak()方法,则从非静态方法区中加载speak()的代码进栈
同样 this做区分
成员函数中打印变量 局部-堆-静态方法区 就近原则
13.在调用静态成员时,可以直接去静态方法区中找
Person.xxx Person是因为该区域中有多个类空间 我们得指定一个
同样 静态函数中 打印变量 局部->静态 与堆无关
重点:
1、静态函数有没有this?
答:静态函数,又称类方法,它不是对象特有的方法,他是所有对象的公共方法,大家都有这个行为,所以称之为公共方法。既然是公共方法,对于这个函数所有对象都是一样的,和对象无关,那么也就不需要用this去标记是那个对象调用了它,所以静态函数没有this。
2、针对性初始化和显示初始化的区别?
答:无论你成员变量是否具有显示初始化,成员变量都会经历默认初始化——》显示初始化——》针对性初始化;成员变量一般都不会给予显示初始化,有显示初始化的成员变量,一般都会被定义成为静态变量,所以决定成员变量的值是针对性初始化。决定静态变量的值是显示初始化。
3、为什么有显示初始化的成员变量,一般都会被定义成为静态变量?
答:成员变量一般都是一个对象特有属性,每个对象的属性值应该是不一样的,所以需要用户传参,针对性初始化对它进行量身定做,如果有显示初始化,那么该属性说明是各个对象共有的相同属性,所以要定义成静态变量,独立于对象之外的类属性。
4、静态变量有针对性初始化吗?
答:没有。针对性初始化是对象特有的,静态变量是属于类的属性,所以不会进行针对性初始化的。
5、静态变量的显示初始化和成员变量的显示初始化的时间区别?
答:静态变量的显示初始化是在赋值的时候进行的;成员变量的显示初始化是在构造函数刚进栈时进行的。