Java基础-复习

Java基础

1. 概述

  1. java语言是面向对象的(oop)
  2. java语言是健壮的,java是请类型机制、一场处理,垃圾的自动收集机制。
  3. java是跨平台的,即一个编译好的class文件可以在多个系统下运行,这种特性成为跨平台
  4. java语言是解释性语言。

1.1 什么是JDK 、 JRE

  • JDK 的全程 (java开发工具包)

3. 变量

char的基本使用

​ char可以直接存放一个数字

4. 原码、反码、补码(重点

  1. 二进制的最高位是符号位: 0表示正数,1表示负数
  2. 正数的原码、反码、补码都一样(三码合一)
  3. 负数的反码 = 它的原码符号位不变,其它位数取反
  4. 负数的补码 = 他的反码 + 1 , 负数的反码 = 负数的补码 - 1
  5. 0的反码,补码都是0
  6. java没有无符号数,换言之,java中的数都是有符号的
  7. 在计算机运算的时候,都是以补码的方式来运算的
  8. 当我们看运算结果的时候,要看他们的原码。

5. 位运算符

java中有7个位运算符 (&、|、^、~、>> 、<< 、>>>)

他们分别是:

  • & : 按位与 : 两位全为 1 ,结果为 1 ,否则为0
  • | : 按位或 :两位有一个为1,结果为1 ,否则为0
  • ^ :按位异或 :两位一个为0,一个为1,结果为1,否则为0
  • ~ :按位取反 :0 -> 1 , 1 -> 0

为了简化过程,其中使用char 1个字节 来计算,

实例一:2&3

1. 先得到 2 的 原码   : 0000 0010
2. 因为计算机中运算的时候,都是以补码的方式来运算的,
		所以需要得到 2 的补码 , 又因为正数三码合一,所以
		2 的补码也是 2 的原码

3. 得到 3 的 原码 : 0000 0011
4. 理由同 2 ,补码:  0000 0011

5. 计算,因为两者中间的符号是 按位与,即 (两位全为 1 ,结果为 1 ,否则为0)
		所以,补码计算的结果为  0000 0010

6. 将计算的补码转换成对应的原码 
		因为二进制数的最高位(符号位是 0 ) 所以,根据正数三码合一,可以得到原码也是 0000 0010
		再将原码转换成十进制 , 得到 2 
7. 得到结果: 2&3 = 2

**实例二:~-2 = ? **

1. 得到 -2 的二进制数(原码) : 1000 0010
2. 得到 -2 的补码(原因 同4.7),因为符号位是1 ,表示负数,
		所以要想获得负数的补码,要先获得负数的反码,根据 4.3 的规则,
		获得反码为:  1111 1101
		再根据 【4.4】中补码的计算方法,得到补码 : 1111 1110
		
3. 算式前面的符号是按位取反,根据对应的规则,得到计算之后的补码为: 0000 0001 
4. 要想求出真正的值,将补码转换成原码,因为符号位是0(正数),所以 原码 = 0000 0001
5. 得到结果:~-2 = 1

实例三:~2 = ?

1. 得到 2 的 原码 : 0000 0010
2. 得到 2 的 补码 : 0000 0010

3. 算式前面的符号 是 按位取反,根据对应的规则,得到补码 : 1111 1101
4. 因为上一步计算出来的 是负数,要想将负数的补码转换成原码,需要先将负数的补码 转换成 反码,
			根据 (负数的反码 = 负数的补码 - 1) 规则 , 反码 : 1111 1100

5. 根据 (负数的反码 = 它的原码符号位不变,其它位数取反) , 可以得到反码的原码 : 1000 0011 =>  -3
6. 结果为: ~2 = -3

实例四:2|3 = ?

1. 得到 2 的 原码 : 0000 0010
2. 得到 2 的 补码 : 0000 0010 

3. 得到 3 的 原码 : 0000 0011
4. 得到 3 的 补码 : 0000 0011

5. 计算 ,位运算符为 按位或 ,根据计算规则, 得到 0000 0011
6. 原码: 0000 0011 =>  3

7. 解雇:2|3 = 3

实例五:2^3 = ?

1. 得到 2 的 原码 : 0000 0010
2. 得到 2 的 补码 : 0000 0010 

3. 得到 3 的 原码 : 0000 0011
4. 得到 3 的 补码 : 0000 0011

5. 计算,位运算符为 按位异或(^), 根据计算规则,得到 0000 0001
6. 原码: 0000 0001 => 1 

7. 结果:2^3 = 1

位运算符 : >> (算数右移) ,<< (算数左移) , >>> (逻辑右移)

  • 算数右移 >> : 低位溢出,符号位不变,并用符号位补溢出的高位 。相当于 除以 2 的 n 次方 ( 1 >> 2 ==> 1 / 2 / 2 = 0)
  • 算数左移 << : 符号位不变,低位补0 。 相当于 乘以 2 的n 次方 ( 1 << 2 ==> 1 * 2 * 2 = 4)
  • 逻辑右移 >>> : 也叫做无符号右移, 运算规则是:低位溢出,高位补0

6. 打印金字塔

编程思想:化繁为简,先死后活

import java.util.Scanner;
public class TestFor{
	public static void main(String[] args){
		/**
		 * 打印出 金字塔
		 *      *        1 层: 1 = 2 * 1 - 1   空格:5 - 1 = 4
		 *     ***       2 层: 3 = 2 * 2 - 1        5 - 2 = 3
		 *    *****      3 层: 5 = 2 * 3 - 1        5 - 3 = 2
		 *   *******     4 层: 7 = 2 * 4 - 1        5 - 4 = 1
		 *  *********    5 层: 9 = 2 * 5 - 1        5 - 5 = 0
		 * 
		 * 编程思想:化繁为简,先死后活
		 * 
		 * 先打印出 
		 *   *******
		 *   *******
		 *   *******
		 *   *******
		 *   *******
		 * 再打印
		 *  * 
		 *  ** 
		 *  ***
		 *  ****
		 *  *****
		 *  ******
		 */	

		Scanner myScanner = new Scanner(System.in);
		System.out.println("请输入需要金字塔的层数");
		int total = myScanner.nextInt();

		System.out.println("请输入金字塔的材料(字符)");
		char c = myScanner.next().charAt(0);

		System.out.println("正在建造中,请稍后...");
		
		for (int i = 1; i <= total ; i++ ) {

			//打印空格
			for (int k = 1; k <= total - i ; k++) {
				System.out.print(" ");
			}

			for (int j = 1;j <= 2 * i - 1 ;j++ ) {
				System.out.print(c);
			}
			System.out.println();
		}
	}
}

image-20210830191226072

6.1 打印空心金字塔

import java.util.Scanner;
public class TestFor{
	public static void main(String[] args){
		/**
		 * 打印出 金字塔
		 *      *        1 层: 1 = 2 * 1 - 1   空格:5 - 1 = 4
		 *     ***       2 层: 3 = 2 * 2 - 1        5 - 2 = 3
		 *    *****      3 层: 5 = 2 * 3 - 1        5 - 3 = 2
		 *   *******     4 层: 7 = 2 * 4 - 1        5 - 4 = 1
		 *  *********    5 层: 9 = 2 * 5 - 1        5 - 5 = 0
		 * 
		 * 编程思想:化繁为简,先死后活
		 * 
		 * 先打印出 
		 *   *******
		 *   *******
		 *   *******
		 *   *******
		 *   *******
		 * 再打印
		 *  * 
		 *  ** 
		 *  ***
		 *  ****
		 *  *****
		 *  ******
		 */	

		Scanner myScanner = new Scanner(System.in);
		System.out.println("请输入需要金字塔的层数");
		int total = myScanner.nextInt();

		System.out.println("请输入金字塔的材料(字符)");
		char c = myScanner.next().charAt(0);

		System.out.println("正在建造中,请稍后...");
		
		for (int i = 1; i <= total ; i++ ) {

			//打印空格
			for (int k = 1; k <= total - i ; k++) {
				System.out.print(" ");
			}

			for (int j = 1;j <= 2 * i - 1 ;j++ ) {
				if (j == 1 || j == 2 * i - 1 || i == total) {
					System.out.print(c);					
				}else{
					System.out.print(" ");
				}
				
			}
			System.out.println();
		}
	}
}

image-20210830191201158

6.2 打印菱形

public class TestFor2{
	/*
		打印菱形
		     *
		    ***
		   *****
		    ***
		     *
	*/
	public static void main(String[] args) {
		int total = 10;

		for (int i = 1; i <= total ; i++ ) {
			for (int k = 1; k <= total - i ; k++ ) {
				System.out.print(" ");
			}

			for (int j = 1;j <= 2 * i - 1 ; j ++ ) {
				System.out.print("*");
			}

			System.out.println();

		}
		for (int m = total - 1; m >= 0 ; m-- ) {
			for (int k = 1; k <= total - m ; k++ ) {
				System.out.print(" ");
			}

			for (int j = 1;j <= 2 * m - 1 ; j ++ ) {
				System.out.print("*");
			}
			System.out.println();

		}
	}
}

image-20210830191106513

6.3 打印空心菱形

public class TestFor2{
	/*
		打印菱形
		     *
		    ***
		   *****
		    ***
		     *
	*/
	public static void main(String[] args) {
		int total = 10;

		for (int i = 1; i <= total ; i++ ) {
			for (int k = 1; k <= total - i ; k++ ) {
				System.out.print(" ");
			}

			for (int j = 1;j <= 2 * i - 1 ; j ++ ) {
				if (j == 1 || j == 2 * i - 1) {
					System.out.print("*");
				}else{
					System.out.print(" ");
				}
				
			}

			System.out.println();

		}
		for (int m = total - 1; m >= 0 ; m-- ) {
			for (int k = 1; k <= total - m ; k++ ) {
				System.out.print(" ");
			}

			for (int j = 1;j <= 2 * m - 1 ; j ++ ) {
				if (j == 1 || j == 2 * m - 1) {
					System.out.print("*");
				}else{
					System.out.print(" ");
				}
			}
			System.out.println();

		}

	}
}

image-20210830191036886

7. 数组

7.1 数组引用内存分析

int[] arr = {10,20,30};
int[] arr2 = arr;

image-20210827213714610

7.2 拷贝数组内存分析

要求,重新开辟一个内存空间

image-20210827223640772

7.3 数组扩容

public class ArrayDemo{
	public static void main(String[] args) {
		/*
			数组扩容
		*/
		int[] arr = {10,20,30};
		//元素扩容,依次将元素拷贝到新的元素中
		int[] arrNew = new int[arr.length + 1];

		for(int i = 0;i < arr.length ; i++){
			arrNew[i] = arr[i];
		}

		//将最后一个元素放进新的元素中
		arrNew[arrNew.length - 1] = 4;

		//让 arr 指向 arrNew
		arr = arrNew;

		System.out.println("======arr======");
		for(int i = 0;i < arr.length ; i++){
			System.out.print(arr[i] + "\t");
		}

	}
}

7.4 冒泡排序

冒泡排序:类似海水中的气泡,大的气泡逐渐上升。

**image-20210828121245245**

代码实现

public class ArrayDemo3{
	public static void main(String[] args) {
		int[] arr = {24,69,80,57,13};

		int tmp = 0;
		for (int i = 0; i < arr.length - 1 ;i++ ) {
			for (int j = 0; j < arr.length - i - 1 ; j++ ) {
				if (arr[j] > arr[j + 1]) {
					tmp = arr[j + 1];
					arr[j+1] = arr[j];
					arr[j] = tmp;					
				}
			}
			
		}

		for (int i = 0;i < arr.length ;i ++ ) {
			System.out.println(arr[i]);
		}
	}
}

7.5 查找


  1. 顺序查找

顺序查找:从前往后,逐渐比较,如果找到了,直接返回,否则,继续查找。

  1. 二分查找

7.5 二维数组

一位数组的每一个元素,都是一个一位数组,这样的数组就是二维数组。

定义: int [][] arr = {{1,2,3},{2,3,4},{4,4,5}};

打印二维数组

public class TwoDimensionalArray01{
	public static void main(String[] args) {
		int[][] arr = {{1,1,1,1},{2,2,2,2},{3,3,2,3},{4,4,4,1}};

		//输出二维图形
		for (int i = 0; i < arr.length ; i++ ) {
			for (int j = 0; j < arr[i].length ; j++ ) {
				System.out.print(arr[i][j] + "\t");
			}
			System.out.println();
		}
	}
}

二维数组内存分析

image-20210828125632423

杨辉三角

1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

类似这样的三角形叫做杨辉三角

分析:

  • 每一行的第一个和最后一个元素都是1

  • 每一行的元素个数都等于行数

  • 每一行中间的数等于 上一行当前位置的元素 和 上一行当前位置前一个位置的元素 和

    arr[i][j] = arr[i-1][j-1] + arr[i-1][j]

代码实现:

public class TwoDimensionalArray01{
	public static void main(String[] args) {
		
		int[][] arr = new int[10][];
		for (int i = 0;i < arr.length ;i++) {
			//开辟空间
			arr[i] = new int[i + 1];

			
			for(int j = 0;j < arr[i].length ; j++){
				if (j == 0 || j == arr[i].length - 1) {
					arr[i][j] = 1;//首尾元素填充1
				}else{
					//填充其他元素
					arr[i][j] = arr[i-1][j] + arr[i - 1][j - 1];
				}
			}

		}

		for (int i = 0;i < arr.length ;i++) {
			for(int j = 0;j < arr[i].length ; j++){
				System.out.print(arr[i][j] + "\t");
			}
			System.out.println();
		}

	}
}

image-20210828133541351

8 面向对象编程

类与对象:OOP

  • 类就是一种数据类型
  • 对象就是一个具体的实例

类:可以有属性和行为,是将一类事物抽象出形成的一个模型,例如:猫有 姓名,颜色,雌雄,年龄,行为有:吃,睡,玩

类和对象的区别和联系

  • 类是抽象的,概念的,代表一类事物,比如人类,猫类…,即它是数据类型
  • 对象是具体的,实际的,代表一个具体的事物,即是实例
  • 类是对象的模板,对象是类的一个个体,对应一个实例

8.1 对象在内存中的存在形式

image-20210828195615969

8.2 对象

对象就是堆中开辟的内存空间,而对象名就是对象的引用,它是指向对象。

例子:image-20210828201509408是一个真实的人,他可以叫小明,也可以叫小王,(小王、小明都是对象的引用),真实的对象是人

8.3 Java内存结构分析

  1. 栈: 一般存放基本数据类型(局部变量)
  2. 堆: 一般对象(Cat cat , 数组等)
  3. 方法区: 常量池(常亮,比如字符串),类加载信息

8.4 Java创建对象的流程简单分析

Person p = new Person();
p.name = "jack";
p.age = 10;
  • 先在方法区中加载Person类的信息(属性和方法信息,只会加载一次)
  • 在堆中分配空间,进行默认初始化(看规则)
  • 把地址赋给p , p就指向对象
  • 进行指定初始化,比如 p.name = “jack”; p.age = 10;

8.5 方法(成员方法)

语法

public void speek(){
		System.out.println("我是一个好人");
}

public void speek2(String name){
		System.out.println(name + "说:我是一个好人");
}

权限修饰符 返回值(数据类型) 方法名称(「形参列表」){
		方法体
}

方法的调用机制原理

image-20210828213637221

分析

方法调用分析

  1. 在执行main方法中,入栈一个main方法空间(开辟一个空间)

  2. 在main空间中 创建对象

(1)先在方法区中加载Person类信息

(2)在堆中开辟一个空间,进行默认初始化,并将地址赋给 p

(3) 调用getSum方法。重新在栈中开辟一个getSum方法的空间。在getSum空间中,进行计算,并返回计算结果。将计算结果赋值给res变量。执行完毕之后。销毁getSum栈空间。

(4)输出 变量res 的值

(5) main方法执行完毕。销毁main方法空间。程序退出


注意:

  • 对于基本的数据类型,传递的是值(值传递),形参的任何改变不影响实参
  • 引用类型传递的是地址(传递的是值,但是指向的是地址),因此形参的改变也会导致实参的改变

8.6 方法的递归调用

简单来说:递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题,同时可以让代码变得更加简洁

递归举例:

  1. 打印问题

    public class TwoDimensionalArray01{
    
    	public static void main(String[] args) {
    
    		int n = 4;
    
    		P r = new P();
    		r.print(n);
    
    	}
    }
    
    class P{
    	public void print(int n){
    		if (n > 2) {
    			print(n - 1);
    		}
    		System.out.println(" n = " + n);
    	}
    }
    

    执行结果:

    image-20210829102731406

内存分析

image-20210829102934232

递归重要规则

  1. 执行一个方法时,就创建一个新的受保护的独立空间
  2. 方法的局部变量是独立的,不会互相影响,不如n变量
  3. 如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据。
  4. 递归必须向退出递归的条件逼近,否则就是无限递归,出现stackOverflowError , 死龟
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕。

递归练习:

  1. 求斐波那契数数,输入一个整数n ,求得其所在位置的斐波那契数, 斐波那契数列 为: 1,1,2,3,5,8……

    (1)分析:

    • 第一个 数 为 1

    • 第二个数 为 1

    • 第三个数 为 1 + 1 (为前两个数相加)

      代码

      //求斐波那契数 
      	public int  test1(int n){
      		if (n >= 1) {
      			if (n == 1 || n == 2) {
      				return 1;
      			}else{
      				return test1(n - 1) + test1(n - 2);
      			}
      		}else {
      			System.out.println("输入的数必须大于 1");
      			return -1;
      		}
      	}
      
  2. 猴子吃桃问题:猴子每天吃桃吃桃子总数的一半还多吃一个,第十天还剩一个桃子,求第一天总共有多少个桃子?

分析

  • 第十天 桃子 1 个
  • 第九天 桃子 (第十天桃子数量 + 1)* 2 = 4
  • 第八天 桃子:(第九天桃子数量 + 1)* 2 =10

代码

public int peach(int day){
  if(day == 10){ //第十天,桃子剩一个
    return 1;
  }else if (day >= 1 && day <= 9){
    return (peach(day + 1) + 1) * 2; //猴子吃桃的规则
  }else{
    System.out.println("day 在1 ~ 10 之间");
    return -1;
  }
}
  1. 老鼠找迷宫问题
package com.lyl.day05;

public class Migong{

    public static void main(String[] args) {
        int row = 10; //行
        int col = 10; //列
        int obstacleNum = 10; //障碍物数量

        Migong m = new Migong();

        int[][] map = m.createMiGong(row,col,obstacleNum);
        m.findWay(map,1,1);
        System.out.println("小老鼠走迷宫情况");
        m.print(map);




    }

    //创建迷宫  row 行  col 列  obstacleNum 障碍物数量
    public int[][] createMiGong(int row, int col,int obstacleNum){
        int[][] map = new int[row][col];
        for (int i = 0;i < row ;i++ ) {
            map[i][0] = 1;
            map[i][col - 1] = 1;
        }

        for (int i = 0;i < col ;i++ ) {
            map[0][i] = 1;
            map[row - 1][i] = 1;
        }

        System.out.println("生成迷宫");
        print(map);
        System.out.println("生成"+obstacleNum+"障碍物");
        createObstacle(map,obstacleNum);
        print(map);

        return map;
    }

    //打印迷宫
    public void print(int[][] map){
        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();
        }
    }

    //生成随机障碍物
    public void createObstacle(int[][] map,int obstacleNum){
        if (obstacleNum <= 0) {
            return;
        }else{
            int row = map.length - 2;
            int col = map[0].length -2;
            int tmpRow;
            int tmpCol;
            do{
                tmpRow = (int)(Math.random() * (row-1)) + 1;
                tmpCol = (int)(Math.random() * (col-1)) + 1;

                System.out.println("tmpRow = " + tmpRow + " ; tmpCol = " + tmpCol);
                if (map[tmpRow][tmpCol] == 0) {
                    map[tmpRow][tmpCol] = 1;
                    break;
                }
            }while(map[tmpRow][tmpCol] == 1);
            obstacleNum--;
            createObstacle(map,obstacleNum);
        }

    }

    /*
        迷宫找路
        1. 明确数字含义
             0: 可以走的, 1:障碍物  2:走过的  3:走过但不通
        2. 起点和终点位置
            起点:map[1][1]  终点:map[row-1][col-1]
        3. 执行策略
             下 -> 右 -> 上 -> 左
        4. 分析:
            (1): 先判断是否到达了终点位置,返回true
            (2): 如果没到终点位置
                1. 判断当前位置是否可以走
                    1. 如果不能走,退出
                    2. 如果可以走。
                        假定可以走,按照执行策略,可以走的返回true,否则返回false  并将当前位置置为 3;
     */
    public boolean findWay(int[][] map,int row,int col){
        //终点位置,默认有右下角
        if (map[map.length-2][map[0].length-2] == 2){
            //到达终点位置
            return true;
        }else {
            //没到达终点

            //可以走
            if (map[row][col] == 0){

                //假定可以走通
                map[row][col] = 2;

                //使用执行策略,看是否真的可以走通
                if (findWay(map, row + 1, col)){ //下
                    return true;
                }else if (findWay(map,row,col + 1)){//右
                    return true;
                }else if (findWay(map,row - 1,col)){//上
                    return true;
                }else if (findWay(map,row,col - 1)){//左
                    return true;
                }else {
                    //否则,表示走过,但走不通
                    map[row][col] = 3;
                    return false;
                }
            }else{
                //1:障碍物  2:走过的  3:走过但不通 ,这三种情况都不用走了
                return false;
            }

        }
    }
}

注意:测试回溯

  1. 汉诺塔问题

    image-20210829165655757

汉诺塔

package com.lyl.day05;

//汉诺塔问题
public class HannuoTa {
    public static void main(String[] args) {
        move(5,'A','B','C');
    }

    /*
        使用递归思想
            num : 层数
            a : A塔
            b : B塔
            c : C塔

        先不要考虑多层,只考虑两层就行了
     */
    public static void move(int num, char a , char b , char c ){
        if (num == 1){
            //如果只有一层,直接将A塔上面的圆盘移动到C塔上面
            System.out.println( a + " --> " + c);
        }else {
            //先移动上面所有盘到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~3 个圆盘的解决方案,圆盘个数越多,解决起来就越棘手。这种情况下,我们可以借助分治思想,将移动多个圆盘的大问题分割成多个移动少量圆盘的小问题。

为了便于讲清楚问题的解决过程,我们将 3 个柱子依次命名为起始柱、辅助柱及目标柱。起始柱指的是初始状态下所有圆盘所在的柱子,目标柱指的是最终放置所有圆盘的柱子,剩下的一个称为辅助柱。

首先,如果初始状态下的起始柱上仅有 1 个圆盘,我们可以很轻松地将圆盘从起始柱直接移到目标柱。如果初始状态下起始柱上有 2 个圆盘,则整个移动操作需执行如下几步:

  1. 将起始柱顶部较小的圆盘移动到辅助柱;
  2. 将起始柱上较大的圆盘移动到目标柱;
  3. 最后,将辅助柱上较小的圆盘移动到目标柱。

图片

实际上,移动 2 个圆盘的过程也同样适用于移动更多的圆盘。对于初始状态下起始柱包含 2 个以上圆盘的情况(假设圆盘个数为 n),移动过程可以遵循以下步骤:

  1. 将起始柱上的 n-1 个圆盘移动到辅助柱;
  2. 将起始柱上最大的圆盘移动到目标柱;
  3. 将辅助柱中的 n-1个圆盘移动到目标柱。

对于移动 n-1 个圆盘的情况,仍可以遵循以上的移动过程。如此,我们就将移动 n 个圆盘的问题划分为移动 n-1 个圆盘的问题,此问题还可以进行更细致的划分。


  1. 八皇后问题

    八皇后问题英文Eight queens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。

    问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

    经典算法之八皇后问题

8.7 方法的重载

在同一个类中,可以允许同名方法存在,但要求形参列表不一致!

注意事项

  • 方法的重载,方法名称一定相同
  • 形参列表,必须不同(形参类型、个数、顺序不一样,必须有其中一个),形参名称不重要
  • 返回类型不是构成方法的重载的条件。

8.8 可变参数

基本概念:java允许将同一个类中多个同名的同功能但参数个数不同的方法,封装成一个方法,就可以通过可变参数实现

基本语法:访问修饰符 返回类型 方法名(数据类型… 形参名){}

在方法中,可以将可变参数当成数组来使用

public int sum(int... nums){
  int res = 0;
  for(int i = 0 ; i < nums.length; i++){
    res += nums[i];
  }
  return res;
}

注意事项

  • 可变参数可以是0个或者任意多个

  • 可变参数的实参可以为数组

  • 可变的参数的本质就是数组

  • 可变参数可以和其他形参一块使用,但必须保证可变参数在形参列表最后

  • 在一个形参列表中最多只能出现一个可变参数

成员变量必须赋默认值,全局变量可以不赋值,因为有默认值

属性和局部变量是可以重名的,访问的时候遵循就近原则。

属性可以添加修饰符,局部变量不可以添加修饰符

8.9 构造器

  1. 基本语法

    [修饰符] 方法名(形参列表){
    	方法体;
    }
    
  2. 注意事项

    • 构造器的修饰符可以默认,也可以是public protected private
    • 构造器没有返回值
    • 方法名 必须和类名一样
    • 参数列表 和成员方法一样的规则
    • 构造器的调用, 由系统完成。

构造器是类的一种特殊的方法,主要作用,是完成新对象的初始化

构造器,完成对象的初始化,并不是创建新对象。

8.10 对象的创建流程分析

image-20210829220157943

  • 在调用构造器时,对象现在堆中完成了对象的默认初始化,之后再使用构造器完成初始化。

8.11 this关键字

java虚拟机给每个对象分配this,this代表当前对象。

可以使用hashCode()方法来查看两个对象是否是同一个对象。

简单的来说,哪个对象,this就指代哪个对象

注意事项

  1. this关键字可以用来访问奔雷的属性、方法、构造器

  2. this用于区分当前类的属性和局部变量

  3. 访问成员方法的语法:this.方法名(参数列表);

  4. 访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另一个构造器

    • 在使用this(参数列表)的时候,只能放在构造方法的第一行
  5. this不能再类定义的外部使用,只能在类定义的方法中使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值