一、面向过程与面向对象
面向过程(POP)、面向对象(OOP)
面向过程:针对于要做的事情一步一步封装到一个方法中,但若是提出要修改不同的规格与事情就需要不断的重复更改方法中的过程及内容。其更强调的是功能行为,以函数为最小单位。
面向对象:适应性与扩展性强,可根据要做的事情抽象成一个个实体类,每个实体类都有对应其自己的方法,若是有公共特征的可以使用继承,方便调用、修改。以类为最小单位,考虑谁来做
加入新功能不会搞乱以前写好的代码。
数据与操作数据的方法摆在同一个类内。
可吃重复运用在别的程序中,并使该类具有足够的扩展性,正因为如此能够有如此之多的工具包。
所有java程序都定义在类中。
以对象来思考,对象可以是已知的事物,对象会执行的动作。对象已知的事物成为实例变量,执行动作为方法。
三个特性:封装、继承、多态
例子说明两者区别
例如:人要打开冰箱,抬起大象塞进冰箱,关闭冰箱
面向过程:直接一个方法具体完成功能行为
void func(){ ①人打开冰箱 ②抬起大象,塞进冰箱 ③关闭冰箱 }
面向对象:相关事进行抽象成一个个类,相应类执行其自己的事,最后进行相互调用
class 人{ 大象进冰箱(大象,冰箱){ 冰箱.打开; 大象.进入(冰箱); 冰箱.关闭; } } class 冰箱{ 打开冰箱(); 关闭冰箱(); } class 大象{ 进入(物体) }
二、类与对象
介绍类与对象
类不是对象,但是类可以创造多个对象(新的实例)。
创建对象时,对象会被存放到称为堆中的内存区域里。此区域是可回收的堆(Garbage-Collectible Heap),Java会根据对象的大小来分配内存空间,对象引用也只是个变量值。
那么对于内存空间如何释放呢?Java会主动帮你管理内存,当某个对象被JVM观察到不再被使用时,该对象会被标记为可回收的。若是内存开始不足,垃圾收集器会启动来清理垃圾,回收空间。
创建类与对象
一般来说先会创建类,类中包含相应的属性、构造器、方法。
有了类之后,我们就可以创建对象了(前提有对象构造器),不同的对象其属性都可以不相同(属性并非为static情况下)。
这里再次温习一下关于初始赋值问题:
类与一维数组中定义的基本类型与引用类型属性:自动赋初值(各个初始值见之前数组章节),引用类型属性默认为null。
方法中定义的基本类型与引用类型:不会自动赋初值,直接输出或使用会报空指针。
我们先创建一个Person类:包含几个私有属性以及几个公共方法
class Person{ private int age; private String name; private boolean isMale; public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } public void setMale(boolean male) { isMale = male; } }
此时类模板有了,我们就可以创建对象了,直接Person person = new Person();即可创建对象了。
类有构造器的情况下,才能够通过new来创建对象
创建一个类时会自动创建一个隐藏的空参构造器,如下:
//这里与上面Person类相关,这里只做演示,默认是隐藏存在的 public Person(){ }
对象创建过程:对象声明、创建、赋值,以上面对象为例子
声明一个引用变量=》Person person
创建对象,java虚拟机中分配堆空间给新建的Person对象=》new Person()
连接对象和引用,将内存地址值赋值给引用变量=》=
Person对象的内存解析:这里借用尚硅谷演示的图展示其在内存中的情况
说明:通过new创建的数组以及对象都是在堆中创建的,栈中存放变量名及指向的内存地址,大致与之前数组相同。
对象引用
摘自《head first java 2.0》,问题描述
问:引用变量多大?
答:不知道。除非你跟某个java虚拟机开发团队有交情,否则是不会知道引用是如何表示的。其内部有指针,但是你无法也不需要去存取。若是想要讨论内存分配问题,最需要关心的就是需要创建多少个对象和引用,以及对象的实际大小。
问:是否意味着所有的对象引用都具有相同的大小,而不管它实际上所引用的对象大小?
答:是的,对于java虚拟机来说,所有的引用大小都一样。但是不同的java虚拟机都会以不同的形式来表示引用,因此某个java虚拟机的引用大小可能会大于或小于另一个java虚拟机的引用。
问:是否可以对引用变量进行运算,就像c语言一样?
答:不行,Java不是C。
关于引用变量:引用变量可以被看做是遥控器,可以设定来控制不同的对象。一旦其引用变量被标记为final,就不能再赋值除了第一次引用之外的对象了。
对象在堆上的生与死:
当一个对象不与一个引用变量产生联系,相关时,能够作垃圾回收器(GC),会等待回收。
当一个引用变量为null时,表示它不再引用任何事物,但还是可以被指定引用其他对象的引用变量。
构造器
构造器:用来创建实例,或叫构造方法(constructor)的使用。
作用:用来创建对象及初始化信息。
构造器例子如下:
class person{ //显示定义空参构造器 public person() { } }
注意点:
创建一个类,会默认提供空参构造器,自己也可以显示定义一个空参构造器。
默认的空参构造器权限与本身类的权限相同。
也可以定义多参构造器,但是一旦定义多参构造器,系统将不会定义空参构造器,所以还应当重载一个无参数列表的构造器(空参构造器)。
开发时,操作数据库时,大多使用的是空参构造器,使用其中set方法进行赋值,需要注意一下。
JavaBean说明
JavaBean:是一种Java语言写成的可重用组件。
包含以下特征:
类是公共的
包含无参构造器
有属性,并且包含对应的set/get方法
满足上述特征及条件的就叫做JavaBean。
UML类图
类似如下:
上面框没有()的表示为属性,:后的表示返回类型。
下面框中若是有下划线的表示为构造器,没有的表示为方法,:后表示返回类型。
可以根据UML图来进行编写Java代码。
this关键字
this:表示当前对象或者当前正在创建的对象。
使用方式:
在类内可以调用属性及方法,例如:this.属性,this.方法
有参构造器中使用this();方式调用构造器。
this可以作为当前实例返回,也可将其传到方法参数中。
三、内存区域
java的内存区域见下图
堆(Heap):内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存空间。在Java虚拟机规范中的描述是:所有的对象实例以及数组都在堆上分配。
栈(Stack):指虚拟机用栈存储局部变量等,局部变量表中存放了编译器可知长度的各种基本数据类型(就是这些值直接在栈中存放)、对象引用(对象在堆内存放的首地址)。方法执行完之后自动释放。
方法区(Method Area):包含了常量池与静态域,用来存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
四、对象数组
对象数组中也只会保存引用,而不是对象本身。无论数组包含什么,它一定是对象!
一旦数组被声明出来,就只能装入所声明的类型,但是对于基本类型byte可以放到int数组中。—《head first java 2.0》 P59
对象数组:创建对象数组后,仅为数组开辟内存空间,其每个对象都没有都没有分配地址都为null,与二维数组不指定后面[]中数字相同(例如:int[][] ids = new int[5][]),没有给实际位置分配空间。
见下面例子:
class Person{ private int age; private String name; }
Person[] pers = new Person[2];,内存空间如下:
说明:只创建数组时是没有开辟内存空间的,我们需要进行额外开辟对象的内存空间才能对其中对象进行操作。例如:pers[0] = new Person();
对象数组的内存解析
这边直接使用尚硅谷课件中的一张图:还是比较明确的