5.1 方法的概念和特点
方法:
每一个方法都代表一个“独立的”、“可复用”的功能。
方法的特点:
(1)必须先声明后使用
(2)不调用不执行,调用一次执行一次
5.2 方法的声明和调用
方法的声明格式:
【修饰符】返回值类型方法名(【形参列表】){
方法体语句;
}
【修饰符】:目前都写public static
返回值类型:
(1)没有结果返回:void,在方法体语句中,如果需要提前结束当前方法,使用 return ;语句。
(2)有结果返回:可以是Java的任意数据类型,包括基本数据类型和引用数据类型。在方法体中使用 return 结果; 语句返回结果。
方法名:(1)见名知意(2)遵循小驼峰命名法,从第二个单词开始首字母大写。
(【形参列表】):
(1)无参,空参:(),调用时,不需要给方法传递参数
(2)有参:(数据类型 参数名) 或 (数据类型 参数名, 数据类型 参数名, .......) ,调用时,必须传入对应个数、类型、顺序的实参。
{方法体语句;}:用于完成方法的“功能”的语句
静态方法的调用格式:
//在本类中,静态方法的调用表达式
方法名(【实参列表】)
//在其他类中,静态方法的调用表达式
类名.方法名(【实参列表】)
5.3 方法的调用过程
入栈:方法被调用时,JVM会给该方法在栈中分配一块“独立的”内存空间,用于存储该方法的局部变量等信息,这个过程称为入栈。
出栈:方法调用结束了,该方法在栈中的内存“自动”释放,这个过程称为出栈。
栈结构的特点:先进后出或后进先出。
5.4 参数问题
1、可变参数
形式:
【修饰符】返回值类型方法名(数据类型... 参数名){
方法体语句;
}
【修饰符】返回值类型方法名(其他非可变参数列表, 数据类型... 参数名){
方法体语句;
}
要求:一个方法最多有一个可变参数,而且可变参数只能是最后一个。
什么情况下需要它?
当某个方法需要某种类型的参数,但是需要几个该类型的参数不确定,可能需要0~n个。
调用包含可变参数的方法时,其他非可变参数该怎么传还是怎么传,对于可变参数部分,可以传入0~n个对应类型的实参元素,或传入一个对应类型的数组。
在声明可变参数的方法体中,把可变参数直接当成数组使用即可。
publicclassDemo{
publicstaticvoidmain(String[] args){
System.out.println(add());//传入0个实参元素
System.out.println(add(1,2,3,4,5));//传入5个实参元素
int[] arr= {4,5,6,7,8,9};
System.out.println(add(arr));//出啊人对应类型的数组
}
publicstaticintadd(int... args){
//这里把args当成数组使用
intsum=0;
for(inti=0; i<args.length; i++){
sum+=args[i];
}
}
}
2、参数的传递问题
(1)实参给形参传值
形参:方法声明时,在方法名后面(数据类型 形参名, 数据类型 形参名)
实参:方法调用时,在方法名后面(值1, 值2),这里的值可能是常量值,也可能是变量值,也可能是表达式的结果
publicclassDemo{
publicstaticvoidmain(String[] args){
System.out.println(add(4,5));//(4,5)就是实参,因为它们有实际的值
System.out.println(add(4,5,6));
}
publicstaticintadd(inta, intb){//形参列表,此时a,b只是一个形式,没有具体值
returna+b;
}
publicstaticintadd(inta, intb, intc){//(int a, int b, int c)形参列表
returnadd(add(a,b),c);
/*
add(a,b):实参,因为现在是在调用
add(add(a,b),c):第一个实参是 add(a,b)的返回值,第二个实参是c
*/
}
}
(2)传的什么值
基本数据类型:实参给形参传数据值的副本,形参的修改和实参完全无关。
引用数据类型:实参给形参传地址值的副本,形参对元素或对象的成员进行修改,就相当于实参对元素或对象的成员进行修改。
5.5 方法重载(Overload)
在同一个类中 或 父子类中 ,出现多个方法的 “方法名相同”,它们的形参列表不同(类型不同、个数不同、顺序不同)的情况,就称为方法重载。方法的重载和返回值类型无关。
5.6 方法的递归调用
递归调用:在方法中出现自己调用自己。
注意避免无限,循环调用自己,即一定要有出口,否则就会发生 StackOverflewError栈内存溢出错误。
类:一类具有相同特性的事物的抽象描述。每一个类都有自己的作用。
对象:类的一个实例,个体,实体。它是具体的。
类是创建对象的模板,类是抽象的,对象是具体的。
【修饰符】class类名{
}
new类名()
new类名(实参)
//特殊的数组对象
new元素的数据类型[长度]
new元素的数据类型[行数][列数]
new元素的数据类型[行数][]
5.8 类的成员之实例变量
5.8.1 实例变量声明格式
【修饰符】class类名{
【修饰符】数据类型 实例变量; //实例变量前面的修饰符没有static
}
5.8.2 实例变量与局部变量的区别
问:变量有在方法里面声明的,有在方法外面声明的,它们有什么区别?
【修饰符】class类名{
【修饰符】数据类型 实例变量; //实例变量前面的修饰符没有static
【修饰符】返回值类型方法名(【数据类型 形参名, 数据类型 形参名】){
数据类型局部变量名;
}
}
(1)声明的位置不同:
在类中方法外声明的:成员变量,(有static修饰的成员变量是静态变量,没有static修饰的成员变量是实例变量)
在类中且在方法中声明的:局部变量,包括在方法的()中声明的形参。
(2)它们在内存中存储位置也不同
实例变量:值是在“堆”中,必须是new之后才会内存
局部变量:值是在“栈”中,当方法被调用时,开辟内存
(3)默认值
实例变量:有默认值。
数组的元素,其实可以看成是数组的实例变量。只不过这些元素没有自己独立的名称,它们只能通过[下标]进行访问。
局部变量:没有默认值。
形参局部变量,必须在方法调用时由实参给它赋值。
其他的局部变量,必须在方法体中手动赋值。
(4)作用域
实例变量:整个类中所有非静态方法等成员都可以直接使用
局部变量:当前方法中,仅限于声明它的{}
(5)生命周期
实例变量:和对象保存一致,从这个对象被new出来,直到这个对象被GC回收。
局部变量:非常短暂,只在这个方法被调用期间,方法调用结束,自动释放。
5.8.3 如何使用实例变量?
1、在本类中
在本类的其他非静态成员中,直接使用。
publicclassCircle{
【修饰符】doubleradius;//无论前面的修饰符是public、private等,非static
publicdoublearea(){//该方法也是非static
returnMath.PI*radius *radius;//直接使用
}
}
2、其他类中
(1)可见性范围允许的情况下
对象名.实例变量
publicclassCircle{
publicdoubleradius;
}
publicclassTest{
publicstaticvoidmain(String[] args){
Circlec=newCircle();
System.out.println("半径值:"+c.radius);//对象名.实例变量
}
}
(2)可见性范围不允许
publicclassCircle{
privatedoubleradius;
publicvoidsetRadius(doubleradius){
this.radius=radius;
}
publicdoublegetRadius(){
returnradius;
}
}
publicclassTest{
publicstaticvoidmain(String[] args){
Circlec=newCircle();
c.setRadius(2.5);//给radius赋值
System.out.println("半径值:"+c.getRaius());//获取radius的值
}
}
5.8.4 实例变量的内存
publicclassCircle{
【修饰符】doubleradius;//无论前面的修饰符是public、private等,非static
}
publicclassTest{
publicstaticvoidmain(String[] args){
Circlec1=newCircle();
Circlec2=newCircle();
}
}
5.8.5 实例变量的特点
1、实例变量有默认值
2、实例变量值是每一个对象独立的
5.9 包
包的作用:
(1)可以像文件夹一样,组织管理不同主题的类
java.lang:最最基础的Java类,例如:String、System、Math它们都在这儿,就因为它们是最最基础的,这个包下的类使用时不需要import
java.util:工具类
java.net:网络编程
java.sql:数据库操作和访问相关类
....
(2)可以避免类的重名
java.util.Date
java.sql.Date
(3)控制类或成员的可见性范围
private,缺省,protected,public
只有缺省以上的,才能在包外可见,而且protected也不是包外任意可见
包的声明格式:
package包名;
这句pakcage语句必须在.java文件的首行,每一个.java文件最多只有一句package语句。
包名:
(1)所有单词都小写,单词之间使用.分割,com.atguigu.bean
(2)习惯使用公司域名倒置,例如:com.atguigu.xxx
(3)自己命名的包不能使用java开头,例如:java.test.xx 错误的
使用其他包的类,需要使用全名称或导包。
import包.类名;
import包.*;
import语句只能在package语句和class声明之间。
5.10 对象数组
对象数组的元素类型是Java的引用数据类型。
String[] names;//是
Student[] all;//是
String[][] strings;//也是
声明格式:
一维:
元素的数据类型[] 一维数组名;
二维:
元素的数据类型[][] 二维数组名;
静态初始化格式:
一维:
元素的数据类型[] 一维数组名= {对象1,对象2,...};
二维:
元素的数据类型[][] 二维数组名= {{对象1,对象2,...}, {对象1,对象2,...}, .....};
动态初始化:
一维:
元素的数据类型[] 一维数组名=new元素的数据类型[长度];//长度代表一个一维数组中对象的个数
//这句话只创建了数组的对象
//比喻:这句话只创建了一个用来装“钥匙”的盒子,这个盒子共有“长度”个格子
一维数组名[下标] =new元素的数据类型();//这里才真正创建元素对象
//比喻:这句代码才真正的创建“产品”及其对应的钥匙。
二维:
元素的数据类型[][] 二维数组名=new元素的数据类型[行长度][列长度];//每一行都有“列长度”个对象
//这个二维数组中的对象个数有 行长度 * 列长度
二维数组名[行下标][列下标] =new元素的数据类型();//这里才真正创建元素对象
元素的数据类型[][] 二维数组名=new元素的数据类型[行长度][];//这句代码只是确定了行
//比喻:这句代码只创建了具有多层的盒子,但是每一层有几个格子还没有确定
二维数组名[行下标] =new元素的数据类型[列长度];//这句代码确定饿了某一行的长度
//比喻:这句代码给某一层的盒子分了“列长度”个格子,产品还有创建出来
二维数组名[行下标][列下标] =new元素的数据类型();//这里才真正创建元素对象
对象数组的使用:
对象数组的元素也是一个对象,是对象就可以访问该对象类型中的成员。
一维:
声明和初始化见上面
一维数组名[下标].实例变量
一维数组名[下标].方法(【实参列表】)
二维数组:
声明和初始化见上面
二维数组名[行下标][列下标].实例变量
二维数组名[行下标][列下标].方法(【实参列表】)