认识面向对象
文章目录
面向对象介绍:
- 面向:拿、找。
- 对象:能干活的东西。
- 面向对象编程:拿东西过来干对应的事情。
设计对象并使用
类和对象
- 类(设计图):是对象共同特征的描述。
- 对象:是真实存在的具体东西。
在Java中,必须先设计类,才能获取对象。
类的几个补充注意事项
定义类的注意事项
-
用来描述一类事物的类,专业叫做:Javabean类。
在Javabean类中,是不写main方法的。
-
在以前,编写main方法的类,叫做测试类。
我们可以在测试类中创建Javabean类的对象并进行赋值调用。
-
类名首字母建议大写,需要见名知意,驼峰命名。
-
一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。
实际开发中建议还是一个文件定义一个class类。
-
成员变量的完整定义格式是:
修饰符 数据类型 变量名称 = 初始化值;一般无需指定初始化值,存在默认值。
封装(面向对象三大特征之一)
- 告诉我们,如何正确设计对象的属性和方法。
- 对象代表什么,就得封装对应的数据,并提供数据对应的行为。
private关键字
- 是一个权限修饰符。
- 可以修饰成员(成员变量和成员方法)。
- 被private修饰的成员只能在本类中才能访问。
小结
提供“setXxx(参数)”方法,用于给成员变量赋值,方法用public修饰。
提供“getXxx(参数)”方法,用于获取成员变量的值,方法用public修饰。
this关键字
成员变量和局部变量
**成员变量:**类里面,方法外面的变量。
局部变量:方法里面的变量。
就近原则
谁离我近,我就用谁。
public class people{
//属性,成员变量
private int age;
public void menthod(){
//局部变量
int age = 10;
System.out.println(age);//谁离我近,就用谁
System.put.println(this.age);
}
}
作用:
可以区别成员变量和局部变量。
this的本质和内存图
本质:
所在方法调用者的地址。
内存图:
set方法中的this
构造方法
概述
- 构造方法也叫做构造器、构造函数。
分类
- 无参构造方法:初始化对象时,成员变量的数据均采用默认值。
- 有参构造方法:初始化对象时,同时可以为对象进行赋值。
作用:
- 创造对象的时候,虚拟机会自动调用构造方法,作用是给成员变量进行初始化(赋值)的。
格式
public class Student{
修饰符 类名(参数){
方法体;
}
}
特点
- 方法名与类名相同,大小写也要一致。
- 没有返回值类型,联void都没有。
- 没有具体的返回值(不能由return带回结果数据)。
执行时机:
- 创建对象的时候由虚拟机调用,不能手动调用构造方法。
- 每创建一次对象,就会调用一次构造方法。
package com.example.test;
public class Student{
private String name;
private int age;
/*如果我们自己没有写任何的构造方法
*那么虚拟机会给我们加上一个如下的空参构造方法
*/
public Studen(){
System.out.println("看看我执行了吗");
}
//有参构造
public Student (String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
package com.example.test;
public class StudentTest{
public static void main(String[] args){
//创建
//调用的空参构造
//Student s = new Student();
Student s = new Student("张三",24);
System.out.println(s.getName);
System.out.println(s.getAge);
}
}
注意事项
1.定义
- 任何类定义出来,默认就自带了无参数构造器,写不写都有。
- 一旦定义了有参数构造器,无参数构造器就没有了,此时就需要自己写无参数构造器了。
package com.example.test;
public class Student{
private String name;
private int age;
/*如果我们自己没有写任何的构造方法
*那么虚拟机会给我们加上一个如下的空参构造方法
*/
//public Studen(){
//System.out.println("看看我执行了吗");
// }
//我们将无参构造方法注释。然后在测试类中去调用无参构造方法。发现代码报错。
//有参构造
public Student (String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
package com.example.test;
public class StudentTest{
public static void main(String[] args){
//创建
//调用的空参构造
Student s = new Student();
Student ss = new Student("张三",24);
System.out.println(ss.getName);
System.out.println(ss.getAge);
}
}
2.重载
- 带参构造方法,和无参数构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载。
3.推荐的使用方式
- 无论是否使用,都手动书写无参数构造方法,和带全参数的构造方法。
标准JavaBean
规矩
1.类名需要见名知意
2.成员变量使用private修饰(保证数据的安全性)
3.提供至少两个构造方法
- 无参构造方法
- 带全部参数的构造方法
4.成员方法
- 提供每一个成员变量对应的setXxx()/getXxx()。
- 如果还有其他行为,也需要写上。
对象内存图
一个对象的内存图
当我们创建对象的时候,比如
Student s = new Student();
虚拟机会执行以下七步:
1.加载class文件
2.申明局部变量
3.在堆内存中开辟一个空间
4.默认初始化
5.显示初始化
6.构造方法初始化
7.将堆内存中的地址值赋值给左边的局部变量
public class Student{
String name;
int age;
public void study(){
System.out.println("好好学习");
}
}
public class TestStudent{
public static void main(String[] args){
Student s = new Student();
System.out.println(s);
System.out.println(s.name + "..." + s.age);
s.name = "阿强";
s.age = 24;
System.out.println(s.name + "..." + s.age);
s.study();
}
}
-
在方法区中加载StudentTest.class文件,文件中将main()进行临时存储。虚拟机会自动调用程序的主入口main方法,所以此时main()方法会被加载进栈里面。其次创建对象,创建对象时,虚拟机会执行以上七步。
-
加载class文件:在方法区加载Student.class文件临时存储,里面会有这个类的所有信息(所有成员变量,所有成员方法)。
-
申明局部变量:创建对象Student s = new Student();等号左边的代码。在栈内存中它会在main()方法中开辟一块名为s的空间。这个空间能存储Student对象的地址值。
-
在堆内存中开辟一个空间:其实就是创建对象Student s = new Student();等号右边的代码。在堆内存中开辟如右边白色区域的空间。假如这个空间的地址值是001。在这个空间中,它会将Student类中所有的成员变量拷贝一份放到该空间。除此之外,还会有所有成员方法的地址。目的是为了以后用对象调方法时能找到对应的方法。
-
默认初始化:给name和age赋默认值,null和0;
-
显示初始化:定义成员变量时,直接给值叫显示初始化。若像如下定义成员变量那么在这一步。name的null就会变为"张三",age的0就会变为23.但在上诉代码中我们没有这样写,所以这一步就直接忽略。
-
范例:String name = "张三"; int age = 23;
-
构造方法初始化:在new Student();括号中什么都没写,代表着我们调用的是空参构造。所以这一步也可以忽略。如果是有参构造那么现在name跟age就会有值了。
-
将堆内存中的地址赋值给左边的局部变量:其实就是将堆内存中的地址值通过等号运算赋值给s,此时s这个空间就会存储001这个地址值。而s也可以通过001找到堆空间。
-
综上一个对象创建完毕。
打印s就是打印s中存储的地址值。所以结果就是001
打印s.name和s.age就是获取堆空间对应name和age的null和0;
对s.name,s.age赋值就是对001.name和001.age赋值
打印就是打印修改后的001.name和修改后的001.age。
调用001的方法。打印好好学习。执行完毕后出栈。程序执行完毕main()方法出栈,变量s消失。没有变量指向堆内存中的001也会变为垃圾消失。
多个对象的内存图
注意:在创建两个对象时class文件只加载一次。
两个变量指向同一个对象内存图
当两个变量指向同一个空间时,只要有一个变量对这个空间的值发生了改变,那么其他的变量再次访问的时候就是修改后的结果。
局部变量和成员变量的区别
成员变量:类中方法外的变量。
局部变量:方法中或者方法申明上的变量。
打印就是打印修改后的001.name和修改后的001.age。
调用001的方法。打印好好学习。执行完毕后出栈。程序执行完毕main()方法出栈,变量s消失。没有变量指向堆内存中的001也会变为垃圾消失。
多个对象的内存图
注意:在创建两个对象时class文件只加载一次。
两个变量指向同一个对象内存图
当两个变量指向同一个空间时,只要有一个变量对这个空间的值发生了改变,那么其他的变量再次访问的时候就是修改后的结果。
局部变量和成员变量的区别
成员变量:类中方法外的变量。
局部变量:方法中或者方法申明上的变量。