JAVA

java

java 的概述:

  • java 是一种高级语言,可以编写跨平台应用软件,完全面向对象的程序设计语言,java语言简单易用,安全可靠,主要面向 Internet 编程

  • java 划分为三个技术平台,它们分别为 JavaSE( java Platform Standard Edition )标椎版 ,JavaEE( Java Platform Enterprise Edition )企业版 ,JavaME( java Platform Micro Edition )小型版。

1,java 语言的特点

  • 简单性 : java 不使用 C++ 中的运算符重裁,多重继承等概念,特别是 Java 语言不使用指针 而使用引用,并提供自动的垃圾回收机制

  • 面向对象性 :是一种纯粹的面向对象程序设计语言

  • 安全性 :一切对内存的访问都必须通过对象的实例变量来实现,从而更安全

  • 跨平台性 :可运行多个平台,也就是说同一段程序既能在 Windows 上运行,也能在 Linux 上运行

  • 支持多线性 :所谓多线程可以简单理解为程序中有多个任务可以并发执行,这样就可以在很大程度上提高程序的执行效率

2,JDK 的使用

  • JDK 是 java 的一套开发环境,简称( Java Development Kit),它是整个 java 的核心,其中包括 Java 编译器,Java 运行工具,Java 文档生成工具,Java 打包工具等。
  • JRE 是 java 的运行环境,JDK 自带 JRE

Java 的基本语法

1,Java中的程序代码可分为 结构定义语句功能执行语句

  • Java中的程序代码可分为 结构定义语句功能执行语句 ,其中,结构定义语句用于声明一个类和方法,功能执行语句用于实现具体的功能。每条功能执行语句的最后都必须用分号(;)结束
System.out.println("这是第一个java程序");

2,类 的关键字为 class

3,在定义标识时应该遵循的规则

  1. 包名所有字母一律小写
  2. 类名和接口名每一个单词的首字母都要大写
  3. 常量名所有字母都大写,单词之间用下划线连接
  4. 变量名和方法名的第一个单词首字母小写,从第二个单词开始每个单词的首字母大写

4,Java 中的常量 :

  • 常量就是在程序中固定不变的值,是不能改变的数据。

  • 在Java中,常量包括整型常量,浮点型常量,布尔常量,字符常量等。

4.1,整形常量
  • 整形常量是整数类型的数据,它的表现方式有四种 :二进制,八进制,十进制,十六进制,
4.2,浮点数常量
  • 浮点数常量就是数学中的小数,它分为 float 单精度浮点和 double 双精度浮点型,其中,单精度浮点数后面以 F 或 f 结尾,而双精度浮点数则以 D 或 d 结尾,在使用浮点型时不加后缀,则以默认为 double 双精度浮点数。
4.3,字符型( char )
  • 字符型( char ),一个字符常量要用一对英文半角格式的单引号(’’)引起来,它可以是英文字母,数字,标点符号,以及由转移序列来表示的特殊字符,例如:
'a'  '1'  '&'  '\r'  '\u0000'
  • ‘\u0000’ 表示一个空白字符,即单引号之间没有字符
4.4,字符串常量
  • 字符串常量,一个字符串常量要用一对英文半角格式的双引号 ("")引起来。
4.5,布尔常量( boolean )
  • 布尔常量( boolean )即布尔型的两个值 true 和 false ,区别一个事物的真假
4.6null 常量
  • null 常量只有一个值 null ,表示对象的引用为空。

Java中的变量

  • 变量的数据类型** 在定义变量时必须声明变量的类型,在为变量赋值时必须赋予和变量同一种类型的值,否则程序会报错

1,整型类型变量 :

  • 字节型( byte ),占用空间1个字节( 8位 )
  • 短整型( short ),占用空间2个字节( 16位 )
  • 整型( int ),占用空间4个字节( 32位 )
  • 长整型( long ),占用空间8个字节( 64位 )

2,浮点数类型变量 :

  • 单精度浮点数( float ),占用空间4个字节( 32位 )
  • 双精度浮点数( double ),占用空间8个字节( 64位 )

3,字符型变量 :

  • char 类型,占用2个字节( 16位 )

4,布尔类型变量 :

  • 用 boolean 表示,该类型的变量只有两个值,即 ture 和 false

5,变量的类型转换

当把一种数据类型的值赋予给另一种数据类型的变量,需要进行数据类型转换,数据类型转换可分为两种:自动类型转换 和 强制类型转换

5.1,自动类型转换:
  • 指的是两个数据类型在转换的过程中不需要显式的进行声明
  1. 是两个数据类型彼此兼容

  2. 是目标类型的取值范围大于原类型的取值范围

    byte b = 3;
    int  x = b;  // 程序把 byte 类型的变量 b 转换成了 int 类型。无需特殊声明
    
5.2,强制类型转换:
  • 指的是两种数据类型之间的转换需要进行显式的声明
  1. 格式 :

    目标类型  变量 = (目标类型)值
    

6,变量的作用域

  • 在程序中,变量一定会被定义在某一对大括号中,该大括号所包含的代码区域便是这个变量的作用域
public static void main(String[] args){
        int x = 4;
        {
        int y = 9;
        ......
        }
        .....
}

Java中的运算符**

  1. 算术运算符

选择结构语句

1,if 条件语句 :

  • if 语句,if… else 语句,if…else if…else 语句
1.1,if 语句 :
  • 判断条件是一个布尔值,当值为 true 时,才会执行{}中的语句
 if (判断条件){
          代码块
      }
案例 :
      public class Example07{
           public static void main(String[] args){
                   int x=5;
                   if(x<10){
                       x++;
                   }
                   System.out.println("x="+x);
           }
      }
1.2,if…else语句
  if (判断条件){
          执行语句1
              ...
      }else{
          执行语句2
              ...
      }
      案例 :判断奇偶的程序
      public class Example08{
           public static void main(String[] args){
               	int num = 19;
               if(num%2==0){
                   System.out.println("num是一个偶数")
               }else{
                   System.out.println("num是一个奇数")
               }
           }
      }
        //三元运算,它和if-else语句类似,其语法格式:
        //判断条件 ? 表达式 1 : 表达式 2
        int x = 0;
        int y = 1;
        int max;
        if (x>y){
            max = x;
        } else {
            max = y;
        }
        //等价于
        int max = x > y ? x : y;
1.3,if…else if…else 语句
if(判断条件 1 ){
            执行语句 1 
        } else if (判断条件 2 ){
            执行语句 2 
        }
		...
        else if (判断条件 n ){
            执行语句 n 
        } else {
            执行语句 n+1
        }
        案例:对学生考试成绩等价划分
           public class Example09 {
                public static void main(String[] args) {
                    int grade = 75; // 定义学生成绩
                    if (grade > 80) {
                        // 满足条件 grade > 80
                        System.out.println("该成绩的等级为优");
                    } else if (grade > 70) {
                        // 不满足条件 grade > 80 ,但满足条件 grade > 70
                        System.out.println("该成绩的等级为良");
                    } else if (grade > 60) {
                        // 不满足条件 grade > 70 ,但满足条件 grade > 60
                        System.out.println("该成绩的等级为中");
                    } else {
                        // 不满足条件 grade > 60
                        System.out.println("该成绩的等级为差");
                    }
                }
            }

2,switch:

  • switch语句也是一种很常见的选择语句。和if条件语句不同,它只能针对某个表达式的值做出判断,从而决定执行哪一段代码。在switch语句中,使用switch关键字来描述一个表达式,使用case关键字来描述和表达式结果比较的目标值,当表达式的值和某个目标值匹配时,会执行对应case下的语句,switch语句的基本语法
switch (表达式){
	case 目标值 1 :
		执行语句 1
		break;
	case 目标值 1 :
		执行语句 1
		break;
	...
	case 目标值 1 :
		执行语句 1
		break;
	default:
		执行语句 n+1
		break}

//例如:使用数字1~7表示周一到周日,如果想根据某个输入的数字输出中文格式的星期值

switch (用于表示星期的数字) {
	case 1 :
		输入星期一;
		break;
	case 2 :
		输入星期二;
		break;
	case 3 :
		输入星期三;
		break;
	case 4 :
		输入星期四;
		break;
	case 5 :
		输入星期五;
		break;
	case 6 :
		输入星期六;
		break;
	case 7 :
		输入星期天;
		break;
}
  • 注意 : 在switch语句中的表达式只能是byte、short、char、int、枚举(JDK1.5引入的)、String类型(JDK1.7引入的)的值,如果传入其他值,程序会报错。
//案例 : 数字来输出中文格式的星期。

public class Example10 {
public static void main(String[] args) {
int week = 8;
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期天");
break;
default:
System.out.println("输入的数字不正确...");
break;
}
}
 }
  • 在使用switch语句的过程中,如果多个case条件后面的执行语句是一样的,则该执行语句只需书写一次即可。
    例如,要判断一周中的某一天是否为工作日,同样使用数字1~7来表示星期一到星期天,当输入的数字为1、2、3、4、5时就视为工作日,否则就视为休息日。
public class Example10 {
	public static void main(String[] args) {
		int week = 8;
		switch (week) {
		case 1:
			System.out.println("星期一");
			break;
		case 2:
			System.out.println("星期二");
			break;
		case 3:
			System.out.println("星期三");
			break;
		case 4:
			System.out.println("星期四");
			break;
        case 5:
            System.out.println("星期五");
            break;
        case 6:
            System.out.println("星期六");
            break;
        case 7:
            System.out.println("星期天");
            break;
        default:
            System.out.println("输入的数字不正确...");
            break;
                }
            }
            }

循环结构语句 :

1,while 循环语句

while(循环条件){
	执行语句
	....
}
//案例 :
int i = 1;
while (i <= 100){
	System.out.println("i =" + i);
	i++;
}

2,do…while 循环语句

do {
	执行语句
	...
}while(循环条件);
//案例 :
int i = i;
do{
    System.out.println("i =" + i);
    i++;
}while(i <= 100);

3,for 循环语句:

  • for 循环语句:{}中的执行语句为循环体
for (初始化表达式;循环条件;操作表达式){
	执行语句
	...
}
  • 如果用 1 表示初始化表达式、 2 表示循环条件、3 表示操作表达式、4 表示循环体,则for循环的执行流程为

    for (1;2;3) {
    	4
    }
    第一步,执行 1 
    第二步,执行 2 如果判断结果为 true ,执行第三步,如果判断为 false ,执行第五步
    第三步,执行 4 
    第四步,执行 3 ,然后重复执行第三步
    第五步,退出循环
    
  • 案例 : 对自然数1~4进行求和

    public class Example14 {
    	public static void main(String[] args) {
    		int sum = 0; // 定义变量sum,用于记住累加的和
    		for (int i = 1; i <= 4; i++) { // i的值会在1~4之间变化
    			sum += i; // 实现sum与i的累加
    		}
    		System.out.println("sum = " + sum); // 打印累加的和
    	}
    }
    

4,嵌套循环 :

  • 嵌套循环 : 嵌套循环是指在一个循环语句的循环体中再定义一个循环语句的语法结构。
for (初始化表达式;循环条件;操作表达式){
	...
for (初始化表达式;循环条件;操作表达式){
         执行语句
      ...
     }
  ...
}
//案例 : 使用“*”打印直角三角形
public class Example15 {
	public static void main(String[] args) {
		int i, j; // 定义两个循环变量
		for (i = 1; i <= 9; i++) { // 外层循环
			for (j = 1; j <= i; j++) { // 内层循环
				System.out.print("*"); // 打印*
			}
			System.out.print("\n"); // 换行
		}
	}
}

5,跳转语句(break,continue)

5.1,break语句:

break语句:用在switch条件语句和循环语句中,它的作用是终止某个case和跳出当前循环结构语句,执行后面的代码。

5.2,continue语句:
  • continue语句:用在循环语句中,它的作用是终止本次循环,执行下一次循环
//案例 : break作用
public class Example16 {
	public static void main(String[] args) {
		int x = 1; // 定义变量x,初始值为1
		while (x <= 4) { // 循环条件
			System.out.println("x = " + x); // 条件成立,打印x的值
			if (x == 3) {
				break;
			}
			x++; // x进行自增
		}
	}
}
//案例 : 当break语句出现在嵌套循环的内层时,它只能跳出内层循环,如果想跳出外层循环,则需要对外层循环添加标记。
public class Example17 {
	public static void main(String[] args) {
		int i, j; // 定义两个循环变量
		itcast: for (i = 1; i <= 9; i++) { // 外层循环
			for (j = 1; j <= i; j++) { // 内层循环
				if (i > 4) { // 判断i的值是否大于4
					break itcast; // 跳出外层循环
				}
				System.out.print("*"); // 打印*
			}
		System.out.print("\n"); // 换行
		}
}
}

//案例 : continue作用,奇数之和
public class Example18 {
	public static void main(String[] args) {
		int sum = 0; // 定义变量sum,用于记住和
		for (int i = 1; i <= 100; i++) {
			if (i % 2 == 0) { // i是一个偶数,不累加
				continue; // 结束本次循环
			}
			sum += i; // 实现sum和i的累加
		}
		System.out.println("sum = " + sum);
	}
}

5.3,猜字游戏
import java.util.Random;
import java.util.Scanner;
/**
 * 猜数字游戏
 */
public class GuessNumber {
	public static void main(String[] args) {
		// 1.通过Random类中的nextInt(int n) 方法,生成一个0-9之间的随机数
		int randomNumber = new Random().nextInt(10);
		System.out.println("随机数已生成!");
		// 2.输入猜的数字
		System.out.println("----请输入您猜的数字:----");
		Scanner sc = new Scanner(System.in);
		int enterNumber = sc.nextInt();
		// 3.通过while循环,进行猜数字对错判断
		// 猜对,跳出循环,游戏结束
while (enterNumber != randomNumber) {
			// 猜错了,根据结果,给出提示,接着猜数字,游戏继续
			if (enterNumber > randomNumber) {
				// 如果猜大了,打印sorry,您猜大了!继续下一次循环
				System.out.println("sorry,您猜大了!");
			} else {
				// 如果猜小了,打印sorry,您猜小了!继续下一次循环
				System.out.println("sorry,您猜小了!");
			}
			// 输入猜的数字
			System.out.println("----请输入您猜的数字:----");
			enterNumber = sc.nextInt();
		}
		System.out.println("恭喜您,答对了!");
	}
}

数组

1,数组的定义:

数组的定义:数组是指一个数据的集合,数组中的每一个元素被称为元素,在数组中可以存放任意类型的元素,但同一个元素中放的元素类型必须一致。

2,一维数组格式

int [] x = new int[100];
//也可写作
int[] x;			//声明一个 int[] 类型的变量
x = new int[100]	//创建一个长度为100的数组
//案例 : 通过“.length”的方式来获得数组的长度,即数组的个数
public class Example24 {
	public static void main(String[] args) {
		int[] arr; // 声明变量
		arr = new int[3]; // 创建数组对象
		System.out.println("arr[0]=" + arr[0]); // 访问数组中的第一个元素
		System.out.println("arr[1]=" + arr[1]); // 访问数组中的第二个元素
		System.out.println("arr[2]=" + arr[2]); // 访问数组中的第三个元素
		System.out.println("数组的长度是:" + arr.length); // 打印数组长度
	}
  • 当数组被成功创建后,数组中元素会被自动赋予一个默认值,根据元素类型的不同,默认初始化的值也是不一样的。
数据类型默认初始化值
byte,short,int,long0
float,double0.0
char一个空字符,即’\u0000’
booleanfalse
引用数据类型null,表示变量不引用任何对象
//案例 : 在使用数组时,如果不想使用默认初始值,也可以显式地为数组元素赋值。接下来,通过一个案例来学习如何为数组的元素赋值.
public class Example25 {
	public static void main(String[] args) {
		int[] arr = new int[4]; // 定义可以存储4个元素的整数类型数组
		arr[0] = 1; // 为第1个元素赋值1
		arr[1] = 2; // 为第2个元素赋值2
		// 依次打印数组中每个元素的值
		System.out.println("arr[0]=" + arr[0]);
		System.out.println("arr[1]=" + arr[1]);
		System.out.println("arr[2]=" + arr[2]);
		System.out.println("arr[3]=" + arr[3]);
	}
  • 在初始化数组时还有一种方法叫做静态初始化,就是在定义数组的同时为数组的每一个元素赋值。数组的静态初始化有两种格式
1,类型[] 数组名 = 类型[]{元素,元素,...};
2,类型[] 数组名 = {元素,元素,...};
//案例 : 
public class Example26 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4 }; // 静态初始化
		// 依次访问数组中的元素
		System.out.println("arr[0] = " + arr[0]);
		System.out.println("arr[1] = " + arr[1]);
		System.out.println("arr[2] = " + arr[2]);
		System.out.println("arr[3] = " + arr[3]);
	}
}
//1、每个数组的索引都有一个范围,即0~length-1。在访问数组的元素时,索引不能超出这个范围,否则程序会报错。通过一个案例来演示,
/**
 * 数组越界异常
 */
public class Example27 {
	public static void main(String[] args) {
		int[] arr = new int[4]; // 定义一个长度为4的数组
		System.out.println("arr[0]=" + arr[4]); // 通过角标4访问数组元素
	}
}
//2、在使用变量引用一个数组时,变量必须指向一个有效的数组对象,如果该变量的值为null,则意味着没有指向任何数组,此时通过该变量访问数组的元素会出现空指针异常。通过一个案例来演示,
/**
 * 空指针异常
 */
public class Example28 {
	public static void main(String[] args) {
		int[] arr = new int[3]; // 定义一个长度为3的数组
		arr[0] = 5; // 为数组的第一个元素赋值
		System.out.println("arr[0]=" + arr[0]); // 访问数组的元素
		arr = null; // 将变量arr置为null
		System.out.println("arr[0]=" + arr[0]); // 访问数组的元素
	}
}

3,数组的常用操作

3.1,数组遍历,
  • 在操作数组时,经常需要依次访问数组中的每一个元素,这种操作叫做数组的遍历
//案例 : 使用 for 循环遍历数组
/**
 * for循环遍历数组
 */
public class Example29 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 }; // 定义数组
		// 使用for循环遍历数组的元素
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]); // 通过索引访问元素
		}
	}
}
3.2,数组最值
  • 在操作数组时,经常需要获得数组中元素的最值
//案例 : 取数组中元素的最大值
/**
 * 获取数组中元素的最大值
 */
public class Example30 {
	public static void main(String[] args) {
		int[] arr = { 4, 1, 6, 3, 9, 8 }; // 定义一个数组
		int max = getMax(arr); // 调用获取元素最大值的方法
		System.out.println("max=" + max); // 打印最大值
	}

	static int getMax(int[] arr) {
		int max = arr[0]; // 定义变量max用于记住最大数,首先假设第一个元素为最大值
		// 下面通过一个for循环遍历数组中的元素
		for (int x = 1; x < arr.length; x++) {
			if (arr[x] > max) { // 比较 arr[x]的值是否大于max
				max = arr[x]; // 条件成立,将arr[x]的值赋给max
			}
		}
		return max; // 返回最大值max
	}
}
3.3数组排序
  • 在操作数组时,经常需要对数组中的元素进行排序,其中冒泡排序是比较常见的一种算法。冒泡过程中,不断比较数组中相邻的两个元素,较小者向上浮,较大者向下沉,整个过程和水中冒泡上升的原理相似。
    数组排序的过程 :
  1. 从第一个元素开始,将相邻的两个元素依次比较,直到最后两个元素完成比较,如果第一个元素比后一个大,则交换位置。整个过程完成后,数组中最后一个元素就是最大值

  2. 除最后一个元素,将剩下的元素继续进行两两比较,过程与第一步类似,这样数组中第二大的元素放在了倒数第二个位置

  3. 以此类推,持续对越来越少的元素重复上面的步骤,直到没有任何一个元素需要比较为止

    //案例  : 冒泡排序
    /**
     * 冒泡排序
     */
    public class Example31 {
    	public static void main(String[] args) {
    		int[] arr = { 9, 8, 3, 5, 2 };
    		System.out.print("冒泡排序前  :");
    		printArray(arr); // 打印数组元素
    		bubbleSort(arr); // 调用排序方法
    		System.out.print("冒泡排序后  :");
    		printArray(arr); // 打印数组元素
    	}
    
    	// 定义打印数组元素的方法
    	public static void printArray(int[] arr) {
    		// 循环遍历数组的元素
    		for (int i = 0; i < arr.length; i++) {
    			System.out.print(arr[i] + " "); // 打印元素和空格
    		}
    		System.out.print("\n");
    	}
    
    	// 定义对数组排序的方法
    	public static void bubbleSort(int[] arr) {
    		// 定义外层循环
    		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]) { // 比较相邻元素
    					// 下面的三行代码用于交换两个元素
    					int temp = arr[j];
    					arr[j] = arr[j + 1];
    					arr[j + 1] = temp;
    				}
    			}
    			System.out.print("第" + (i + 1) + "轮排序后:");
    			printArray(arr); // 每轮比较结束打印数组元素
    		}
    	}
    }
    

4,多维数组

  • 多维数组可以简单地理解为在数组中嵌套数组,比较常见的就是二维数组

  • 而二维数组也有很多的定义方式 :

    1. 方式一 :

      int[][] arr = new int[3][4];
      //三行四列的二维数组
      

      它的结构图像

      XX [0] [0]XX [0] [1]XX [0] [2]XX [0] [3]
      XX [1] [0]XX [1] [1]XX [1] [2]XX [1] [3]
      XX [2] [0]XX [2] [1]XX [2] [2]XX [2] [3]
    2. 方式二 :

      int[][] arr = new int[3][];
      //与第一种方式类似,只是数组中的每行元素的长度不确定
      

      它的结构图像

      XX [0] [0]
      XX [1] [0]XX [1] [1]
      XX [2] [0]XX [2] [1]XX [2] [2]
    3. 方式三 :

      int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
      //采用上述方式定义的二维数组有三个元素,这三个元素多是数组,分别是{1,2},{3,4,5,6},{7,8,8}
      

      它的结构图像

      12
      3456
      789
      //案例 :统计一个公司三个销售小组中每个小组的总销售额以及整个公司的销售额
      /**
       * 二维数组的使用
       */
      public class Example32 {
      	public static void main(String[] args) {
      		int[][] arr = new int[3][]; // 定义一个长度为3的二维数组
      		arr[0] = new int[] { 11, 12 }; // 为数组的元素赋值
      		arr[1] = new int[] { 21, 22, 23 };
      		arr[2] = new int[] { 31, 32, 33, 34 };
      		int sum = 0; // 定义变量记录总销售额
      		for (int i = 0; i < arr.length; i++) { // 遍历数组元素
      			int groupSum = 0; // 定义变量记录小组销售总额
      			for (int j = 0; j < arr[i].length; j++) { // 遍历小组内每个人的销售额
      				groupSum = groupSum + arr[i][j];
      			}
      			sum = sum + groupSum; // 累加小组销售额
      			System.out.println("第" + (i + 1) + "小组销售额为:" + groupSum + " 万元。");
      		}
      		System.out.println("总销售额为: " + sum + " 万元。");
      	}
      }
      

面向对象

1,面向对象的概念

面向对象的特点主要可以概括为封装性、继承性和多态性

1.1,封装性
  • 封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界知道具体实现细节,这就是封装思想。
1.2,继承性
  • 继承性主要描述的是类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展。
1.3,多态性
  • 多态性指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其它类继承后,它们可以具有不同的数据类型或表现出不同的行为,这使得同一个属性和方法在不同的类中具有不同的语义。

2,类与对象

2.1类的定义
  • 在面向对象的思想中最核心的就是对象,为了在程序中创建对象,首先需要定义一个类。类是对象的抽象,它用于描述一组对象的共同特征和行为。类中可以定义成员变量和成员方法,其中成员变量用于描述对象的特征,也被称作属性,成员方法用于描述对象的行为,可简称为方法。

  • 下面我们结合Java程序的格式来详细介绍类的声明方法:

package 包名       // 声明程序所在包
import 包名.*      // 导入外部包,可包含多条import语句,以导入多个外部包中的类
import 包名.类名
// 声明和定义类
[类修饰符] class 类名[extends 父类名称][implements 接口名称列表]{
	// 声明成员变量或常量
	[访问控制修饰符][static][final]<数据类型> 变量名或常量名;
	……			// 定义其他成员变量或常量
	// 声明和定义成员方法
	 [访问控制修饰符][abstract][static][final][native][synchronized]
		返回类型 方法名(参数列表) [throws 异常类型列表]
	{
		……		// 方法体
	}
	……			// 定义其他方法
}
……				// 定义其他类

//解释说明
//(1)在一个Java文档中可以包含多个类,但最多只能有一个为公共类(即public class,也可以没有)。
//(2)如果存在public class的话,该类的类名必须与文档名相同。
//(3)main方法是Java应用程序的入口,如果文档中存在publicclass和main方法,则main方法必须位于public class中。
         
//main方法的格式如下:
public class 类名 {
		// 成员变量列表
		public static void main(String[] args) {
			// 局部变量声明
			// 方法体
<1>,类声明
  • 类声明定义了类的名字及其他属性。类声明的一般格式如下:
   [类修饰符] class 类名[extends 父类名称][implements 接口名称列表]{
	……
   }
  • 其中,class关键字和类名是必需的,[]表示可选项。类名是要声明的类的名字,它必须是一个合法的Java标识符,习惯上首字母要大写。

类修饰符

  • 类修饰符有public、abstract和final。如果没有声明这些类修饰符,Java编译器默认该类为friendly类,对于这些类,只有同一包中的类可以访问。

  • public(公共的):带有public修饰符的类称为公共类,公共类可以被 任何包中的类访问。不过,要在一个类中使用其他包中的类,必须在 程序中增加import语句 。

  • abstract(抽象的):带有abstract修饰符的类称为抽象类,相当于类 的抽象。一个抽象类可以包含抽象方法,而抽象方法是没有方法体的 方法,所以抽象类不具备具体功能,只用于衍生出子类。因此,抽象 类不能被实例化。

  • final(最终的) :带有final修饰符的类称为最终类。不能通过扩展最 终类来创建新类。也就是说,它不能被继承,或者说它不能派生子类。

    package cn.itcast.chapter03.example01;
    class Person {
    	int age; // 定义int类型的变量age
    	// 定义 speak() 方法
    	void speak() {
    		System.out.println("大家好,我今年" + age + "岁!");
    	}
    }
    
<2>,成员变量
  • 在Java中,定义在类中的变量被称为成员变量,定义在方法中的变量被称为局部变量。如果在某一个方法中定义的局部变量与成员变量同名,这种情况是允许的,此时方法中通过变量名访问到的是局部变量,而并非成员变量

  • 成员变量或常量声明必须放在类体中,其一般形式为:

 [访问控制修饰符][static]<数据类型> 变量名;
  • 访问控制修饰符

  • 使用访问控制修饰符可以限制访问成员变量的权限。访问控制修饰符有4个等级:private、protected、public以及默认(即不指定修饰符)

类型privateprotectedpublic默认
所属类可访问可访问可访问可访问
同一个包的其他类不可访问可访问可访问可访问
同一个包的子类不可访问可访问可访问可访问
不同包中的子类不可访问可访问可访问不可访问
不同包中的非子类不可访问不可访问可访问不可访问
2.2,对象的创建与使用
  • 应用程序想要完成具体的功能,仅有类是远远不够的,还需要根据类创建实例对象。在Java程序中可以使用new关键字来创建对象,具体格式如下:
类名 对象名称 = new 类名()
  
//例如,创建Person类的实例对象代码如下:

Person p = new Person();
  • 上面的代码中,“new Person()”用于创建Person类的一个实例对象,“Person p”则是声明了一个Person类型的变量p。中间的等号用于将Person对象在内存中的地址赋值给变量p,这样变量p便持有了对象的引用。
package cn.itcast.chapter03.example01;
/**
 * 访问对象的成员
 */
class Example01 {
	public static void main(String[] args) {
		Person p1 = new Person(); // 创建第一个Person对象
		Person p2 = new Person(); // 创建第二个Person对象
		p1.age = 18; // 为age属性赋值
		p1.speak(); // 调用对象的方法
		p2.speak();
	}
}
<1>,方法
  • 在Java中,声明一个方法的具体语法格式如下所示:
修饰符 返回值类型 方法名([参数类型 参数名1,....]){
	执行语句
	...
	return 返回值;
}
  • 修饰符:是对访问权限的限定,例如,public、static都是修饰符
  • 返回值类型:用于限定方法返回值的数据类型
  • 参数类型:用于限定调用方法时传入参数的数据类型
  • 参数名:是一个变量,用于接收调用方法时传入的数据
  • return关键字:用于结束方法以及返回方法指定类型的值
  • 返回值:被return语句返回的值,该值会返回调用者
package cn.itcast.chapter02.example20;
/**
 * 使用方法时实现打印三个长宽不同的矩形
 */
public class Example20 {
	public static void main(String[] args) {
		printRectangle(3, 5); // 调用 printRectangle()方法实现打印矩形
		printRectangle(2, 4);
		printRectangle(6, 10);
	}

	// 下面定义了一个打印矩形的方法,接收两个参数,其中height为高,width为宽
	public static void printRectangle(int height, int width) {
		// 下面是使用嵌套for循环实现*打印矩形
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				System.out.print("*");
			}
			System.out.print("\n");
		}
		System.out.print("\n");
	}
}
package cn.itcast.chapter02.example21;
/**
 * 使用有返回值的方法求矩形的面积
 */
public class Example21 {
	public static void main(String[] args) {
		int area = getArea(3, 5); // 调用 getArea方法
		System.out.println(" The area is " + area);
	}

	// 下面定义了一个求矩形面积的方法,接收两个参数,其中x为高,y为宽
	public static int getArea(int x, int y) {
		int temp = x * y; // 使用变量temp记住运算结果
		return temp; // 将变量temp的值返回
	}
}

方法的重载

  • Java允许在一个程序中定义多个名称相同的方法,但是参数的类型或个数必须不同,这就是方法的重载。
package cn.itcast.chapter02.example23;
/**
 * 方法的重载
 */
public class Example23 {
	public static void main(String[] args) {
		// 下面是针对求和方法的调用
		int sum1 = add(1, 2);
		int sum2 = add(1, 2, 3);
		double sum3 = add(1.2, 2.3);
		// 下面的代码是打印求和的结果
		System.out.println("sum1=" + sum1);
		System.out.println("sum2=" + sum2);
		System.out.println("sum3=" + sum3);
	}

	// 下面的方法实现了两个整数相加
	public static int add(int x, int y) {
		return x + y;
	}

	// 下面的方法实现了三个整数相加
	public static int add(int x, int y, int z) {
		return x + y + z;
	}

	// 下面的方法实现了两个小数相加
	public static double add(double x, double y) {
		return x + y;
	}
}
2.3,类的设计
  • 在Java中,对象是通过类创建出来的。因此,在程序设计时,最重要的就是类的设计

  • 假设要在程序中描述一个学校所有学生的信息,可以先设计一个学生类(Student),在这个类中定义两个属性name、age分别表示学生的姓名和年龄,定义一个方法introduce()表示学生做自我介绍。根据上面的描述设计出来的Student类如下所示。

public class Student {
	String name;	//定义一个姓名属性
	int age;		//定义一个年龄属性
	public void introduce(){
		//方法中打印属性 name 和 age 的值
		System.out.println("大家好,我叫" + name + ",我今年" + age +"岁");
	}
}
2.4,类的封装
  • 在设计一个类时,应该对成员变量的访问作出一些限定,不允许外界随意访问,这就需要实现类的封装。

  • 封装的目的 :在于使对象的设计者和使用者分开,使用者不必知道对象行为实现的细节,只需要使用设计者提供的接口来访问对象。

封装步骤:
(1)修改属性的可见性,限制访问。
  (2)设置属性的读取方法。
  (3)在读取属性的方法中,添加对属性读取的限制。

  • 封装是OOP设计者追求的理想境界,它可以为开发员带来两个好处:模块化和数据隐藏。模块化意味着对象代码的编写和维护可以独立进行,不会影响到其他模块,而且有很好的重用性;数据隐藏则使对象有能力保护自己,它可以自行维护自身的数据和方法。因此,封装机制提高了程序的安全性和可维护性。

  • 所谓类的封装是指在定义一个类时,将类中的属性私有化,即使用 private 关键字来修饰,私有属性只能在它所在类中被访问,如果外界想要访问私有属性,需要提供一些使用 public 修饰的公有方法,其中包括用于获取属性值的 getXxx 方法和设置属性值的 setXxx 方法。

package cn.itcast.chapter03.example04;
/**
 * 实现类的封装
 */
class Student {
	private String name; // 将name属性私有化
	private int age; // 将age属性私有化

	// 下面是公有的 getXxx 和 setXxx 方法
	public String getName() {
		return name;
	}

	public void setName(String stuName) {
		name = stuName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int stuAge) {
		// 下面是对传入的参数进行检查
		if (stuAge <= 0) {
			System.out.println("对不起,您输入的年龄=不合法...");
		} else {
			age = stuAge; // 对属性赋值
		}
	}

	public void introduce() {
		System.out.println("大家好,我叫" + name + ",我今年" + age + "岁!");
	}
}

public class Example04 {
	public static void main(String[] args) {
		Student stu = new Student();
		stu.setAge(-30);
		stu.setName("韩强");
		stu.introduce();
	}
}

3-1,超市购物程序设计

在example 03文件下task01。

3,构造方法

定义

在一个类中定义的方法如果同时满足以下三个条件,该方法称为构造方法,具体如下:

  • 方法名与类名相同
  • 在方法名的前面没有返回值类型的声明
  • 在方法中不能使用return语句返回一个值,但是可以单独写return语句来作为方法的结束。

为了便于在基于类创建对象时向对象传递参数,以及对类的成员变量进行初始化。我们经常会为类编写一个或多个特殊的方法——构造方法。 类的构造方法有如下几个特点:

  1. 每个类都有一个默认的构造方法,它既无参数又无返回值,其作用是使用new操作符创建新对象后初始化新建对象。

  2. 一旦为类编写了构造方法,默认的构造方法将被覆盖 。

  3. 构造方法仅在使用new操作符创建新对象时执行一次,而且一般不能用“对象名.方法名”形式来显式调用。

  4. 编写构造方法的目的通常是为了向对象传递参数,以及对类的成员变量进行初始化 。

  5. 构造方法同样支持方法重载。

  6. 构造方法的名称必须与类名完全相同,并且不返回任何值

  7. 构造方法不能被static、final、abstract、synchronized和native等修饰符修饰,并且带参数的构造方法不能被子类继承 。

    package cn.itcast.chapter03.example05;
    /**
     * 构造方法的定义
     */
    class Person {
    	// 下面是类的构造方法
    	public Person() { //构造方法与类名一致
    		System.out.println("无参的构造方法被调用了...");
    	}
    }
    
    public class Example05 {
    	public static void main(String[] args) {
    		Person p = new Person(); // 实例化 Person对象
    	}
    }
    

构造方法的重载

  • 与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。在创建对象时,可以通过调用不同的构造方法来为不同的属性进行赋值。
package cn.itcast.chapter03.example07;
/**
 * 构造方法的重载
 */
class Person {
	String name;
	int age;

	// 定义两个参数的构造方法
	public Person(String con_name, int con_age) {
		name = con_name; // 为name属性赋值
		age = con_age; // 为age属性赋值
	}

	// 定义一个参数的构造方法
	public Person(String con_name) {
		name = con_name; // 为name属性赋值
	}

	public void speak() {
		// 打印name和age的值
		System.out.println("大家好,我叫" + name + ",我今年" + age + "岁!");
	}
}

public class Example07 {
	public static void main(String[] args) {
		// 分别创建两个对象 ps1 和 ps2
		Person p1 = new Person("韩强");
		Person p2 = new Person("晓英", 27);
		// 通过对象ps1 和 ps2 调用speak()方法
		p1.speak();
		p2.speak();
	}
}

4,this关键字

  • 例如都声明为age。但是这样做又会导致成员变量和局部变量的名称冲突,在方法中将无法访问成员变量age。为了解决这个问题,Java中提供了一个关键字this来指代当前对象,用于在方法中访问对象的其它成员
  1. 区分成员变量和局部变量
  2. 代表当前对象
  3. 构造方法与构造方法之间的调用
  • this关键字在程序中的三种常见用法
package cn.itcast.chapter03.example10;

public class Example_this1 {
	 public static void main(String[] args) {
	        Student1 s=new Student1("小明明",20);
	        System.out.println(s);
	    }
}
class Student1{
    String name;
    int age;
    int id;

    public Student1(int id,String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }


    public Student1(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student1(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student1 [ id=" + id + ", name=" + name + ", age=" + age +"]";
    }
}
package cn.itcast.chapter03.example10;
//3.构造方法与构造方法之间的调用

/*构造器用法-->this();跟函数一样()中可以写参数
构造器调用一般是这样子用的.不同的构造器中存在相同代码.为了复用性。
可以在参数少的构造器中调用参数多的构造器,如下:*/
public class Example_this2 {
	public static void main(String[] args) {
        Student2 s=new Student2("小明明");
        System.out.println(s);
    }
   
}
class Student2{
    String name;
    int age;
    int id;
    public Student2(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
        System.out.println("构造器3已调用");
    }
    public Student2(String name, int age) {
    	//只能写到第一行
        this(name,age,0);
        System.out.println("构造器2已调用");
    }

    public Student2(String name) {
        this(name,0);//参数不足,就使用参数默认值补全
        System.out.println("构造器1已调用");
    }
    @Override
    public String toString() {
        return "Student2 [ id=" + id + ", name=" + name + ", age=" + age +"]";
    }
}
package cn.itcast.chapter03.example10;
/**
 * 构造方法中使用this
 */
class Person {
	public Person() {
		System.out.println("无参的构造方法被调用了...");
	}

	public Person(String name) {
		this(); // 调用无参的构造方法
		System.out.println("有参的构造方法被调用了...");
	}
}

public class Example10 {
	public static void main(String[] args) {
		Person p = new Person("itcast"); // 实例化 Person 对象
	}
}
package cn.itcast.chapter03.example10;
//1.区分成员变量和局部变量

public class Example10_this {
    public static void main(String[] args) {
        Student s=new Student("小明明",20);
        System.out.println(s);
    }
    /*2.代表当前对象
  //为什么加入this后就可以区分呢?
    //因为this当前代表的是s实例(对象)相当于
    s.name="小明明";
    s.age="20";
    //再可以理解如下
    this.name=实例(对象).name="小明明";
    */
}
class Student{
    String name;
    int age;
    public Student(String name, int age) {
        //注:没有加this
        name = name;
        age = age;
    }
    /*
    public Student(String name, int age) {
        //注:可以使用this进行区分成员变量和局部变量
        this.name = name;
        this.age = age;
}*/

    @Override
    public String toString() {
        return "Student [ name=" + name + ", age=" + age +"]";
    }
}

5,立即回收

6,static关键字

静态变量

在定义一个类时,只是在描述某类事物的特征和行为,并没有产生具体的数据。只有通过new关键字创建该类的实例对象后,系统才会为每个对象分配空间,存储各自的数据。

在一个Java类中,可以使用static关键字来修饰成员变量,该变量被称作静态变量。静态变量被所有实例共享,可以使用“类名.变量名”的形式来访问

// 例如:

/*
 * 静态变量
 */
class Student {
	static String schoolName; // 定义静态变量schoolName
}

public class Example12 {
	public static void main(String[] args) {
		Student stu1 = new Student(); // 创建学生对象
		Student stu2 = new Student();
		Student.schoolName = "郑电院"; // 为静态变量赋值
		System.out.println("我的学校是" + stu1.schoolName); // 打印第一个学生对象的学校
		System.out.println("我的学校是" + stu2.schoolName); // 打印第二个学生对象的学校
	}
}
/*
注意:static关键字只能用于修饰成员变量,不能用于修饰局部变量,否则编译会报错。
*/

静态方法

在实际开发时,开发人员有时会希望在不创建对象的情况下就可以调用某个方法,换句话说也就是使该方法不必和对象绑在一起。要实现这样的效果,只需要在类中定义的方法前加上static关键字即可,通常称这种方法为静态方法。同静态变量一样,静态方法可以使用“类名.方法名”的方式来访问,也可以通过类的实例对象来访问

注意:在一个静态方法中只能访问用static修饰的成员,原因在于没有被static修饰的成员需要先创建对象才能访问,而静态方法在被调用时可以不创建任何对象。

// 案例:

/**
 * 静态方法的使用
 */
class Person {
	public static void sayHello() { // 定义静态方法
		System.out.println("hello");
	}
}

class Example13 {
	public static void main(String[] args) {
		//1.类名.方法的方式调用静态方法
		Person.sayHello();
		//2.实例化对象的方式来调用静态方法
		Person p = new Person();
		p.sayHello(); 
	}
}

静态代码块

在Java类中,使用一对大括号包围起来的若干行代码被称为一个代码块,用static关键字修饰的代码块称为静态代码块。当类被加载时,静态代码块会执行,由于类只加载一次,因此静态代码块只执行一次。在程序中,通常会使用静态代码块来对类的成员变量进行初始化

// 案例:

package cn.itcast.chapter03.example14;
/**
 * 静态代码块
 */
class Example14 {
	// 静态代码块
	static {
		System.out.println("测试类的静态代码块执行了");
	}
	public static void main(String[] args) {
		// 下面的代码创建了两个Person对象
		Person p1 = new Person();
		Person p2 = new Person();
	}
}
class Person {
	// 下面是一个静态代码块
	static {
		System.out.println("Person类中的静态代码块执行了");
	}
}

7,成员内部类

在Java中,允许在一个类的内部定义类,这样的类称作内部类,这个内部类所在的类称作外部类。根据内部类的位置、修饰符和定义的方式可分为:成员内部类,局部内部类,静态内部类,匿名内部类

定义 : 在一个类中除了可以定义成员变量、成员方法,还可以定义类,这样的类被称作成员内部类。在成员内部类中,可以访问外部类的所有成员

如果想通过外部类去访问内部类,则需要通过外部类对象去创建内部类对象,创建内部类对象的具体语法格式如下:

外部类名.内部类名 变量名=new 外部类名().new 内部类名();

3-2,银行新用户现金业务办理

package cn.itcast.chapter03.task02;
public class Bank {
	static String bankName; // 定义静态变量银行名称
	private String name ;//储户姓名
	private String password ;//密码
	private double balance ;//账户余额
	private double turnover ;//交易额
	//静态方法,打印出银行欢迎语句
	static void welcome(){
		System.out.println("欢迎来到"+bankName+"-------------");
	}
	//构造方法  开户
	public Bank(String name,String password,double turnover){
			//将变量赋值给成员变量
			this.name = name;
			this.password = password;
			this.turnover = turnover;
			this.balance = turnover - 10;
			System.out.println(name+" 开户成功,账户余额 "+balance);	
	}
	//存款
	public void deposit(double turnover){
		balance = balance + turnover;
		System.out.println(name+"您好,您的账户 已存入"+turnover+"元,"
				+ "当前余额 "+balance+" 元");
	} 
	//取款
	public void withdrawal( String password,double turnover){
		//根据传入的变量与成员变量比对,判断密码是否正确
		if(this.password != password){
			System.out.println("您输入的密码错误!");
			return;
		}
		//判断余额是否充足
		if(balance - turnover >  0){
			balance = balance - turnover;
			System.out.println(name+"您好,您的账户 已取出"+turnover+"元,"
					+ "当前余额 "+balance+" 元");
		}else{
			System.out.println("对不起,账户余额不足!");
		}
	}
	//静态方法,打印出银行欢迎下次光临语句
	static void welcomeNext(){
		System.out.println("请携带好随身财物,欢迎下次光临"+bankName+"-------------");
	}
}
package cn.itcast.chapter03.task02;
public class Trade {
	public static void main(String[] args) {
		//定义一家银行   给静态变量(银行名称)赋值,可以直接使用类名访问
		Bank.bankName = "招商银行";
		//银行打印欢迎语句   调用静态方法
		Bank.welcome();
		//开户操作    通过构造方法进行开户操作
		Bank bank = new Bank("小梦", "654321", 100.0);
		//进行存款操作
		bank.deposit(500.00);
		//取款时密码输入错误,取款失败
		bank.withdrawal("123456",200.0);
		//取款时余额不足时,取款失败
		bank.withdrawal("654321", 1000.0);
		//取款时密码正确,余额充足,取款成功
		bank.withdrawal("654321", 200.0);
		//银行打印道别语句  调用静态方法
		Bank.welcomeNext();
	}
}

面向对象(下)

1,类的继承

类继承的语法格式:

[修饰符] class 子类名 extends 父类名{
		// 程序核心代码
}
// 如果想声明一个类继承另一个类,需要使用extends关键字

在语法格式中,类的修饰符是可选的,用来指定类的访问权限,可以指定类的访问权限,可以使用public或者省略不写;子类名和父类名都是必选的,并且子类和父类之间要是用extends关键字实现继承关系

1.1,继承的概念

在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法

package cn.itcast.chapter04.example01;

// 定义Animal类
class Animal {
	String name; // 定义name属性

	// 定义动物叫的方法
	void shout() {
		System.out.println("动物发出叫声");
	}
}

// 定义Dog类继承Animal类
class Dog extends Animal {
	// 定义一个打印name的方法
	public void printName() {
		System.out.println("name=" + name);
	}
}

// 定义测试类
public class Example01 {
	public static void main(String[] args) {
		Dog dog = new Dog(); // 创建一个Dog类的实例对象
		dog.name = "沙皮狗"; // 为Dog类的name属性进行赋值
		dog.printName(); // 调用dog类的getInfo()方法
		dog.shout(); // 调用dog类继承来的shout()方法
	}
}

在类的继承中,需要注意一些问题,具体如下:

1,在Java中,类只支持单继承,不允许多重继承,也就是说一个类只能有一个直接父类,例如下面这种情况是不合法的。

class A()
class B()
class C extends A,B()  //C类不可以同时继承A类与B类

2,多个类可以继承一个父类,例如下面这种情况是允许的。

class A()
class B extends A()
class C extends A() //B类和C类都可以继承A类

3,在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类,例如C类继承自B类,而B类又可以去继承A类,这时,C类也可称作A类的子类。例如下面这种情况是允许的。

class A()
class B extends A()//B类继承A类,B类是A类的子类
class C extends B()//C类继承B类,C类是B类的子类,也是A类的子类

4,在Java中,子类和父类是一种相对概念,也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如上面的示例中,B类是A类的子类,同时又是C类的父类。

1.2,重写父类方法

在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。

注意:

  1. 子类中重写的方法需要和父类被重写的方法具有相同的方法名,参数列表以及返回值类型。
  2. 子类重写父类方法时不能使用比父类中被重写的方法更严格的访问权限
/*
Dog类从Animal类继承了shout()方法,该方法在被调用时会打印“动物发出叫声”,这明显不能描述一种具体动物的叫声,Dog类对象表示犬类,发出的叫声应该是“汪汪汪”。
*/
// 定义Animal类
class Animal {
	// 定义动物叫的方法
	void shout() {
		System.out.println("动物发出叫声");
	}
}

// 定义Dog类继承动物类
class Dog extends Animal {
	// 定义狗叫的方法
	void shout() {
		System.out.println("汪汪汪……");
	}
}

// 定义测试类
public class Example02 {
	public static void main(String[] args) {
		Dog dog = new Dog(); // 创建Dog类的实例对象
		dog.shout(); // 调用dog重写的shout()方法
	}
}
1.3,super关键字

当子类重写父类的方法后,子类对象将无法访问父类被重写的方法,为了解决这个问题,在Java中专门提供了一个super关键字用于访问父类的成员。例如访问父类的成员变量、成员方法和构造方法。接下来分两种情况来学习一下super关键字的具体用法。

1,使用super关键字访问父类的成员变量和成员方法。具体格式如下:

super.成员变量
super.成员方法([参数1,参数2...])
// 定义Animal类
class Animal {
	String name = "动物";

	// 定义动物叫的方法
	void shout() {
		System.out.println("动物发出叫声");
	}
}

// 定义Dog类继承动物类
class Dog extends Animal {
	String name = "犬类";

	// 重写父类的shout()方法
	void shout() {
		super.shout(); // 访问父类的成员方法
	}

	// 定义打印name的方法
	void printName() {
		System.out.println("name=" + super.name); // 访问父类的成员变量
	}
}

// 定义测试类
public class Example03 {
	public static void main(String[] args) {
		Dog dog = new Dog(); // 创建一个Dog对象
		dog.shout(); // 调用dog对象重写的shout()方法
		dog.printName(); // 调用dog对象的的printName()方法
	}
}

2,使用super关键字访问父类的构造方法。具体格式如下:

super([参数1,参数2...])
package cn.itcast.chapter04.example04;
// 定义Animal类
class Animal {
	// 定义Animal类有参的构造方法
	public Animal(String name) {
		System.out.println("我是一只" + name);
	}
}
// 定义Dog类继承Animal类
class Dog extends Animal {
	public Dog() {
		super("沙皮狗"); // 调用父类有参的构造方法
	}
}
// 定义测试类
public class Example04 {
	public static void main(String[] args) {
		Dog dog = new Dog(); // 实例化子类Dog对象
	}
}

2,final关键字

2.1,final关键字修饰符

final关键字可用于修饰类、变量和方法,它有“无法改变”或者“最终”的含义,因此被final修饰的类、变量和方法将具有以下特性:

  1. final修饰的类不能被继承。
  2. final修饰的方法不能被子类重写。
  3. final修饰的变量(成员变量和局部变量)是常量,只能赋值一次
2.2,final关键字修饰类

Java中的类被final关键字修饰后,该类将不可以被继承,也就是不能够派生子类。

package cn.itcast.chapter04.example06;
// 使用final关键字修饰Animal类时,子类会报错
//final class Animal {
class Animal {
	// 方法体为空
}
// Dog类继承Animal类
class Dog extends Animal {
	// 方法体为空
}
// 定义测试类
class Example06 {
	public static void main(String[] args) {
		Dog dog = new Dog(); // 创建Dog类的实例对象
	}
}
2.3,final关键字修饰方法

当一个类的方法被final关键字修饰后,这个类的子类将不能重写该方法

// 定义Animal类
class Animal {
	// 使用final关键字修饰shout()方法后,如果子类重写父类的这个方法,编译会报错
	//public final void shout() {
	public void shout() {
		// 程序代码
	}
}
// 定义Dog类继承Animal类
class Dog extends Animal {
	// 重写Animal类的shout()方法
	public void shout() {
		// 程序代码
	}
}
// 定义测试类
class Example07 {
	public static void main(String[] args) {
		Dog dog = new Dog(); // 创建Dog类的实例对象
	}
}
2.4,final关键字修饰变量

Java中被final修饰的变量称为常量,它只能被赋值一次,也就是说final修饰的变量一旦被赋值,其值不能改变。如果再次对该变量进行赋值,则程序会在编译时报错。

package cn.itcast.chapter04.example08;
public class Example08 {
	public static void main(String[] args) {
		final int num = 2; // 第一次可以赋值
		//num = 4; // 再次赋值会报错
	}
}
// 定义Student类
class Student {
	//final String name; // 使用final关键字修饰name属性
	final String name = "韩强"; // 为成员变量赋予初始值
	// 定义introduce()方法,打印学生信息
	public void introduce() {
		System.out.println("我叫" + name+",是传智播客的学生");
	}
}
// 定义测试类
public class Example09 {
	public static void main(String[] args) {
		Student stu = new Student(); // 创建Student类的实例对象
		stu.introduce(); // 调用Student的introduce()方法
	}
}

3,抽象类和接口

1,抽象类

当定义一个类时,常常需要定义一些方法来描述该类的行为特征,但有时这些方法的实现方式是无法确定的。例如前面在定义Animal类时,shout()方法用于表示动物的叫声,但是针对不同的动物,叫声也是不同的,因此在shout()方法中无法准确描述动物的叫声。

针对上面描述的情况,Java允许在定义方法时不写方法体,不包含方法体的方法为抽象方法,抽象方法必须使用abstract关键字来修饰,具体示例如下:

abstract void shout(); //定义抽象方法 shout()

当一个类中包含了抽象方法,该类必须使用abstract关键字来修饰,使用 abstract 关键字修饰的类为抽象类,具体示例如下:

// 定义抽象类 Animal
abstract class Animal{
	// 定义抽象方法 shout()
	abstract int shout()
}

在定义抽象类时需要注意,包含抽象方法的类必须声明为抽象类,但抽象类可以不包含任何抽象方法,只需使用abstract关键字来修饰即可。另外,抽象类是不可以被实例化的,因为抽象类中有可能包含抽象方法,抽象方法是没有方法体的,不可以被调用。如果想调用抽象类中定义的方法,则需要创建一个子类,在子类中将抽象类中的抽象方法进行实现。

2,接口

如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另外一种方式来定义,即接口。接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象。

在定义接口时,需要使用 interface 关键字来声明,其语法格式如下:

[public] interface 接口名 [extends 接口1,接口2...]{
    [public] [static] [final] 数据类型 常量名 = 常量值;
    [public] [abstract] 返回值 抽象方法名(参数列表);
}

在上面的语法中,一个接口可以有多个父接口,他们之间用逗号隔开。Java使用接口的目的是为了克服单继承的限制,因为一个类只能有一个父类,而一个类可以实现多个接口。接口中的变量默认使用“public static final”来修饰,即全局常量;接口中定义的方法默认使用“public abstract”来修饰,即抽象方法。如果接口声明为public,则接口中的变量和方法全部为public。

由于接口中的方法都是抽象方法(JDK1.8以后可以有非抽象方法),因此不能通过实例化对象的方式来调用接口中的方法。此时需要定义一个类,并使用 implements 关键字实现接口中所有的方法。一个类可以在继承的同时实现多个接口,在implements子句中用逗号隔开。接口的实现类声明格式如下:

[<修饰符>] class <类名> [extends <超类名>] [implements <接口1>,<接口2>,...]

为了加深初学者对接口的认识,接下来对接口的特点进行归纳,具体如下:

  • 接口中的方法都是抽象的(JDK1.8以后可以有非抽象方法),不能实例化对象。

  • 接口中的属性只能是常量。

  • 当一个类实现接口时,如果这个类是抽象类,则实现接口中的部分方法即可,否则需要实现接口中的所有方法。

  • 一个类通过implements关键字实现接口时,可以实现多个接口,被实现的多个接口之间要用逗号隔开。具体示例如下:

    interface Run{
        程序代码......
    }
    interface Fly{
        程序代码......
    }
    class Bird implementd Run,Fly{
        程序代码......
    }
    
  • 一个接口可以通过extends关键字继承多个接口,接口之间用逗号隔开。具体示例如下:

    interface Runing{
        程序代码......
    }
    interface Flying{
        程序代码......
    }
    Interface Eating extends Runing,Flying{
        程序代码......
    }
    
  • 一个类在继承另一个类的同时还可以实现接口,此时,extends关键字必须位于implements关键字之前。具体示例如下:

    class Dog extends Canidae implements Animal{//先继承,在实现
        程序代码....
    }
    
3,USB接口程序设计

第8周源代码文件下的task01文件

4,多态

形成多态的条件:

  • 要有继承或者接口的实现
  • 子类重写父类的方法
  • 父类的引用指向子类的对象
1,多态概述

在设计一个方法时,通常希望该方法具备一定的通用性。例如要实现一个动物叫的方法,由于每种动物的叫声是不同的,因此可以在方法中接收一个动物类型的参数,当传入猫类对象时就发出猫类的叫声,传入犬类对象时就发出犬类的叫声。在同一个方法中,这种由于参数类型不同而导致执行效果各异的现象就是多态。继承是多态得以实现的基础。

在Java中为了实现多态,允许使用一个父类类型的变量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。

2,多态的类型转换

在多态的学习中,涉及到将子类对象当作父类类型使用的情况,此种情况在Java的语言环境中称之为“向上转型”,例如下面两行代码:

Animal an1 = new Cat();//将 Cat 对象当作 Animal 类型使用
Animal an2 = new Dog();//将 Dog 对象当作 Animal 类型使用

将子类对象当作父类使用时不需要任何显式地声明,需要注意的是,此时不能通过父类变量去调用子类中的特有方法

针对这种情况,Java提供了一个关键字instanceof,它可以判断一个对象是否为某个类(或接口)的实例或子类实例,语法格式如下:

对象(或者对象的引用变量) instanceof(接口)
3,模拟物流快递系统程序设计

第8周源代码task02

5,异常

1,什么是异常

尽管人人希望自己身体健康,处理的事情都能顺利进行,但在实际生活中总会遇到各种状况,比如感冒发烧,工作时电脑蓝屏、死机等。同样,在程序运行的过程中,也会发生各种非正常状况,比如程序运行时磁盘空间不足、网络连接中断、被装载的类不存在等。针对这种情况,在 Java 语言中,引入了异常,以异常类的形式对这些非正常情况进行封装,通过异常处理机制对程序运行时发生的各种问题进行处理。

// 例如:什么是异常

package cn.itcast.chapter04.example20;
public class Example20 {
	public static void main(String[] args) {
		int result = divide(4, 0); // 调用divide()方法
		System.out.println(result);
	}
	// 下面的方法实现了两个整数相除
	public static int divide(int x, int y) {
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}

Throwable 类的继承体系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-piuGbJ25-1587969466275)(C:\Users\Administrator\Desktop\笔记\java图片\1587968295049.png)]

通过图中可以看出,Throwable 有两个直接子类 Error 和 Exception,其中 Error 代表程序中产生的错误,Exception 代表程序中产生的异常

  • 接下来就对这两个直接子类进行详细的讲解。
    • Error类称为错误类,它表示Java运行时产生的系统内部错误或资源耗尽的错误,是比较严重的,仅靠修改程序本身是不能恢复执行的。举一个生活中的例子,在盖楼的过程中因偷工减料,导致大楼坍塌,这就相当于一个Error。使用java命令去运行一个不存在的类就会出现Error错误。
    • Exception类称为异常类,它表示程序本身可以处理的错误,在开发Java程序中进行的异常处理,都是针对Exception类及其子类。在Exception类的众多子类中有一个特殊的RuntimeException类,该类及其子类用于表示运行时异常,除了此类,Exception类下所有其他的子类都用于表示编译时异常。本节主要针对Exception类及其子类进行讲解。

Throwable类中的常用方法

方法声明功能描述
String getMessage()返回此 Throwable 的详细信息字符
void prinStackTrace()将此 Throwable 及其追踪输出至标准错误
void printStackTrace(PrintStreams)将此 Throwable 及其追踪输出到指定的输出流
2,try…catch和finally

Java中提供了一种对异常进行处理的方式——异常捕获。异常捕获通常使用 try…catch 语句,具体语法格式如下:

try{
    //可能发生异常的语句
}catch (Exception类及其子类 e){
    //对捕获的异常进行处理
}

其中在try代码块中编写可能发生异常的Java语句,catch代码块中编写针对异常进行处理的代码。当try代码块中的程序发生了异常,系统会将这个异常的信息封装成一个异常对象,并将这个对象传递给catch代码块。catch代码块需要一个参数指明它所能够接收的异常类型,这个参数的类型必须是Exception类或其子类。

//例如:使用try...catch语句对源代码Example20中出现的异常进行捕获和finally代码块的用法

package cn.itcast.chapter04.example21;

public class Example21 {
	public static void main(String[] args) {
		// 下面的代码定义了一个try…catch语句用于捕获异常
		try {
			int result = divide(4, 0); // 调用divide()方法
			System.out.println(result);
		} catch (Exception e) { // 对异常进行处理
			System.out.println("捕获的异常信息为:" + e.getMessage());
		}
		System.out.println("程序继续向下执行...");
	}

	// 下面的方法实现了两个整数相除
	public static int divide(int x, int y) {
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}

package cn.itcast.chapter04.example22;

public class Example22 {
	public static void main(String[] args) {
		// 下面的代码定义了一个try…catch…finally语句用于捕获异常
		try {
			int result = divide(4, 0); // 调用divide()方法
			System.out.println(result);
		} catch (Exception e) { // 对捕获到的异常进行处理
			System.out.println("捕获的异常信息为:" + e.getMessage());
			return; // 用于结束当前语句
		} finally {
			System.out.println("进入finally代码块");
		}
		System.out.println("程序继续向下执行…");
	}

	// 下面的方法实现了两个整数相除
	public static int divide(int x, int y) {
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}
3,throws关键字

在上一小节学习的源文件 Example22.java中,由于调用的是自己写的divide()方法,因此很清楚该方法可能会发生异常。试想一下,如果去调用一个别人写的方法时,是否能知道别人写的方法是否会有异常呢?这是很难做出判断的。针对这种情况,Java中允许在方法的后面使用throws关键字对外声明该方法有可能发生的异常,这样调用者在调用方法时,就明确地知道该方法有异常,并且必须在程序中对异常进行处理,否则编译无法通过。

throws关键字声明抛出异常的语法格式如下:

修饰符 返回值类型 方法名([参数1,参数2...])throws ExceptionType1,ExceptionType2...{
    
}

从上述语法格式中可以看出,throws关键字需要写在方法声明的后面,throws后面需要声明方法中发生异常的类型,通常将这种做法称为方法声明抛出一个异常。

//例如:分别对在devide()方法上声明抛出异常和try…catch处理以及未处理非正常终止的情况——演示

package cn.itcast.chapter04.example23;
public class Example23 {
	public static void main(String[] args) {		
//		int result = divide(4, 2); // 调用divide()方法
//		System.out.println(result);
	}
	// 下面的方法实现了两个整数相除,并使用throws关键字声明抛出异常
	public static int divide(int x, int y) throws Exception {
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}

package cn.itcast.chapter04.example24;
public class Example24 {
	public static void main(String[] args) {
		// 下面的代码定义了一个try…catch语句用于捕获异常
		try {
			int result = divide(4, 2); // 调用divide()方法
			System.out.println(result);
		} catch (Exception e) { // 对捕获到的异常进行处理
			e.printStackTrace(); // 打印捕获的异常信息
		}
	}
	// 下面的方法实现了两个整数相除,并使用throws关键字声明抛出异常
	public static int divide(int x, int y) throws Exception {
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}

package cn.itcast.chapter04.example25;
public class Example25 {
	public static void main(String[] args) throws Exception {
		int result = divide(4, 0); // 调用divide()方法
		System.out.println(result);
	}
	// 下面的方法实现了两个整数相除,并使用throws关键字声明抛出异常
	public static int divide(int x, int y) throws Exception {
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}
4,运行时异常与编译时异常

在实际开发中,经常会在程序编译时产生一些异常,而这些异常必须要进行处理,这种异常被称为编译时异常,也称为checked异常。另外还有一种异常是在程序运行时产生的,这种异常即使不编写异常处理代码,依然可以通过编译,因此被称为运行时异常,也称为unchecked异常

1,编译时异常

在Java中,Exception类中除了RuntimeException类及其子类都是编译时异常。编译时异常的特点是Java编译器会对其进行检查,如果出现异常就必须对异常进行处理,否则程序无法通过编译。处理编译时期的异常有两种方式:

  1. 使用try…catch语句对异常进行捕获
  2. 使用throws关键字声明抛出异常,调用者对其处理
2,运行时异常

RuntimeException类及其子类都是运行时异常。运行时异常的特点是Java编译器不会对其进行检查,也就是说,当程序中出现这类异常时,即使没有使用try…catch语句捕获或使用throws关键字声明抛出,程序也能编译通过。运行时异常一般是由程序中的逻辑错误引起的,在程序运行时无法恢复。比如通过数组的角标访问数组的元素时,如果超过了数组的最大角标,就会发生运行时异常,代码如下所示:

// 例如

int[] arr=new int[5]
System.out.println(arr[5]);

上面代码中,由于数组arr的length为5,最大角标应为4,当使用arr[6]访问数组中的元素就会发生数组角标越界的异常。

5,自定义异常

JDK中定义了大量的异常类,虽然这些异常类可以描述编程时出现的大部分异常情况,但是在程序开发中有时可能需要描述程序中特有的异常情况,例如文件4-38中在divide()方法中不允许被除数为负数。为了解决这个问题,在Java中允许用户自定义异常,但自定义的异常类必须继承自Exception或其子类。

//例如:如何自定义异常

package cn.itcast.chapter04.example26;

// 下面的代码是自定义一个异常类继承自Exception
public class DivideByMinusException extends Exception {
	public DivideByMinusException() {
		super(); // 调用Exception无参的构造方法
	}

	public DivideByMinusException(String message) {
		super(message); // 调用Exception有参的构造方法
	}
}

在实际开发中,如果没有特殊的要求,自定义的异常类只需继承Exception类,在构造方法中使用super()语句调用Exception的构造方法即可。
既然自定义了异常,那么该如何使用呢?这时就需要用到throw关键字,throw关键字用于在方法中声明抛出异常的实例对象,其语法格式如下:

throw Exception 异常对象
//例如:重新对源文件Example25中的divide()方法进行改写,在divide()方法中判断被除数是否为负数,如果为负数,就使用throw关键字在方法中向调用者抛出自定义的DivideByMinusException异常对象

package cn.itcast.chapter04.example26;
public class Example26 {
	public static void main(String[] args) {
		int result = divide(4, -2); // 调用divide()方法,传入一个负数作为被除数
		System.out.println(result);
	}
	// 下面的方法实现了两个整数相除,
	public static int divide(int x, int y) {
		if (y < 0) {
			//throw new DivideByMinusException("除数是负数");// 使用throw关键字声明异常对象
		}
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}

从编译结果可以看出,程序在编译时就发生了异常。这是因为在一个方法内使用throw关键字抛出异常对象时,需要使用try…catch语句对抛出的异常进行处理,或者在divide()方法上使用throws关键字声明抛出异常,由该方法的调用者负责处理

//例如:为了解决上面的问题,可以对源文件Example26进行修改,在divide()方法上,使用throws关键子声明抛出DivideByMinusException异常,并在调用该方法时使用try…catch语句对异常进行处理

package cn.itcast.chapter04.example27;
public class Example27 {
	public static void main(String[] args) {
		// 下面的代码定义了一个try…catch语句用于捕获异常
		try {
			int result = divide(4, -2); // 调用divide()方法,传入一个负数作为被除数
			System.out.println(result);
		} catch (DivideByMinusException e) { // 对捕获到的异常进行处理
			System.out.println(e.getMessage()); // 打印捕获的异常信息
		}
	}
	// 下面的方法实现了两个整数相除,并使用throws关键字声明抛出自定义异常
	public static int divide(int x, int y) throws DivideByMinusException {
		if (y < 0) {
			throw new DivideByMinusException("除数是负数");// 使用throw关键字声明异常对象
		}
		int result = x / y; // 定义一个变量result记录两个数相除的结果
		return result; // 将结果返回
	}
}

在Java中,针对类、成员方法和属性提供了四种访问级别,分别是private、default、protected和public。接下来通过一个图将这四种控制级别由小到大依次列出,如下图所示。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rptkyn7o-1587969466278)(C:\Users\Administrator\Desktop\笔记\java图片\1587968256133.png)]

上图中展示了Java中的四种访问控制级别,具体介绍如下:

  • private(类访问级别) :如果类的成员被private访问控制符来修饰,则这个成员只能被该类的其他成员访问,其他类无法直接访问。类的良好封装就是通过private关键字来实现的。
  • default(包访问级别) :如果一个类或者类的成员不使用任何访问控制符修饰,则称它为默认访问控制级别,这个类或者类的成员只能被本包中的其他类访问。
  • protected(子类访问级别) :如果一个类的成员被protected访问控制符修饰,那么这个成员既能被同一包下的其他类访问,也能被不同包下该类的子类访问。
  • public(公共访问级别) :这是一个最宽松的访问控制级别,如果一个类或者类的成员被public访问控制符修饰,那么这个类或者类的成员能被所有的类访问,不管访问类与被访问类是否在同一个包中。
访问范围privatedefaultprotectedpublic
同一类中
同一包中
子类中
全局范围

6,访问控制

<9>,Java APL

API(Application Programming Interface)指的是应用程序编程接口

1,String 类和StringBuffer 类

在Java中定义了String 和StringRuffer 两个类来封装字符串,并提供了一系列操作字符串的方法,他梦都位于java.lang包中,因此不需要导包就可以直接使用。

1.1,String 类的初始化

在操作String 类之前,需要对String 类进行初始化,在Java中可以通过以下两种方法对String类进行初始化,具体如下:

  • 使用字符串常量直接初始化一个String对象,具体如下
String strl = "abc"
  • 使用String 的构造方法初始化字符串对象,String 类的构造方法如下

    方法声明功能描述
    String()创建一个内容为空的字符串
    String(String value)根据指定的字符串内容创建对象
    String(char[] value)根据指定的字符数组创建对象
// 例如:学习String类的使用

package cn.itcast.chapter05.example01;
/**
 * String类构造方法的使用
 */
public class Example01 {
	public static void main(String[] args) throws Exception {
		// 创建一个空的字符串
		String str1 = new String();
		// 创建一个内容为abcd的字符串
		String str2 = new String("abcd");
		// 创建一个内容为字符数组的字符串
		char[] charArray = new char[] { 'D', 'E', 'F' };
		String str3 = new String(charArray);
		System.out.println("a" + str1 + "b");
		System.out.println(str2);
		System.out.println(str3);
	}
}
1.2,String 类的常见操作

String类在实际开发中的应用非常广泛,因此灵活地使用String类是非常重要的,接下来介绍String类常用的一些方法,如下所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ssa4A5I5-1587969466279)(C:\Users\Administrator\Desktop\笔记\java图片\1587967612606.png)]

// 例如:需要对字符串进行一些基本操作,如获得字符串长度、获得指定位置的字符等。String类针对每一个操作都提供了对应的方法

package cn.itcast.chapter05.example02;
/**
 * 字符串的基本操作
 */
public class Example02 {
	public static void main(String[] args) {
		String s = "ababcdedcba"; // 声明字符串
		System.out.println("字符串的长度为:" + s.length());// 获取字符串长度,即字符个数
		System.out.println("字符串中第一个字符:" + s.charAt(0));
		System.out.println("字符c第一次出现的位置:" + s.indexOf('c'));
		System.out.println("字符c最后一次出现的位置:" + s.lastIndexOf('c'));
		System.out.println("子字符串第一次出现的位置:" + s.indexOf("ab"));
		System.out.println("子字符串最后一次出现的位置:" + s.lastIndexOf("ab"));
	}
}
1.3,String Buffer类

由于字符串是常量,因此一旦创建,其内容和长度是不可改变的。如果需要对一个字符串进行修改,则只能创建新的字符串。为了便于对字符串进行修改,在JDK中提供了一个StringBuffer类(也称字符串缓冲区)。StringBuffer类和String类最大的区别在于它的内容和长度都是可以改变的。StringBuffer类似一个字符容器,当在其中添加或删除字符时,并不会产生新的StringBuffer对象。

针对添加和删除字符的操作,StringBuffer类提供了一系列的方法,具体如下表所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9S3TplWy-1587969466280)(C:\Users\Administrator\Desktop\笔记\java图片\1587967928354.png)]

// 案例:

package cn.itcast.chapter05.example08;
/*
 * StringBuffer的常用方法
 */
public class Example08 {
	public static void main(String[] args) {
		System.out.println("1、添加------------------------");
		add();
		System.out.println("2、删除------------------------");
		remove();
		System.out.println("3、修改------------------------");
		alter();
	}
	public static void add() {
		StringBuffer sb = new StringBuffer(); // 定义一个字符串缓冲区
		sb.append("abcdefg"); // 在末尾添加字符串
		System.out.println("append添加结果:" + sb);
		sb.insert(2, "123"); // 在指定位置插入字符串
		System.out.println("insert添加结果:" + sb);
	}
	public static void remove() {
		StringBuffer sb = new StringBuffer("abcdefg");
		sb.delete(1, 5); // 指定范围删除
		System.out.println("删除指定位置结果:" + sb);
		sb.deleteCharAt(2); // 指定位置删除
		System.out.println("删除指定位置结果:" + sb);
		sb.delete(0, sb.length()); // 清空缓冲区
		System.out.println("清空缓冲区结果:" + sb);
	}
	public static void alter() {
		StringBuffer sb = new StringBuffer("abcdef");
		sb.setCharAt(1, 'p'); // 修改指定位置字符
		System.out.println("修改指定位置字符结果:" + sb);
		sb.replace(1, 3, "qq"); // 替换指定位置字符串或字符
		System.out.println("替换指定位置字符(串)结果:" + sb);
		System.out.println("字符串翻转结果:" + sb.reverse());
	}
}

StringBuffer类和String类有很多相似之处,初学者在使用时很容易混淆。接下来针对这两个类进行对比,简单归纳一下两者的不同,具体如下:

  1. String类表示的字符串是常量,一旦创建后,内容和长度都是无法改变的。而StringBuffer表示字符容器,其内容和长度可以随时修改。在操作字符串时,如果该字符串仅用于表示数据类型,则使用String类即可,但是如果需要对字符串中的字符进行增删操作,则使用StringBuffer类。
  2. String类覆盖了Object类的equals()方法,而StringBuffer类没有覆盖Object类的equals()方法,具体示例如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MgSXbkyY-1587969466282)(C:\Users\Administrator\Desktop\笔记\java图片\1587968128239.png)]
  3. String类对象可以用操作符“+”进行连接,而StringBuffer类对象之间不能,具体示例如下:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yLybqKaz-1587969466283)(C:\Users\Administrator\Desktop\笔记\java图片\1587968460269.png)]
1.4,记录一个子串在整串中出现的次数

请查看第10周源代码task0

2,System 类和Runtime 类

2.1,System类

System类对读者来说并不陌生,因为在之前所学知识中,需要打印结果时,使用的都是“System.out.println();”语句,这句代码中就使用了System类。System类定义了一些与系统相关的属性和方法,它所提供的属性和方法都是静态的,因此,想要引用这些属性和方法,直接使用System类调用即可

System类的常用方法如下表所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0aJf5nm-1587969466285)(C:\Users\Administrator\Desktop\笔记\java图片\1587968642094.png)]

1,getProperties()方法

System类的getProperties()方法用于获取当前系统的全部属性,该方法会返回一个Properties对象,其中封装了系统的所有属性,这些属性是以键值对形式存在的。

2,currentTimeMillis()

currentTimeMillis()方法返回一个long类型的值,该值表示当前时间与1970年1月1日0点0分0秒之间的时间差,单位是毫秒,通常也将该值称作时间戳。

3,arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

arraycopy()方法用于将一个数组中的元素快速拷贝到另一个数组。其中的参数具体作用如下:

  • src:表示源数组。
  • dest:表示目标数组。
  • srcPos:表示源数组中拷贝元素的起始位置。
  • destPos:表示拷贝到目标数组的起始位置。
  • length:表示拷贝元素的个数。
2.2,Runtime 类

Runtime类用于表示虚拟机运行时的状态,它用于封装JVM虚拟机进程。每次使用java命令启动虚拟机都对应一个Runtime实例,并且只有一个实例,因此该类采用单例模式进行设计,对象不可以直接实例化。若想在程序中获得一个Runtime实例,只能通过以下方式:

Runtime run = Runtimr.getRuntime();
//案例: Runtime类中提供了一个exec()方法,该方法用于执行一个dos命令,从而实现和在命令行窗口中输入dos命令同样的效果。例如,通过运行“notepad.exe”命令打开一个Windows自带的记事本程序

package cn.itcast.chapter05.example13;
import java.io.IOException;
/**
 * 使用exec()方法打开记事本
 */
public class Example13 {
	public static void main(String[] args) throws IOException {
		Runtime rt = Runtime.getRuntime(); // 创建Runtime实例对象
		rt.exec("notepad.exe"); // 调用exec()方法
	}
}

// 案例:实现打开的记事本并在3秒后自动关闭的功能
package cn.itcast.chapter05.example14;
/**
 * 打开的记事本并在3秒后自动关闭
 */
public class Example14 {
	public static void main(String[] args) throws Exception {
		Runtime rt = Runtime.getRuntime(); // 创建一个Runtime实例对象
		Process process = rt.exec("notepad.exe");// 得到表示进程的Process对象
		Thread.sleep(3000); // 程序休眠3秒
		process.destroy(); // 杀掉进程
	}
}

3,Math 类和 Random 类

4,包装类

4.1,字符串排序程序设计

5,JDK新特性——switch 语句支持字符串类型

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值