成员方法注意事项和细节
形式参数列表
1. 一个方法可以有0个参数,也可以有多个参数,用逗号隔开
2. 可以是基本数据类型,也可以是引用数据类型
3. 调用带参数的方法时,对应参数列表传入相同类型或兼容类型
4. 方法定义时为形式参数,调用时传入的为实参,形参与实参类型一致或兼容,个数顺序必须一致
方法体不能再定义方法
方法调用
同一类的方法调用:直接调用
跨类中A类方法调用B类方法:需要通过对象名调用
(在A的方法中创建B类对象,再调用)
跨类的方法调用和访问修饰符有关
parameter 参数 row 行 column 列
基本数据类型传递的是值,形参的任何变化不影响实参
引用类型传递的是地址,可以通过形参影响实参
拷贝对象
public class Input{
public static void main(String args[]){
Person p = new Person();
p.name = "milan";
p.age = 100;
MyTools tools = new MyTools();
Person p2 = tools.copyPerson(p);
System.out.println("p的属性 age=" + p.age + " 名字" + p.name);
System.out.println("p2的属性 age=" + p2.age + " 名字" + p2.name);
}
}
class Person {
String name;
int age;
}
class MyTools {
public Person copyPerson(Person p) {
//创建一个新的对象
Person p2 = new Person();
p2.name = p.name;
p2.age = p.age;
return p2;
}
}
方法递归调用(recursion)
public class Input{
public static void main(String args[]){
T t1 = new T();
t1.test(4);
}
}
class T {
public void test(int n) {
if(n > 2) {
test(n - 1);
}
System.out.println("n=" + n);
}
}
factorial 阶乘
老鼠找路问题分析(开始有逻辑)
public class MiGong {
public static void main(String args[]) {
//地图
int map[][] = new int[8][7];
//0表示可以走 1表示障碍物
for(int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
for(int i = 0; i < 8; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1;
//输出当前的迷宫
System.out.println("========当前地图情况========");
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
//使用findWay给老鼠找路
T t1 = new T();
t1.findWay(map, 1, 1);
System.out.println("====找路的情况如下====");
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
}
class T {
//使用递归回溯方法解决问题
//i和j表示老鼠的位置
//因为是递归找路,map地图各值的含义!!!
//0表示可以走 1表示障碍物 2表示可以走 3表示走过,但走不通!!!
//当map[6][5]为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;
}
} else { //map[i][j] = 1,2,3
return false;
}
}
}
}
========当前地图情况========
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 1 0 0 0 1
1 1 1 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1
====找路的情况如下====
1 1 1 1 1 1 1
1 2 2 2 0 0 1
1 3 1 2 0 0 1
1 1 1 2 0 0 1
1 0 0 2 0 0 1
1 0 0 2 0 0 1
1 0 0 2 2 2 1
1 1 1 1 1 1 1
难点分析(我自己的最困难的地方): 由于使用boolean类型,所以返回只有真假,如果最后找到路了,那么就是根据最后一层的map[6][5] == 2返回的true一路返回到最开始的return true。最难的位置在于if ( findWay ( i, j ) ) 判断的真假,如果if中语句为false,那么就不会return,所以就不会执行return true进而执行下一个else if语句,知道内部的最后根据map[6][5]的位置返回true或者运行完成第一轮的迭代语句执行最后的else语句返回false为止。
汉诺塔代码:
public class HanNuoTa {
public static void main(String args[]) {
T t1 = new T();
t1.move(3, 'A', 'B', 'C');
}
}
class T {
public void move(int num, char a, char b, char c) {
if(num == 1) {
System.out.println(a + "->" + b);
} else {
move(num - 1, a, c, b);
System.out.println(a + "->" + b);
move(num - 1, c, b, a);
}
}
}
难点分析:比较抽象,根据递归思路,先确定1个的情况移动方法,为了加深理解,我们和视频课移动位置不同,把b作为初始移动位置,也就是最大的一块移动到b。然后根据递归,将上面所以当做一起移动。所以开始将num-1块移动到c处,借助b,然后将最大的块移动到b处,之后再将剩下的部分从c借助a移动到b处。代码便如上所示。最难点在于思路,不借助老师的思路自己很难想到这个方法,所以要多积累经验,找到递归规律。
八皇后问题还是自己想不出来。。。
网上扒的代码,看懂自己又“默写”了一遍
import java.util.Scanner;
public class EightQueen {
static int tol = 0, n;
static int C[];
static Scanner scanner = new Scanner(System.in);
public static void main(String args[]) {
n = scanner.nextInt();
C = new int[n];
for(int i = 0; i < n; i++) {
C[i] = 0;
}
search(0);
}
public static void search(int cur) {//当前层数
if(cur == n) {
tol++;
System.out.println("第" + tol + "种放法");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(C[i] == j) {
System.out.print("Q");
} else {
System.out.print("*");
}
}
System.out.println();
}
System.out.println();
} else {
for(int k = 0; k < n; k++) {
int flag = 1;
C[cur] = k;
for(int k1 = 0; k1 < cur; k1++) {
if(C[cur] == C[k1] || C[cur] - cur == C[k1] - k1 || C[cur] + cur == C[k1] + k1) {
flag = 0;
break;
}
}
if(flag == 1) {
search(cur + 1);
}
}
}
}
}
方法重载(Overload)(简单)
java允许一个类中,多个同名方法的存在,但要求形参列表不一致(类型、个数、顺序)
可变参数(简单)
java允许将同一类中多个同名同功能但参数个数不同的方法,封装成一个方法,就可以通过可变参数技术实现
访问修饰符 访问类型 方法名(数据类型... 形参名) {}
public int sum(int... nums)
1. int... 表示可变参数 类型为int 即可以接收多个int(0~多),也可以传递数组
2. 使用可变参数时 可当做数组来使用 即 nums 可当做数组
3. 可变参数可以和普通类型的参数一起放在形参列表,但可变参数要放在最后
4.最多只能出现一个可变参数
public class VarParameterExercise {
public static void main(String args[]) {
HspMethod hm = new HspMethod();
System.out.println(hm.showScore("milan", 90.1, 80.5));
}
}
class HspMethod {
public String showScore(String name, double... scores) {
double totalScore = 0;
for(int i = 0; i < scores.length; i++) {
totalScore += scores[i];
}
return name + "有" + scores.length + "门课成绩总分为" + totalScore;
}
}
作用域(Scope)
1. 在java编程中,主要的变量就是属性(成员变量)和局部变量
2. 局部变量一般是指定义在成员方法中的变量
3. java中作用域的分类
全局变量 :也就是属性,作用域为整个类体,定义时可以直接赋值
局部变量:除了属性之外的其他变量(还有代码块),作用域在定义它的代码块中
1. 全局变量可以不赋值,有默认值,局部变量必须赋值,没有默认值
2. 属性和局部变量可以重名,访问时遵循就近原则
3. 属性生命周期长,伴随对象创建而创建,伴随对象销毁而销毁
局部变量生命周期短,伴随它代码块的执行而创建,伴随代码块的结束而销毁(一次调用方法中)
4. 作用域范围不同:
全局变量(属性):可以在本类使用,或其他类使用->新建对应类的对象/形参调用
局部变量:只能在本类对应的方法中使用
5. 修饰符不同:
全局变量(属性)可以加修饰符
局部变量不可以加修饰符
构造器(构造方法Constructor)
[修饰符] 方法名(形参列表){方法体;}
1. 构造器的修饰符可以默认
2. 构造器没有返回值
3. 方法名和类型必须一样
4. 参数列表和成员方法一样的规则
5. 构造器调用由系统完成
6. 可以进行重载
7. 程序员没有定义构造器,系统自动生成给类一个默认无参构造器(也叫默认构造方法)
javap反编译查看:对class进行反编译(.class->.java)
8. 定义自己构造器后,无参构造器被覆盖,不能再使用无参构造器
除非显示的定义一下:即Person(){}
构造器是类的一种特殊方法,他的主要作用是完成对新对象的初始化
public class Constructor {
public static void main(String args[]) {
//new一个新对象时 用构造器指定这个对象的姓名和年龄
Person p1 = new Person("simth", 80);
System.out.println("p1的信息如下:");
System.out.println("p1对象的姓名=" + p1.name);
System.out.println("p1对象的年龄=" + p1.age);
}
}
class Person {
String name;
int age;
public Person(String pName, int pAge) {
//System.out.println("构造器被调用~");
name = pName;
age = pAge;
}
//构造器重载
public Person(String pName) {
name = pName;
}
}