oop初级
类是抽象的,对象是实例的,类是对象的模板,对象是类的一个个体
1. 对象内存布局
基本数据类型直接放在堆中,不放方法区的常量池
在new对象的时候会在方法区中加载Cat类信息
2. 基本介绍
叫法:成员变量 = 属性 = field(字段)
属性一般是基本数据类型,也可以是引用数据类型
属性的注意事项及其说明:
(1).属性的定义: 访问修饰符 属性类型 属性名;
(2).访问修饰符:控制属性的访问范围; 4种访问修饰符(public;proctected;默认;private)
(3).属性一般是基本数据类型,也可以是引用数据类型
(4).属性如果不赋值有默认值
访问属性:对象.方法
jvm的内存分析代码执行流程
0198集
类信息只会加载一次
//Person b;
b = null;//b -> null;b不再具有堆中存放的属性(或者说不再指向堆中存放原有属性的地址)(也就不能调用b中原有的属性)
方法调用机制
方法调用流程(小结):
-
在main栈中new一个Person类的对象,指向堆中的(对象);
-
用该对象调用方法,就会开辟一个独立的空间(栈空间)(getSum栈(独立空间))
-
当方法执行完毕,或者执行到return语句时,就会返回
-
返回到调用方法的地方
-
-
当main方法(栈)执行完毕,整个程序退出
3. 成员方法的定义
基本语法:
访问修饰符 返回数据类型 方法名 (形参列表..){
方法体语句;
return 返回值;
}
-
形参列表:表示成员方法输入 cal(int n),getSum(int num1,int num2);
-
数据类型(返回类型):表示成员方法输出,void表示没有返回值
-
结合void是否使用return语句
-
方法体:为了实现某一功能的代码块
4. 方法注意事项与细节
-
访问修饰符(public, protected, 默认,private);如果不写默认访问
-
一个方法最多有一个返回值[如何返回多个值? --> 返回数组]
-
返回类型可以为任意类型,基本数据类型和引用类型
-
参数类型可以为任意类型,包含基本类型或引用类型
-
如果方法要求有返回数据类型,则方法体最后为 return 值;且要求返回值类型必须和return类型一致或者兼容
-
如果方法是void,则方法体中可以没有return语句,或者只写 return;
-
方法定义时的参数称为形参,方法调用时的传入参数称为实参;实参与形参类型要一致或兼容,个数、顺序必须一致
-
方法不能嵌套定义
方法调用细节:
-
同一个类中的方法调用:直接调用就行
-
跨类方法调用:通过对象名调用
特别说明:跨类的方法调用与方法的访问修饰符有关
5. 方法传参!!!(paramete 参数)
(1).基本数据类型的传参机制
以一个冒泡交换的案例引:
swap栈与main栈空间独立
结论:基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参。(如上图)
(2).引用数据类型的传参机制(数组)
引用类型(数组) 指向 堆中一个地址
调用一个方法就会产生一个新栈
引用类型传递地址!!
结论:引用类型传递的是地址(地址中有值),可以通过形参影响实参。(如上图)
(3). 传对象
p.age = 10000; //修改对象属性
深刻剖析:
实质上就是传对象
原来的 p.age = 10 ; 然后调用test200方法,将p传进去,然后修改对象属性 p.age = 10000;
思考?
1.如果将上面B类中的 p.age = 10000; 改为 p = null; 结果如何?
B类中的p对象为空,只是自己变为空,对age无影响,所以age没有改变,所以 main 的p.age=10
2.如果将上面B类中的 p.age = 10000; 改为 p = new Person(); p.name = "tom"; p.age = 99; 结果如何?
深刻剖析:
出现 p = new Person(); 实质上是创建了一个新的对象p(开辟了一个新的空间,与main方法中的对象p空间相互独立),
p.name = "tom"; p.age = 99; 实质上是对这个新创建的对象进行赋值,与main方法中的p对象无关
形参类型与方法类型一致
6. 递归
入门案例
案例一:
自己调用自己,不断开辟新栈;当不满足条件,执行输出语句;不断返回上一个栈(从最顶级的栈开始返回),执行未完成的语句;
直到返回到最后一个栈,程序退出
案例二:
阶乘
递归重要规则
-
执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
-
方法的局部变量是独立的,不会相互影响,比如n变量
-
如果方法中使用的是引用类型变量(数组,对象)(指向地址),就会共享该引用类型的数据(相互影响)
-
递归必须向退出递归的条件逼近
-
当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕(程序退出)
实质:递归就是从后往前推,在最前面找一个临界条件;根据所给的最后条件一步步往前推
递归具有回溯现象!!!(老鼠走迷宫)
汉诺塔,八皇后
7. 方法重载
java中允许一个类中,多个同名方法的存在,但要求形参列表不一致!
当使用方法时系统自动匹配符合形参列表的方法
细节:
-
方法名相同
-
形参不同(不是说形参的名字不同)
-
返回类型无要求(可以是void也可以是基本数据类型)
可变参数
java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。就可以通过可变参数实现
基本语法:
访问修饰符 返回类型 方法名 (数据类型... 形参名){ }
使用可变参数时可以当作数组来使用(加上循环)
细节:
-
可变参数个数可以为0个或者多个
-
可变参数的实参可以为数组
-
可变参数的本质就是数组
-
可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
-
一个形参列表中只能出现一个可变参数
8.变量作用域!!!
细节:
-
主要变量是属性(成员变量)和局部变量(是指在成员方法中定义的变量)
-
属性作用域为整个类,局部变量(除了属性外的变量)作用域在定义它的代码块中
-
属性可以不赋值(有默认值),局部变量必须赋值
注意:
-
属性和局部变量可以重名,访问时遵循就近原则
-
在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名
-
属性生命周期长(随对象),局部变量声明周期短
-
作用域范围不同:属性可以被本类或其他类使用(new对象)(1.方法调用 2.传对象);局部变量只能在本类中对应的方法使用
-
属性可以加修饰符,局部变量不能加修饰符
9. 构造器(construor)
基本语法:
[修饰符] 方法名 (形参列表){
方法体;
}
-
修饰符可以默认
-
没有返回值,也不能写void
-
方法名和类名一样
-
参数列表和成员方法一样的规则
-
构造器调用由系统完成
作用:初始化对象
一个没有返回值的方法(用来给属性初始化值,传入的)
Person p1 = new Person("smith", 80); //传入初始化属性的值
当构造器被调用的时候,对象已然存在(不是创建对象,是初始化)(传入属性)
补充细节:
-
一个类可以定义多个构造器,即构造器的重载(形参列表)(可以通过不同对象传入不同实参理解)
-
如果没有写定构造器,系统会给出一个默认无参构造器(Dog dog1 = new Dog();)
-
如果定义了自己的构造器,默认无参构造器就不能使用(覆盖),除非显示定义一下(Dog( ){ })
真正的对象在堆中,栈中的只是对象名
流程分析:
-
加载Person类信息(Person.class),只会加载一次
-
在堆中分配空间(地址)(实际对象)
-
完成对象初始化 [3.1 默认初始化 age = 0,name = null; 3.2 显示初始化 age = 90,name = null; 3.3 构造器的初始化 age = 20, name = 小倩]
-
将对象在堆中的地址,返回给p(p是对象名,也可以理解成是对象的引用)
10. this关键字
Dog dog1 = new Dog("大壮",3);
dog1.info();//大壮 3
//一个对象就是一个独立空间
//栈中存放方法,堆中存放对象
class Dog{
String name;
int age;
public Dog(String name,int age){
//this.name 就是当前对象的属性name
this.name = name;
//this.age 就是当前对象的属性age
this.age = age;
//也就是令传入的("大壮",3)(String name,int age) 赋给当前对象dog1,则dog1的name = "大壮",age = 3
System.out.println("this.hashCode" + this.hashCode());//可通过hashcode来看this和dog1的地址(不是真的地址)
}
public void info(){
System.out.println(name + "\t" + age + "\t");
}
}
jvm内存深入理解this
this小结:哪个对象调用,this就代表哪个对象!!!
细节:
-
this关键字可以用来访问本类的属性(准确访问)、方法、构造器
-
this用于区分当前类的属性和局部变量
-
访问成员方法的语法:this.方法名(参数列表);
-
访问构造器语法:this(参数列表);注意只能在构造器中使用(在一个构造器中访问另一个构造器 this(参数列表)必须放在开始)(构造器的复用)
-
this不能在类定义的外部使用,只能在类定义的方法中使用
new Test().count1(); //new Test()是匿名对象,匿名对象使用后,就销毁(不能再使用)
System.out.println("count=" + count++);//先输出count,再自增

浙公网安备 33010602011771号