面向对象的重点学习什么?
- 学习获取已有对象并使用
- 学习如何自己设计对象并使用 --> 面向对象的语法
设计对象并使用
类和对象
- 类(设计图):是对象共同特征的描述
- 对象:是真实存在的具体东西
在Java中,必须先设计类,才能获得对象
如何定义类
如何得到类的对象
如何使用对象
- 访问属性:对象名.成员变量
- 访问行为:对象名.方法名(...)
类的几个补充注意事项
- 用来描述一类事物的类,专业叫做:Javabean类。在Javabean类中,是不写main方法的。
- 在以前,编写main方法的类,叫做测试类。我们可以在测试类中创建javabean类的对象并进行赋值调用
- 在Javabean类中,属性由成员变量的形式来体现,行为由成员方法(不加static)的形式来体现。
- 类名首字母建议大写,需要见名知意,驼峰形式
- 一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。实际开发中建议还是一个文件一个class类。
- 成员变量的完整定义格式是:修饰符 数据类型 变量名称 = 初始化值; 一般无需指定初始化值,存在默认值
封装
原则
对象代表什么,就得封装对应的数据,并提供数据对应的行为
private关键字
- 是一个权限修饰符
- 可以修饰成员
- 被private修饰的成员只能在本类中才能访问
- 针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作,如“setXxx”,“getXxx”方法
- “setXxx”方法,用于给成员变量赋值,方法用public修饰
- “getXxx”方法,用于获取成员变量的值,方法用public修饰
成员变量和局部变量
成员变量:定义在方法的外面,类的里面
局部变量:定义在方法的里面
就近原则
private int age; public void method() { int age = 10; System.out.println(age); }
第一个age是成员变量,第二个age是局部变量,由于就近原则,输出的age是第二个age
this关键字
作用
区别成员变量和局部变量
this的本质和内存图
本质:所在方法 调用者 的地址值
构造方法
构造方法也叫构造器、构造函数
作用
在创建对象的时候,虚拟机自动调用构造方法,作用是给成员变量进行赋初始化的
格式
特点
- 方法名与类名相同,大小写也要一致
- 没有返回值类型,连void也没有
- 没有具体的返回值(不能由return带回结果数据)
执行时机
- 创建对象时由虚拟机调用,不能手动调用构造方法
- 没创建一次对象,就会调用一次构造方法
分类
- 无参构造方法:初始化对象时,成员变量的数据均采用默认值
- 有参构造方法:在初始化对象时,同时可以为对象进行赋值
构造方法的注意事项
- 构造方法的定义
- 如果没有定义构造方法,系统将给出一个默认的无参构造方法
- 如果定义了构造方法,系统将不再提供默认的构造方法
- 构造方法的重载
- 带参构造方法和无参构造方法的,两者方法名相同,但是参数不同,这叫做构造方法的重载
- 推荐的使用方式
- 无论是否使用,都手动书写无参构造方法,和带全部参数的构造方法
标准JavaBean
1.类名需要见名知意
2.成员变量使用private修饰
3.提供至少两个构造方法
无参构造方法
带全部参数的构造方法
4.成员方法
提供一个成员变量对应的setXxx() / getXxx()
如果还有其他行为,也需要写上
细节
- 快捷键alt+=,选择getter and setter快速生成get和set方法
- 右击,选择ptg to JavaBean快速生成JavaBean
对象内存图
简介
每一款软件都会占用一块内存,java也不例外,JVM将占用的内存分为五个部分,如下图所示
JDK7以前,JVM将内存分为五个部分,堆和方法区是连在一起的,在真实的物理空间中也是一片连续的空间。JDK8以后,取消方法区,新增元空间,把原来方法区的多种功能进行拆分,有的功能放到了堆中,有的功能放到了元空间中。此时,加载字节码文件的功能属于元空间了。为了方便理解加载字节码文件后代码如何运行,暂且还是把元空间叫做方法区。
总体运作
当运行一个类的时候,这个类的字节码文件就会加载到方法区中临时存储
当类中的方法被调用的时候,方法进栈执行,执行之后就要出战,注意变量也是在这个区域里面
new出来的东西放入堆中,并且在这块内存中开辟空间会产生地址值
一个对象的内存图
如 Student s = new Student();
- 加载字节码文件,即将Student类的字节码文件加载入内存
- 声明局部变量,对等号左边的s进行声明
- 在堆内存中开辟一个空间,即等号右边,因为有new关键字
- 默认初始化
- 显示初始化
- 构造方法初始化
- 将堆内存中的地址值复制给左边的局部变量
例子
1.首先,程序是从main方法开始执行的,所以要把TestStudent类的字节码文件加载到方法区中,在这里将main()方法进行临时存储。
2.然后虚拟机会自动地进入程序的主入口,调用main()方法,于是main()方法被加载到栈里面。
3.开始创建Student对象,执行上面Student s = new Student()需要的七个步骤,第一步,将Student.class加载到方法区中,在这个里面有Student类的所有信息,即成员变量和成员方法。第二步,声明局部变量,在main方法中声明s。第三步,在堆内存中开辟一个空间,而堆里面的空间都是有地址值的,假设地址值是001,这个空间里面就会把Student类里面所有的成员变量拷贝一份放进去,除此之外还存饭成员方法的地址,是为了以后用对象调用方法的时候能找到对应的方法
,其实堆里面地址值为001的空间就是我们所说的对象。第四步,先默认初始化,不同类型的数据有不同的默认值。第五步,如果说在定义成员变量的时候是直接给值的,比如
,那么就要用显式初始化的值代替默认值。第六步,如果使用了带参的构造方法,则会用带参的构造方法给成员变量赋值,代替显式初始化。第七步,将堆内存中的地址值复制给左边的局部变量,即将001赋值给s。到目前为止,一个对象才刚刚创建完毕。
4.接着执行输出语句输出s.name + "..." + s.age,表示s代表的地址值001里面的name和age。
5.接着给对象的成员变量赋值,也是通过s,即001找到堆中地址值为001的空间,把值赋值给此空间中的name和age。
6.最后调用方法s.study(),也是通过s即001到堆中找到对应的空间,而这个空间会有成员方法的地址,再通过成员方法的地址找到成员方法,于是把方法加载进栈,并且执行。方法执行之后,就会从栈中出去,而main方法此时也执行完毕,所以main方法也出去,此时没有变量指向地址值为001的堆对象,所有被释放。
两个对象的内存图
和一个对象的内存图类似
两(多)个引用指向同一个对象
就是两(多)个变量指向同一个堆空间
成员变量和局部变量
成员变量:类中方法外的变量
局部变量:方法中的变量