成员方法的传参机制:
对于基本数据类型,传递的是值,形参的任何改变不影响实参
引用类型(类,数组,接口)传递的是地址,可以通过形参改变实参
方法递归调用:自己调用自己
递归的重要规则:
1执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2方法的局部变量时独立的,不会互相影响
3如果方法中使用的是引用类型变量(比如数组,对象),就会共享该引用类型的数据
4不能死循环
5谁调用就将结果返回谁
方法重载:允许在同一个类中,多个同名方法的存在,但要求形参列表不一致
重载的好处:起名字/记名字麻烦
使用细节:
方法名必须相同,形参列表必须不同,参数名无要求,返回类型无要求
可变参数:允许一个类中多个同名同功能但参数个数不同的方法封装成一个方法
//int... 表示接受的是可变参数,类型是int,可接受(0-多个)int,可以把nums当作数组来用
//可变参数的实参可以是数组
//可变参数可以和普通类型的参数一起放在形参列表,但是可变参数必须在最后
//一个形参列表中只能出现一个可变参数
语法:public int sum(int... nums){
int res = 0;
for(int i = 0; i < nums.length;i++){
res +=nums[i];
}
return res;
}
作用域:
全局变量:也就是属性,作用域为整个类体,属性在定义时,可以直接赋值
局部变量:一般在成员方法中定义的变量,作用域在成员方法中
除了属性之外的其他变量都是局部变量
属性(全局变量)不赋值有默认值,但是局部变量必须赋值才能使用
属性和局部变量可以重名,访问时遵循就近原则
同一个作用域中,两个局部变量不能重名
属性的生命周期长,局部变量的生命周期短
属性可以加修饰符,局部变量不能加修饰符
构造方法/构造器:是类的一种特殊的方法,主要作用是完成对新对象的初始化
特点:方法名和类名相同,没有返回值,在创建对象时,系统会自动完成对象的初始化
一个类可以定义多个构造器,构造器可以重载
如果程序员没有定义构造类,系统会自动给类生成一个默认无参构造器,可以使用javap反编译查看
一旦定义了自己的构造器,默认的构造器就被覆盖了,除非自己再显示的定义一下
栈里是对象引用,堆里才是对象
public Dog(String name){}-------->自己定义的 Dog(){}--------->默认构造器
main函数中:Person p1 = new Person("jack", 90);
class Person{
String name;
int age;
public Person(String pname, int page){
name = pname;
age = page;
}
}
对象创建的流程分析:
class Person{
String name;
int age=90;//比构造器先执行
Person(String pname, int page){//构造器
name = pname;//给属性赋值
age = page;
}
}
Person p = new Person("小钱", 20);
1.先加载Person类信息(Person.class),只会加载一次,在堆中分配空间(地址)
2完成对象初始化(默认初始化 age=0,name=null),再进行显示初始化 age=90,name=null,构造器初始化 age=20,name=小钱
3把对象在堆中的地址返回给p(p是对象名或者是对象引用)
this关键字:java虚拟机会给每个对象分配this代表当前对象
Person(String pname, int page){//构造器 中的输入参数不是非常的好,如果能直接将pname改成name就好了,但是我们会发现按照变量的作用域原则,name的值就是null ,因此引出this关键字
//this.name就是当前对象的属性
this.name = name;
哪个对象调用,this就代表哪个对象
如果方法中没有局部变量,那this可以不用写
this不能在类的外部使用,只能在类定义的方法中使用
this关键字访问成员方法
public void f1(){}
public void f2(){
//调用f1的第一种方法
f1();
//调用f1的第2种方法
this,f1()
}
this关键字访问构造器(只能在构造器中访问另一个构造器)
public T1(){
//这里去访问public T1(String name,int age)只能放在第一句
this("jack", 20);
}
public T1(String name,int age){
}
new Test().count1();//new Test().为匿名对象,使用后就不能使用了