1.3 方法递归调用
*阶乘
public int factorial(int n)
{
if(n == 1){
return 1;
}
else{
return factorial(n-1)*n;
}
}
1.递归重要规则
1.执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
2.方法的局部变量是独立的,不会相互影响,比如n变量
3.如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据
4.递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError
5.当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就,就将结果返回给谁,当方法执行完毕或者返回时,该方法也就执行完毕
2.斐波那契数列
public int fib(int n)
{
if(n == 1 || n ==2)
{
return 1;
}
else
{
return fib(n-1) + fib(n-2);
}
}
3.猴子吃桃
public int eatPeach(int day)
{
if(day == 10)
{
return 1;
}
else if(day >=1 && day <=9)
{
return (eatPeach(day + 1)+1) * 2;
}
}
4.老鼠走迷宫
0表示可以走,1表示障碍物,2表示走得通
public boolean findway(int[][] map, int i,int j)
{
if(map[6][5] == 2) //说明已经找到
{
return true;
}
else
{
if(map[i][j]==0) //当前这个位置为0,表明可以走
{
map[i][j] == 2;
//找路策略,下,右,上,左
if(findWay(map, i+1 , j))
{
return true;
}else if ( findWay(map,i, j+1)){
return true;
}else if( findWay(map,i-1, j)){
return true;
}else if( findWay(map,i, j-1)){
return true;
}else {
map[i][j] = 3;
return false;
}
}
}
}
5.汉诺塔
pubolic class HanoiTower{
public static void main(String[] args){
Tower tower = new Tower();
tower.move(1,'A','B','C');
}
}
class Tower{
//方法
//num 表示要移动的个数,a,b,c分别表示A塔,B塔,C塔
public void move(int num, char a,char b, char c)
{
if(num == 1){
System.out.println(a + "->" + c);
}else{
//如果有多个盘,可以看成两个,最下面的和上面的所有盘(num-1)
//1.先移动上面所有的盘到b,借助c
move(num - 1,a,c,b);
//2.把最下面的这个盘,移动到c
System.out.println(a + "->" + c);
//3.再把b塔的所有盘,移动到c,借助a
move(num - 1,b,a,c);
}
}
}
1.4 方法重载(OverLoad)
*基本介绍
java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致。
class MyCalculator{
public int calculate(int n1,int n2)
{
return n1 + n2;
}
public double calculate(int n1,double n2)
{
return n1 + n2;
}
public double calculate(double n1,int n2)
{
return n1 + n2;
}
public int calculate(int n1,int n2,int n3)
{
return n1 + n2 + n3;
}
}
1.方法重载使用细节
1.方法名:必须相同
2.参数列表:必须不同(参数类型或个数或顺序,至少有一样不同,形参参数名无要求)
3.返回类型:无要求
1.4 可变参数
*基本概念:
java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法,就可以通过可变参数实现
*基本语法:
访问修饰符 返回类型 方法名(数据类型…形参名){
}
class HspMethod{
//可以计算2个数的和,3个数,4,5,6...
//可以使用方法重载
public int sum(int n1, int n2){
return n1 +n2;
}
public int sum(int n1,int n2, int n3){
return n1 +n2 +n3;
}
public int sum(int n1,int n2, int n3,int n4){
return n1 +n2 +n3+n4;
}
//上面三个方法名称相同,功能相同,但参数个数不同->使用可变参数优化
//1.int...表示接受的是可变参数,类型是int,即可以接收多个Int(0-多)
//2.使用可变参数时,可以当做数组来使用,即nums可以当做数组
//3.遍历nums求和即可
public int sum(int... nums){
//System.out.println("接收的参数个数=" + nums.length);
int res = 0;
for(int i =0;i<nums.length;i++){
res += nums[i];
}
}
}
1.可变参数的注意事项与细节
1.可变参数的实参可以为0个或任意多个
2.可变参数的实参可以为数组
3.可变参数的本质就是数组
4.可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
5.一个形参列表中只能出现一个可变参数
public class VarParameterDetail{
//编写一个main方法
public static void main(String[] args){
//细节:可变参数的实参可以为数组
int[] arr = {1,2,3};
T t1 = new T();
t1.f1(arr);
}
}
class T
{
public void f1(int... nums){
System.out.println("长度=" + nums.length);
}
//细节:可变参数和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
public void f2(String str,double... nums){
}
}
1.5 作用域
*提醒:
1.主要的变量就是属性(成员变量)和局部变量
2.我们所说的局部变量一般是指在成员方法中定义的量
3.java中的作用域分类
*全局变量:也就是属性,作用域为整个类体
*局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中
class Cat
{
//全局变量:也就是属性,作用域为整个类体
int age = 10; //全局变量
public void cry()
{
//1.局部变量一般是指在成员方法中定义的量
//2.n和name就是局部变量
int n = 10;
String name = "jack";
}
}
4.全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才可以使用,因为没有默认值
1.注意事项和细节
1.属性和局部变量可以重名,访问时遵循就近原则
2.在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名
3.属性生命周期较长,伴随着对象的创建和死亡;局部变量生命周期较短,随着代码块的结束而死亡
4.作用域范围不同
*全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
*局部变量:只能在本类中对应的方法中使用
5.修饰符不同
*全局变量/属性可以加修饰符
*局部变量不可以加修饰符(public,protected之类的)
1.6 构造方法/构造器
*构造方法又叫构造器,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化
1.方法名和类名相同
2.没有返回值
3.在创建对象时,系统会自动的调用该类的构造器完成对对象的初始化
*基本语法:
[修饰符] 方法名(形参列表){
方法体;
}
*说明:
1.构造器的修饰符可以默认,也可以是public protected private
2.构造器没有返回值
3.方法名 和类名字必须一样
4.参数列表和 成员方法一样的规则
5.构造器的调用由系统完成
main()
{
Person p1 = new Person("smith", 80);
}
class Person{
String name;
int age;
//1.构造器没有返回值,也不能写void
//2.构造器的名称和类Person一样
//3.(String pName, int pAge)是构造器形参列表,规则和成员方法一样
public Person(String pName, int pAge)
{
System.out.println("构造器被调用~");
name = pName;
age = pAge;
}
}
1.注意事项和使用细节
1.一个类可以定义多个不同的构造器,即构造器重载
2.构造器名和类名要相同
3.构造器没有返回值
4.构造器是完成对象的初始化,而不是创建对象
5.在创建对象时,系统自动的调用该类的构造方法
6.如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法,比如Person(){},使用javap指令,可以反编译查看
7.一但定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器
1.7 this关键字
*java虚拟机会给每个对象分配this,代表当前对象。
class Dog{
String name;
int age;
public Dog(String name, ing age){
//this指当前变量的属性值
this.name = name;
this.age = age;
}
}
*哪个对象调用,this就指向哪个对象值
1.this使用注意事项和细节
1.this关键字可以用来访问本类的属性、方法、构造器
this.name
2.this用于区分当前类的属性和局部变量
3.访问成员方法的语法:this.方法名(参数列表);
class T{
//细节:访问成员方法的语法:this.方法名(参数列表);
public void f1()
{
System.out.println("f1()方法");
public void f2(){
System.out.println("f2()方法");
//调用本类的f1
//方法一:
f1();
//方法二:
this.f1();
}
}
}
4.访问构造器语法:this(参数列表);只能在构造器中使用(即只能在构造器中访问另外一个构造器) 必须放在构造器的第一条语句
class T
{
//细节:访问构造器语法:this(参数列表);
//只能在构造器中使用(即只能在构造器中访问另外一个构造器)
//注意:访问构造器语法:this(参数列表);必须放在构造器的第一条语句
public T(){
//这里去访问T(String name,int age)构造器
this("jack", 100);
System.out.println("T() 构造器");
}
public T(String name,int age){
System.out.println("T(String name, int age) 构造器");
}
}
5.this不能在类定义的外部使用,只能在类定义的方法中使用
class T{
//this关键字可以用来访问本类的属性
public void f3()
{
String name = "smith";
//传统方式
System.out.println("name=" + name + " num=" + num); //输出smith,会按照就近原则调用局部变量
//也可以使用this访问属性
System.out.println("name=" + this.name + " num=" + this.num); //直接调用类中的成员属性
}
}