一、联系与定义:
面向过程:当需要实现一个功能的时候,强调具体的实现细节和步骤,第一步干什么,第二步干什么。。。。
面向对象:当需要实现一个功能的时候,不关心具体的细节,而是找一个已经有该功能的东西替我实现 *
类:相关属性和行为的集合。
对象:是一类事物的具体体现。对象是类的一个实例
案例:
要求遍历10、20、30、40、50这样的数组并以方括号的形式打印出来
面向过程:强调的是具体细节
1.第一步打包 int[] array={10,20,30,40,50};
2.第二步添加方括号 System.out.print("[");
3.第三步使用for语句遍历 for (int i=0;i<array.length;i++){
4.第四步为了使最后 if (i==array.length-1)
输出50并加上方括号
使用if语句 System.out.println(array[i]+"]");
else {
System.out.print(array[i]+",");
}
}
面向对象:使用已经有该功能的代码替我完成
int[] array={10,20,30,40,50};
System.out.println(Arrays.toString(array));
Array.toString(数组名)自动遍历数组,并以方括号为存储
二、面向对象理论与实列讲解
1.成员变量直接定义在类当中,方法外
2.成员方法不要写static关键字,调用方法必须使用实例化(创建对象,由对象来调用)
3.普通方法要有static关键字,调用方法有(单独调用,直接调用,赋值调用)
1.定义一个student类 public class Student {
2.描述属性 String name;
(成员变量名) int age;
3.描述行为,这里使用
方法做为容器,不可以 public void eat(){
使用static关键字 System.out.println("我会吃");
(成员方法) }
}
三、调用方法
通常情况下,一个类不能直接使用,需要根据类创建一个对象来使用
类的作用:把这个类里的属性和行为封装到一个类里,用到什么调用什么
1.导包:指出要用到的类在什么位置 格式:import 包名.类名 * 但是对于和当前类属于同一个包的情况,可以省略导包语句
2.创建对象:类名 对象名=new 类名();
3.使用成员变量和成员方法
均使用单独调用的方法实现
成员变量:对象名.成员变量名
System.out.println(stu.name);
成员方法:对象名.成员方法名()
stu.eat();
即 用谁 就 对象名.谁
注:成员变量若没有赋值,那么他是有默认值的,规则和数组里的一样
1.创建一个新的类 public class UseStudent {
2.使用main方法 public static void main(String[] args) {
3.创建对象,使用 Student stu=new Student;
new元素开辟空间
4.使用成员变量 System.out.println(stu.name);
System.out.println(stu.age);
5.使用成员方法 stu.eat();
}
}
四、成员变量与局部变量的区别
1.定义的位置不一样
成员变量:类里方法外 局部变量:方法里
2.作用范围不一样
成员变量:整个类里面都可以使用 局部变量:方法里可以用,出了方法就失效
3.默认值不一样
成员变量:有默认值,规则和数组一样 局部变量:无默认值,要想使用必须赋值
4.生命周期不一样
成员变量:随着对象的诞生而诞生,对象被回收而消失
局部变量:随着方法的诞生而诞生,方法执行完局部变量失效
5.内存的位置不一样 成员变量:堆 局部变量:栈
案例:
在二、三类的基础上做扩展
在student中新建方法
4.新建方法 public void method1(){
此时变量为局部变量 int age=20;
输出的依旧是成员变量 System.out.println(age);
System.out.println(name);
}
}
在UseStudent中使用
public class UseStudent {
public static void main(String[] args) {
Student stu = new Student(); //使用new元素开辟空间 可以创建无穷无尽的对象
Student stu2 = new Student();
定义stu stu.name="张三";
stu.age=18;
定义stu2 stu2.name="李四";
stu2.age=58;
此时的输出结果为张三20,体现局部变量的私有性
id给予:
创建p1对象并赋值,再将p1赋值给p2,此时p2的地址就与p1一致,值也一致
phone p1=new phone(); //new 相当于返回地址值
//见到new做两件事情:
1.给对象分配一个引用值
2.把类中的成员变量和方法都给了对象
p1.brand="小米2";
p1.price=1999.99;
p1.color="red";
五、this用法:
1.当局部和成员变量名重名时,优先使用局部
2.想要使用成员变量,需要使用this关键字。格式:this.变量名
案例:
1.建立类:
public class person {
//成员变量
String name; //对方的名字
//成员方法
public void sayHello(String name){
System.out.println(this.name+"你好"+name);
}
}
2.调用方法:
public class personText {
public static void main(String[] args) {
person p = new person();
p.name="赵寻说";
p.sayHello("李怡");
}
}
3.调用其他构造方法
例子
public class Person {
private String name;
private int age;
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
}
this关键字的内存原理
this的作用:区分局部变量和成员变量
this的本质:所在方法调用者的地址值
this的内存原理:
1.首先找到main方法,main方法先进栈
方法区会自动加载studentTest类的字节码文件
2.然后执行main方法的第一行代码,因为调用了student类,所以会将student这个类的字节码文件加载到方法区当中
3.在调用时
Student s = new Student;
Student s 相当于定义了一个变量s,所以s会加载到栈内存中
new Student 相当于在堆内存开辟了一个新的空间,这个空间的地址拟定为001
4.因为在student类当中只定义了一个成员变量,那么推内存当中也就只有一个变量,并为int数据类型赋予一个初始值0。在001的空间中还有成员方法的地址引用。最后将001这个空间的地址值赋值给s
5.main方法继续执行,
s.method;
1.method因为s的调用会进入到栈,其方法和属性同样进入栈内
2.调用者s(001)
3.this的本质代表着调用者的地址值,this(001)
4.sout(age) 因为就近原则,age输出为10
5.this.age 调用堆001空间中的默认值0
set
六、private介绍
封装思想:
对象代表什么,就得封装什么样的数据,并提供数据对应的行为
private:
private(私有):通过私有化成员变量,保护数据的安全性
修饰完之后只能在本类中使用
1.pritave是一个权限修饰符
2.可以修饰成员(成员变量和成员方法)
3.被private修饰的成员只能在本类中才能访问
4.针对private修饰的成员变量,如果需要被其他类处理,需要提供相应的操作
5.提供"setxxx(参数)"方法,用于给成员变量赋值,方法用public修饰
6.提供"getxxx"()方法,用于获取成员变量的值,方法用public修饰
set方法:给成员变量赋值
get方法:对外提供成员变量的值
案例说明:
在定义男朋友对象时,成员方法的赋值是在调用类中所实现的,试想定义了一个男朋友类,如果在赋值时,错误的将其年龄赋值为了-18,那么这个程序也是可以正常运行的,但是在人类的思想中年龄不可能是负数,这时我们就需要对数据进行筛选,以确保数据的安全性与准确性。
1.为了确保数据的准确性,那我们为男朋友添加一个方法,用来筛选正确的数据
那么这个筛选的方法肯定是要封装到男朋友这个对象中,遵循的是对象代表什么,就得封装什么样的数据,并提供数据对应的行为 体现封装性
2.由于男朋友这个类中是没有main方法的所以这时就需要创建普通方法
此时就需要用到:
5.提供"setxxx(参数)"方法,用于给成员变量赋值,方法用public修饰
6.提供"getxxx"()方法,用于获取成员变量的值,方法用public修饰
定义方法:
1.如果一个方法无返回值,那么方法名前面的”返回值类型“就是void类型
2.如果一个方法无返回值,那么它只能使用单独调用,不能使用赋值调用和打印调用
定义步骤:
针对于每一个私有化变量都需要提供get和set方法
1.定义name与type,这两个数据是不需要加以限制的,也不需要使用返回值,故其方法名前的返回值类型为void
set的作用是给name赋值
不需要返回值
public void setName(String n){ //此处使用public作为修饰,返回值为空,()括号里的参数类型与上
name=n; 面对应一致
}
2.对外输出提供name属性
1.不需要接收数据
2.只需要将值给外面
public String getname(){
return name;
};
3.type同name一致操作
4.定义age
public void setAge(int a){
if (a>=18&&a<50){
age=a;
}else{
System.out.println("非法数据");
}
}
public int getAge(){
return age;
}
5.调用方法:
boyfriend b1 =new boyfriend();
b1.setName("郑义");
b1.setAge(-18);
b1.setType("型男");
System.out.println(b1.getName());
System.out.println(b1.getAge());
System.out.println(b1.getType());
这时输入年龄-18就会报错
补充内容:
1.对于private修饰的boolean类型成员变量,get方法要写成isxxx的形式
boolean的数据只能接收输出true和false
2.单独调用和赋值调用都不会输出结果
3.对于无法回值的方法,只能同过单独调用进行赋值
七、构造方法
构造方法:new是专门用来创建对象的方法,在创建new时,就是在调用一个构造方法
此时构造的是一个空参方法
类名 对象名 = new 类名();
作用:在创建对象的时候给成员变量进行初始化的。
想调用几个构造方法就new几个
1.在创建对象的时候,会调用构造方法,完成对象的实例化,即为对象的赋予了初值,确保对象在使用之前就具有正确的状态。
2.避免了手动赋值的繁琐
格式:
public 类名(参数类型 参数名1,参数类型 参数名2,){
方法体
}
注意: 1.构造方法的名称和类名一模一样,包括大小写
2.构造方法无返回值类型,不写void
3.构造方法不能return具体的返回值
4.如果没有编写构造方法,那么编译器会默认赠送一个构造方法:无参数,无方法体,什么也不做。
public 类名(){
}
5.构造方法是可以重载的,方法名相同,但是参数不同
6.只要编写了至少一个构造方法,那么编译器将不会赠送默认的构造方法,相当于无参构造失效,必须手动添加
7.空参构造没有给变量赋值时,他的变量就是默认的初始化
执行时机:
1.创建对象的时候由虚拟机调用,不能手动调用构造方法
2.每创建一次对象,就会调用一次构造方法
两大构造方法的特点:
无参的构造方法:初始化对象时,成员变量均采用默认值、
有参的构造方法:在初始化的时候,同时可以为对象进行赋值
注意事项:
1.只要编写了至少一个构造方法,那么编译器将不会赠送默认的构造方法,相当于无参构造失效,必须手动添加
2.任何类定义出来,默认自带了无参的构造器,写不写都有
方法的重载:
方法名相同,但是参数列表不一样
1.参数的个数不同: 比如sum(int a,int b) sum(int a)
2.参数的类型不同:比如sum(int a,int b) sum(double a,double b)
调用重载时的赋值问题
由参数而定,无参不用赋值,只有一个参数的只需赋一值,全参的将全部参数赋值
public student(){ //自定义无参的构造方法
System.out.println("无参构造方法执行了");
}
public student(String name,int age){
System.out.println("全参构造方法执行了");
this.age=age;
this.name=name;
}
public student(String name){
this.name=name;
System.out.println("只有一个参数的构造方法");
}
以下参数输入几参,就是为几参方法赋值
student stu1=new student(); //无参的构造方法
student stu2=new student("黄蓉",20); //全参的构造方法
student stu3=new student("郭靖"); //一个参数
八、标准的类javaBean
标准的类,应满足以下4个条件:
1.类名要有见名之意
2.所有的成员变量都要使用private来修饰(外部类不能访问本类中的成员变量,就不会随意的去改值,起到了一个保护成员变量的作用)
3.为每一个成员变量编写一对getter和setter方法
其他行为也要写上
4.提供至少两个构造方法
无参的构造方法
全参的构造方法
九、对象内存图
1.java内存分配介绍:
栈、堆、方法区、本地方法栈、寄存器
在程序运行时,每个软件都会占用内存
jvm将其划分为五个部分
1.当运行一个类的时候,类的字节码文件就会进入方法区中临时存储
jdk8前
jdk8后
一个对象的内存图:
创建一个对象
student s = new student();
创建一个对象至少做7步
1.加载class文件
将student的字节码文件加载到内存
2.申明局部变量
就是将等号左边的s进行声明
3.在堆内存中开辟一个空间
等号的右边new关键字会在堆里面开辟一个空间
这个空间就是对象
4.默认初始化
5.显示初始化
6.构造方法初始化
7.将堆内存的地址值赋值给局部变量
执行完毕后成员方法、main方法会从栈内存中退出。
当没有变量指向推内存中新建的空间时,堆内存中的变量也会消失变成垃圾
两个对象的内存图
当第一个对象的study方法出栈时
这一次class字节码文件不会在加载一次,可以直接使用
new空间相互独立
两个引用指向同一个对象
此时,把stu1的地址值赋值给了stu2,stu2与stu1的地址值都位001
当给stu2.name赋值时,就是将“阿珍”赋值给了001,阿珍覆盖了阿强
当给stu1赋值null时,就相当于关闭了栈与堆的连接,此时在打印stu.name就会报错空指针异常
但是此时输出stu2.name时,会正常输出栈里001的值
当将stu2赋值null时,就会断开stu2与栈001的链接
一旦没有人在用栈中001的空间,它就变成了垃圾
程序执行完之后,main方法就会从栈里出去
当两个变量指向同一个空间的时候,只要有其中一个发生了改变,再次访问时,就是后面改变之后的结果。
十、基本数据类型与引用数据类型的区别
基本数据类型:
四类八种:
1.整数类型
2.浮点型类型
3.布尔类型
4.字符类型
引用数据类型:
除了四类八种以外的
内存图:
基本数据类型:
引用数据类型:
内存上的解释:
如果有一个对象对空间中的值进行了修改,那么其它对象访问到的也就是修改后的值