Java学习笔记(待更新)

文章目录

  • 一、进制数值以及数据编码
    • 1、原码
    • 2、反码
    • 3、补码
  • 二、java概述
    • 1、第一个java程序
  • 三、数据类型和运算符号
    • 1、标识符Identifier
    • 2、数据类型
    • 3、常量和变量
    • 4、运算符号
    • 4、运算符的优先级
    • 5、基本数据类型的转换
      • 5.1、强制转换
  • 四、流程控制语句
    • 1、if循环结构
    • 2、if-else双分支选择结构
    • 3、练习
    • 4、if-else 多分支结构
    • 5、switch多分支结构
    • 6、while循环
    • 7、do-while循环
    • 8、for循环
    • 9、跳转语句break和continue
    • 10、跳转语句return
    • 11、多重循环(循环嵌套)
    • 12、递归结构
  • 五、数组
    • 1、概述
    • 2、练习
    • 3、二维数组
    • 4、数组的拷贝
  • 六、面向对象
    • 1、概述
      • 1.1对象和类的总结:
      • 1.2 对象的特征:
    • 2、创建和使用对象
    • 3、局部变量和成员变量
    • 4、相关内存分析
    • 5、构造方法
    • 6、This关键字
    • 7、static关键字
    • 8、代码块
    • 9、pakcage
    • 10、import
    • 11、封装
    • 12、继承
    • 13、Super关键字
    • 14、方法重写
    • 15、抽象类(Abstract)
    • 16、final的用法
    • 17、Object类
    • 18、多态
    • 19、接口
    • 20、内部类
    • 21、垃圾回收机制
    • 22、小练习
  • 七、异常处理
    • 1、概念以及常见的异常类型
    • 2、try-catch捕获异常
    • 3、try-catch-finally捕获异常
    • 4、自定义异常
  • 八、常用类
    • 1、包装类
    • 2、String类
    • 3、StringBuffer类
    • 4、Date时间类
    • 5、Calendar类
    • 6、Math类
    • 7、枚举:

有很多图片暂时没有花时间去一张张的上传,后期,会花时间整理一下,抱歉。当然,您可以留言。

一、进制数值以及数据编码

1、原码

原码是只将最高位作为符号(0表示正,1表示负),其他数字代表数值本身的绝对值的数字的表示方式

  • 数字6在计算机中的表示方式为:0000 0110
  • 数字-6在计算机中的原码表示为:1000 0100

2、反码

反码的表示规则为:如果是正数,则表示方法和原码一样,如果是负数,则保留符号位1,然后将这个数字的原码按照原码按照每位取反,则得到这个数的反码表示形式。

数字6在计算机中的表现形式,原码:0000 0110.
数字-6在计算机中的反码为: 1111 1001

3、补码

负数的补码就是在反码的基础上+1,正数的原码反码补码都是一样的。在计算机中,补码-128代表了-0。

补码设计的目的是:

  • 使符号位能与有效值部分一起参加运算。
  • 使减法转为加法运算,简化计算机中运算器的路线设计。

二、java概述

java发展过程的转折点:1999年Java被分成j2se,j2ee,j2m,jsp/Servlet技术诞生。

java的核心优势:跨平台。

JVM(java virtul machine)

  • jvm是一种规范,一个虚拟的用来执行bytecodes字节码的虚拟计算机。
  • java虚拟机时java的核心技术,跨平台的基础。
  • 可以使用软件来实现它,可以自己写jvm.
  • 可以用硬件来实现

java代码的执行流程:通过“编译器”将java源代码编译成java字节码文件(.class),再由解释器将java字节码文件解释为对应机器语言并执行。

JVM的特点如下:

  • java时跨平台的(jvm特性使得代码在各平台运行)
  • java时简单的(取消指针,自动内存管理)
  • java是安全的(取消指针,避免数组越界)
  • java是完全面向对象的
  • java是健壮的

1、第一个java程序

public class HelloWorld{
	public static void main(String[] args){
	    //单行注释
	    /*
	    多行注释
	    */
	    /**
	    *文档注释(可以通过javadoc命令,生成程序的API文档)
	    */
		System.out.println("hallo");
	}
}

注:

  • 注意缩进
  • 成对变成(括号、引号都需要写完整,再往里面添加内容)
  • 见名知义
  • 多注释
  • 编译:源代码–class
  • 反编译: class–源代码

三、数据类型和运算符号

1、标识符Identifier

作用:常量,变量,方法,类和包等的名称
命令规则:

  • 必须以字母,_下划线、美元符$开头。
  • 其它部分可以是字母,下划线,美元符号和数字的任意组合
  • 大小写敏感,长度不限
  • 不可以是java的关键字

注意:

  • java通常采用unicode.

IdentifiedDemo.java

  /*
标识符命名规范
  硬性规定:
  1、标识符必须以字母,下划线或者美元符号开头
  2、其他部分必须是字母,数字,下划线或者美元符号,但是不能出现特殊符号,
  3、标识符大小写敏感
  4、不能是java的关键字或者保留字(留给系统使用的特殊含义的字符串)
  
  常规建议:
  1、驼峰标识
      类名,接口名首字母大写
	  方法,变量首字母小写
	  多个单词拼接表示一个标识符的时候,每个单词的首字母大写
  2、见名知义
      通过标识符的名称能知道代表的含义
	  千万不要写拼音
	  
  3、java建议擦采用unicode
  
*/

public class IdentifiedDemo{
	public static void main(String[] args){
		int a = 10;
		int $b = 20;
		int aa  = 10;
	}
}


2、数据类型

基本数据类型:
    数值型:
        整数类型:(byte,short,int,long)
            整形变量默认为int,声明log型常量可以在数字后加L(建议大写)
        浮点型:
            float:单精度类型,尾数可以精确到7位数字。
            doulbe类型:双精度类型,精度是float的两倍,
            浮点型默认为double,要使用float,需要在数字后面加F(建议大写)
            浮点型会有精度损失,涉及金融,需要使用BigDecimal类
    字符型(char)
        单引号用来表示字符常量。'A'表示一个字符,"A"表示一个字符串
        char类用来表示在Unicode编码中的字符。
        char类在内存中存储的是该字符的Unicode编码值,所以char类型可以当作int类型来处理。
    布尔型(boolean)
        有两个值:true和 false
        布尔类型判断建议这样写if(whether && !done)

引用数据类型:
    类(class)
    接口(interface)
    数组

DataTypeDemo.java

/*
数据类型
	java是使用强类型语言
		强类型表示,变量定义的时候必须显示的声明数据的类型是什么,  java
		弱类型表示,变量定义的时候可以不用声明数据的类型是什么,系统自动根据初始化的值去判断数据类型,js,python,scala
	
	java数据类型
		基本数据类型(4类8种)
		  整数类型:byte,int,short,long(不同类型表示不同的精度)
			byte:使用一个字节存储,因此范围是 -128-127
			short: 使用两个字节存储,因此范围是-32768-32767
			int:使用4个字节存储,因此范围是正负21亿
			log: 使用8个字节存储
			注意:
				在使用整型类型的时候,默认都是int类型,
				如果要用long类型,就必须要在数字的后面添加L,建议添加大写L,小写容易混淆。
				
		  浮点类型:float,double  小数类型:使用小数点,使用科学计数法
			float:单精度,小数点后7位
			double:双精度,float的两倍
			注意:
				默认浮点类型是double类型
				使用float要在数字后面添加F  
				浮点类型并不能表示一个精确的值,会损失一定的精度
		  字符类型:char 
			 占用2个字节,使用''表示
			 字符串使用""表四
		  布尔类型:boolean
			只有true和false两个值,在存储的时候占1位
		    
		引用数据类型
*/

public class DataTypeDemo{
	
	public static void main(String[] args){
	//	byte b = 128;
	//	short s = 4444; 
	//	int i = 111111111;
	//log l = 121212121212L;
	//int  a = 31111111111;
	//long b = 31111111111L;
	//float a  =  2.222222222222F;
	//float b  =  2.22222222222222222222F;
	//System.out.println( a == b);
	//表示一个字符
	char  a  = 'a';
	System.out.println(a+1);
	//表示一个字符串,一个字符序列
	String s = "A";
	System.out.println(a==97);
	char ch = '\t';
	System.out.println('['+ch+']');
	double d = 3.14159;
	int e = (int)d;
	System.out.println(e);
	
	

	}
	
}

3、常量和变量

常量:数据在运行的过程中值不发生改变。例如:圆周率

变量:数据在运行的过程中值会发生改变。例如2d游戏中,代表人物的位置,x,y坐标在人物的移动过程中是会变化的。

java是一种强类型语言,每个变量都必须声明类型。

java变量是程序中最基本的单元,包括变量名,变量类和作用域。

final常量:使用final修饰的变量,只能被初始化一次,变成了常量。

final常量是有名称的,要注意:

变量在使用前必须声明:格式为:
    type varName [=value] [,varName[=value]];
    注意:
        每个变量都必须又类型,类型可以是基本类型,也可以是引用类型。
        变量名必须是合法的标识符。
变量常量的命名规范:
    所有变量、方法、类名:见名知意。
    变量、方法名:
        首字母小写和驼峰原则
        run(),runRoun(),ageNew
    常量:
        大写字母和下划线:MAX_VALUE
    类名:
        首字母大写和驼峰原则: Man,GoodMan

ConstantAndVar.java

/*
常量和变量
	常量: 在程序运行过程中,值不会发生改变的量叫做常量
	变量:  在程序运行过程中,值会发生改变
	
	变量;变量名称,变量类型,作用域
		1、先声明,后赋值
			int a; 声明
			a = 10; 赋值
		2、声明+赋值
	常量:
		用final关键字修饰的变量称之为最终常量,值不可修改。
	注意:
		在类内,方法外定义的变量叫成员变量,会存在默认值
		在方法内,定义的变量必须要进行初始化操作,不会存在默认值
		在一行内可以定义多个变量,但不推荐,每个变量最好单独一行
		给变量赋值的过程中,变量的值成为常量
		
*/
public class ConstantAndVar{
	static int d;
	public static void main(String[] args){
		int a;
		a = 10;
		//声明+赋值
		//int b = 20;
		//int c;
		//System.out.println(d);
		//int x=10,y=10;
		System.out.println(a);
		a=30;
		System.out.println(a);
		final int c = 20;
		System.out.println(c);
		//c = 30;
		//System.out.println(c);
	}
}

4、运算符号

java支持以下运算符号:

算术运算符: +-*/%++--

	+加法

	-:减法

	*:乘法

	/:除法

	%:取商

	++:自增

		a++(表示先输出a再自加1)
		++a(表示a先自加1,再输出)
    	例如:
    		int a = 3;
			int b = a++; //执行完b=3,先给b赋值,再自增。执行后a=4
			int c = ++a; //执行完c=5.先自增(4+1),再给c赋值
    --:自减
        a--(表示先输出a再自减a)
        --a(表示先自减a再输出a)
        
  注意:
        整数运算:
        	如果有两个操作数有一个为Long,则结果也为long
        	没有long时,结果为int.即使操作数全为shot,byte,结果也为int.
       	浮点运算:
        	如果两个操作数有一个为double,则结果为double.
        	只有两个操作数都是float,则结果才为float.

赋值运算符:=

扩展赋值运算符:+=,-=,*=,/=

关系运算符:>, <, >=,<=,==,!=

​ 注意:==比较的是地址是否相同,而equals比较的是两个内容是否相同。

逻辑运算符: &&(短路与),||(短路或),!(逻辑反)

位运算符: &(逻辑与),|(逻辑或),^(逻辑异或),>>(右移,,右边空位补0,带符号), <<(左移,左边空位最高位补符号位,带符号),>>>(右移动,不带符号)

条件运算符: ?:(三目运算符)

  • x?y:z (x为boolean表达式,先计算x的值,若为ture,则结果为y表达式的值,否则为z表达式的值)

注意:&和&&的区别:

  • & / |:无论任何情况,&两边的表达式都会参与计算
  • && / ||:当左边的结果为false,则将不会计算右边的表达式

OperatorDemo.java

/*
  运算符:
	算术运算符: +,-,*,/,%,++,--
	赋值运算符:=
		java中=表示赋值运算符,==表示相等的操作
	扩展运算符:+=,-=,*=,/=
	关系运算符:>,<,>=,<=,==,!
	逻辑运算符: &&,||, !
		逻辑运算符一般两边的值不是一个具体的值,而是一个表达式
	位运算符: &, |, ^, ~,>>,<<,>>>
	条件运算符: ? :
*/

public class OperatorDemo{
	
	public static void main(String[]  args){
		int a = 1;
		int b = 2;
		System.out.println(a+b);
		System.out.println(a-b);
		System.out.println(a*b);
		System.out.println(a/b);
		System.out.println(a%b);
		//++,表示在变量的基础上+1,谁在前,先运算谁
		System.out.println(a++);
		System.out.println(++a);
		//--,表示在变量的基础上-1,谁在前,先运算谁
		System.out.println(a--);
		System.out.println(--a);
		
		System.out.println(++b+b++);
		//扩展赋值运算符
		int c = 1;
		//下述两种写法一样,表示加2的操作
		c = c + 2;
		c+=2;
		//类型转换的问题,d是byte,d+1整体变成int类型,需要将int类型转换为byte,会有精度损失,因此需要强制转换
		//建议在进行操作的时候使用扩展赋值运算符
		byte d = 10;
		//d = d+1;
		d+=1;
		
		//关系运算符:返回的值是布尔类型,返回的结果为True,或False
		System.out.println(1>2);
		System.out.println(1<2);
		System.out.println(1>=2);
		System.out.println(1<=2);
		System.out.println(1==2);
		System.out.println(1!=2);
		
		//逻辑运算符
		/*
			&&:表示短路与
				两边表达式从左向右开始对比,如果左边的表达式是false,右边不需要进行判断
			||:表示短路或,两边表达式中只要有一个是true,整体结果就是true,
				两边表达式从左向右开始对比,如果左边的表达式为true,右边不需要参与计算
			&:与运算符,两边都会参与计算
			|:或运算符,两边都会参与计算
			
		*/
		System.out.println(3>5 && 3<4);
		System.out.println(3>5 || 3<4);
		System.out.println(3>5 & 3<4);
		System.out.println(3>5 | 3<4);
		// !取反
		System.out.println(!true);
		System.out.println(!false);
		
		//位运算符:只能操作数值,操作的时候会转换成二进制进行计算
		System.out.println(4 & 5);
		System.out.println(4 | 5);
		System.out.println(4 ^ 5);
		//移码,补码,原码,反码
		System.out.println(~4);
		
		
		//左移位运算,按位向左移动
		System.out.println(2<<2);
		//右移位运算,按位向右移动
		System.out.println(16>>2);
		
		//条件运算符/三目运算符,
		//运算的时候需要跟一个表达式,表达式如果是true,则返回?后的结果,如果表达式为false,
		System.out.println(3>2 ?3:2);
		
		/*
		基本数据类型之间的转换:
			自动转换
			强制转换
			注意: 
				1、在进行算数运算的操作的时候,必须要求数据类型一致,否则无法操作
				2、在运算过程中,如果两个值的类型不一致,会自动将小的类型转换为大的类型
				3、在运算过程中用,可以手动强制转换,将大的类型转换为小的类型
		*/
		byte bb = 10;
		int aa = 200;
		byte cc;
		cc = (byte)(aa+bb);
		System.out.println((byte)270);
		
	}
}

4、运算符的优先级

赋值<三目<逻辑<关系<算术<单目

一般用()控制优先级比较好。

5、基本数据类型的转换

在赋值运算或者算数运算时,要求数据类型相同,否则要进行类型转换。

转换方式:

  • 自动转换
  • 强制转换

除了Boolean类型外,所有基本的数据类型,因为精度不同,都需要考虑这个问题。

除了boolean类型外,基本数据类型包括:整型,浮点型,字符型。

整型,浮点型,字符型数据可以混合运算。

不同类型的数据转为同一类型,然后进行计算(转换从低精度到高精度转换)

5.1、强制转换

int n = 270;
System.out.println("n="+n);
byte b = (byte)n;
System.out.println("b="+b);

如代码块所示,强制转换需要在转换目标前加上“(需要转换成的类型)”

要点:=的右侧,所有变量先转换为字节数最多的数据类型,再计算。

​ =的两侧,左侧宽度>右侧宽度 自动转换

​ 左侧宽度<右侧宽度 强制转换

特例:可以将整型常量直接赋值给byte,short,char等类型变量,而不需要进行强制类型转换,只要不超出其表数范围:

  • short b = 12; //合法
  • short b = 1234567; //非法

四、流程控制语句

程序设计中有三种基本流程结构:顺序结构,分支结构,循环结构:

1、if循环结构

对条件表达式进行一次测试,若测试为真,则执行下面的语句,否则跳过该语句

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-skPg1mrn-1587198271491)(C:\myfiles\files\javaStudyExercise\javaStudyExercise\notes\images\if.PNG)]

IfBack.java

public class IfBack{
	public static void main(String[] args){
		//Math.random 生成一个[0,1)的随机数
		double i = 6 * Math.random();
		double j = 6 * Math.random();
		double k = 6 * Math.random();
		int count = (int)(i + j + k);
		if(count > 15){
			System.out.println("今天受气不错");
		}
		if(count >= 10 && count <= 15){
			System.out.println("今天手气一般");
		}
		if(count < 10){
			System.out.println("今天手气不怎么样");
		}
		System.out.println("得了"+ count + "分");
	}
}

2、if-else双分支选择结构

当条件表达式为真时,执行语句块1,否则,执行语句块2.也就是else.

![

](C:\myfiles\files\javaStudyExercise\javaStudyExercise\notes\images\if-else.PNG)

IfElseDemo.java

public class IfElseDemo{
	public static void main(String[] args){
		//计算圆的周长和面积
		double r = 4 * Math.random();
		double area =  Math.PI * Math.pow(r,2);
		double circle = 2 * Math.PI * r;
		System.out.println("半径为:" + r);
		System.out.println("面积为:" + area);
		System.out.println("周长为:" + circle);
		if(area >= circle){
			System.out.println("面积大于周长");
		}else{
			System.out.println("周长大于面积");
		}
	}
}

3、练习

NarcissusNumber.java

查找水仙花数

public class NarcissusNumber{
	public static void main(String[] args){
		for(int i=100;i<1000;i++){
			if(isLotus(i)){
				System.out.print(i+"\t");
			}
		}
	}
	
	private static boolean isLotus(int lotus){
		boolean flag = false;
		int a = lotus%10;
		int b = lotus/10%10;
		int c = lotus/100%10;
		if(Math.pow(a,3)+Math.pow(b,3)+Math.pow(c,3)==lotus){
			flag=true;
		}
		return flag;
		
	}
	
}

MembersInfo.java

/*
录入会员信息
判断录入的会员号是否合法
需要用到Scanner
*/
import java.util.Scanner;
public class MembersInfo{
	public static void main(String[] args){
		//创建一个Scanner对象
		Scanner sc = new Scanner(System.in);
		System.out.println("欢迎登录本公司会员系统");
		System.out.println("添加会员名");
		String memberName = sc.nextLine();
		System.out.println("添加会员号");
		String memberNum = sc.nextLine();
		int memberNums = Integer.valueOf(memberNum);
		System.out.println("输入会员生日");
		String memberBir = sc.nextLine();
		if(memberNums==123){
			System.out.println("123 是无效的会员号,输入信息无效");
		}else{
			System.out.println("输入的会员信息是:");
			System.out.println("会员名:"+memberName+"\t会员号:"+memberNums+"\t会员生日"+memrBir);
		}
		
		
	} 
}

LuckyDraw.java

 /*
会员号的百位数字等于产生的随机数字即为幸运会员
*/
import java.util.Scanner;
public class LuckyDraw{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("欢迎登录会员抽奖系统");
		System.out.println("请输入4位会员号码:");
		int memberNum = sc.nextInt();
		int hundred = (memberNum % 1000)/100;
		int luckyNum = (int)(10*Math.random());
		if(hundred == luckyNum){
			System.out.println("恭喜 "+memberNum+"\t您中奖了");
		}else{
			System.out.println("谢谢参与:"+memberNum);
		}
		System.out.println("中将数字为:"+luckyNum);
		System.out.println("百位数字为:"+hundred);
	}
}

WelcomQing.java

/*
?会员登录,如果用户名是 ‘青’,并且密码 123, ? 输入欢迎您青, ? 否则输出,对不起,您不是会员
*/

import java.util.Scanner;
public class WelcomQing{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("会员登录,请输入会员信息");
		System.out.println("请输入会员名");
		String memberName = sc.nextLine();
		System.out.println("请输入会员密码");
		String memberSecret = sc.nextLine();
		int memberSecrets = Integer.valueOf(memberSecret);
		String memName = "青";
		// == 比较的是两个字符串所指的地址是否相同,而要比较两个字符串内容是否相同,用s1.equals(s2)
		if(memberSecrets==123 && memberName.equals(memName)){
			System.out.println("欢迎会员青");
		}else{
			System.out.println("输入信息有误,您或许不是会员,请确认用户名和密码");
		}
	}
}

MoveDesk.java

/*
小孩儿搬桌子:年龄大于7岁,可以搬动桌子,大于5岁性别为男也可以搬动桌子,否则不可以,太小了
*/

import java.util.Scanner;
public class MoveDesk{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入您的性别[F/M](男/女的意思)");
		String Sex = sc.nextLine();
		System.out.println("请输入您的年龄");
		int Age = (int)sc.nextInt();
		String sex = "F";
		
		if(Age>7){
			System.out.println("可以搬动桌子");
		}else if(Sex.equals(sex) && Age > 5){
			System.out.println("可以搬动桌子");
		}else{
			System.out.println("太小了");
		}
		
	}
}

EncryptNum.java

/*
某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,
加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,
第二位和第三位交换
*/
import java.util.Scanner;

public class EncryptNum{
	
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入一个4位正整数:\t");
		String numString = sc.nextLine();
		Boolean strResult = numString.matches("[0-9]{4}");
		if(strResult == true){
			int numInt = Integer.valueOf(numString);
			//System.out.println(numInt);	
			int singDigit = numInt % 10;
			int tensDigit = (numInt % 100) / 10;
			int hundredDigit = (numInt % 1000) / 100;
			int thousandDigit = numInt /1000;
			int singDigitEncrypt = (singDigit+5) % 10;
			int tensDigitEncrypt = (tensDigit+5) % 10;
			int hundredDigitEncrypt = (hundredDigit+5)%10;
			int thousandDigitEncrypt = (thousandDigit+5) % 10;
			System.out.println("加密后的数字为:\t"+singDigitEncrypt+tensDigitEncrypt+hundredDigitEncrypt+thousandDigitEncrypt);
		}else{
			System.out.println("必须输入4位正整数");
		}		
	}
}

Addcust.java

import java.util.Scanner;

public class AddCust{
	
	public static void main(String[] args){
		
		System.out.println("欢迎光临我的公园");
		System.out.println("添加用户信息");
		//创建Scanner对象
		Scanner  sc = new Scanner(System.in);
		System.out.println("请输入会员码<4位正数>");
		String number = sc.nextLine();
		System.out.println("请输入会员生日<日/月/>");
		String birthday = sc.nextLine();
		System.out.println("请输入会员积分");
		String score = sc.nextLine();
		
		if(number.length()==4){
			System.out.println("会员信息如下:");
			System.out.println(number+"\t"+birthday+"\t"+score);
		}else{
			System.out.println("会员信息错误,必须为4位会员号");
		}
	}
}

PrincipalAndInterest.java

//3.银行利率表如下表所示,请计算存款10000元,活期1年、活期2年,定期1年,定期2年后的本息合计。
public class PrincipalAndInterest{
	public static void main(String[] args){
		int principal = 10000;
		double oneYearDynamicInterest = 0.0035;
		double oneYearStaticInterest = 0.015;
		double twoYearstaticInterest = 0.021;
		double oneDynamicAllCrash = principal*(1+oneYearDynamicInterest);
		double twoDynamicAllCrash = (principal*(1+oneYearDynamicInterest))*(1+oneYearDynamicInterest);
		double oneStaticAllCrash = principal*(1+oneYearStaticInterest);
		double twoStaticAllCrash = (principal*(1+twoYearstaticInterest))*(1+twoYearstaticInterest);
		
		System.out.println("本金:\t"+principal);
		System.out.println("活期存款1年本息总计:\t"+Math.round(oneDynamicAllCrash));
		System.out.println("活期存款2年本息总计:\t"+Math.round(twoDynamicAllCrash));
		System.out.println("定期存款1年本息总计:\t"+Math.round(oneStaticAllCrash));
		System.out.println("定期存款2年本息总计:\t"+Math.round(twoStaticAllCrash));
		
		
	}
}

4、if-else 多分支结构

if(boolean表达式){
	语句块1}else if{boolean表达式2}{
	语句块2....
}else{
}
可以有任意多个分支

ScoreRank.java

/*
对学生的成绩评测
>=90 优秀
>=80 良好
>=60 中等
<60 差
*/
import java.util.Scanner;
public class ScoreRank{
	public static void main(String[] args){
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入考分");
	int score = (int)sc.nextInt();
	if(score>=90){
		System.out.println("优秀");
	}else if(score>=80){
		System.out.println("良好");
	}else if(score>=60){
		System.out.println("中等");
	}else{
		System.out.println("差");
	}
  }
}

BuyCars.java

/*
我想买车,买什么车决定我在银行有多少存款
	如果我的存款超过500万,就买凯迪拉克
	否则如果超过100万,就买帕萨特
	否则如果超过50完,就买伊兰特
	否则如果超过10万,就买奥托
	否则就买捷安特
*/

import java.util.Scanner;
public class BuyCars{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入你的存款数");
		int despoit = sc.nextInt();
		if(despoit>=5000000){
			System.out.println("凯迪拉克");
		}else if(despoit>=1000000){
			System.out.println("帕萨特");
		}else if(despoit>=500000){
			System.out.println("伊兰特");
		}else if(despoit>=100000){
			System.out.println("奥托");
		}else{
			System.out.println("捷安特");
		}
	}
}

BuyDiscount.java

/*
会员购物时,根据积分获得不同的折扣
计算会员购物时的折扣
x<2000 9
2000<=x<4000 8
4000<=x<8000 7
x>=8000 6
*/
import java.util.Scanner;
public class MemDiscount{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入会员积分");
		int memberPoint = sc.nextInt();
		if(memberPoint>=8000){
			System.out.println("6折");
		}else if(memberPoint>=4000 && memberPoint < 8000){
			System.out.println("7折");
		}else if(memberPoint>=2000 && memberPoint<4000){
			System.out.println("8折");
		}else{
			System.out.println("9折");
		}
	}
	
}

DiscountNormalMem.java

/*普通说明:
普通顾客购物满100元打9折,会员购物打8折,会员购物满200折7.5
*/

import java.util.Scanner;
public class DiscountNormalMem{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入是否是会员【Y/N】");
		String huiyuan = sc.nextLine();
		System.out.println("请输入购物金额");
		int crash = sc.nextInt();
		/*
		System.out.println("请输入购物金额");
		int crash = sc.nextInt();
		System.out.println("请输入是否是会员【Y/N】");
		String huiyuan = sc.nextLine();
		注:如果代码顺序像注释里一样,那么 就会跳过String huiyuan = sc.nextLine();这一行
		*/
		
		
		if(crash>200){
			if(huiyuan.equals("Y")){
				System.out.println("7.5折扣");
			}else{
				System.out.println("9折");
			}
		}else if(crash>100){
			if(huiyuan.equals("Y")){
				System.out.println("8折");
			}else{
				System.out.println("9折");
			}
		}else {
			System.out.println("没有折扣");
		}
		
		
	}
}

5、switch多分支结构

switch(表达式){
case1:
语句序列;
break;
case2:
语句序列;
break;
.....
default:

}
  • switch语句会根据表达式的值从相匹配的执行,一直到break标签出,或者是switch语句的末尾,与任意条件不匹配,则进入default语句。
  • 只能处理等值条件判断的情况,且表达式的值必须为byte,short,int或者char,不能是String或则和double,float,1.7版本后可以用String.
  • 常量必须是与表达式类型兼容的一个特定常量。
  • 不允许有重复的case值。
  • default子句为可选。

switch和if的区别

  • switch与if都是用于多分支。
  • switch只能处理等值条件情况,而且条件必须是整形变量或者字符变量或者字符串。
  • if没有switch选择结构的限制。特别适合某个变量处于某个连续区间的情况。

SpeedCall.java

/*
张三为自己的手机设定了自动拨号
按1键: 拨打爸爸的号
按2键: 拨打妈妈的号
按3键: 拨打爷爷的号
按4键: 拨打奶奶的号
*/

import java.util.Scanner;
public class SpeedCall{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入1/2/3/4中任意一个数字");
		int num = sc.nextInt();
		switch(num){
			case 1:
				System.out.println("Call Father");
				break;
			case 2:
				System.out.println("Call Mother");
				break;
			case 3:
				System.out.println("Call Grandfather");
				break;
			case 4:
				System.out.println("Call Grandmother");
				break;
			default:
				System.out.println("只能输入1/2/3/4任意一个数字");
		}
	}
}

MiniCalculator.java

//迷你计算器
import java.util.Scanner;
public class MiniCalculator{
	public static void main(String[] args){
		System.out.println("仅支持+,——,*,/四种操作符");
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入第一个操作数");
		int oneNum = sc.nextInt();
		System.out.println("请输入操作符1:*,2:/,3:+,4:-");
		int fuhao = sc.nextInt();
		System.out.println("请输入第二个操作数");
		int twoNum = sc.nextInt();
		switch(fuhao){
			case 1:
				System.out.println(oneNum+"*"+twoNum+"="+(oneNum*twoNum));
				break;
			case 2:
				System.out.println(oneNum+"/"+twoNum+"="+(oneNum/twoNum));
				break;
			case 3:
				System.out.println(oneNum+"+"+twoNum+"="+(oneNum+twoNum));
				break;
			case 4:
				System.out.println(oneNum+"-"+twoNum+"="+(oneNum-twoNum));
				break;
			default:
				System.out.println("只支持+,-,*,/");
		}
	}
}

AirTicketDiscount.java

/*
原价机票5000
淡季头等舱5折,经济舱4折
旺季头等舱9折,经济舱8折

要求:
输入任意的月份与仓位来计算机票的价格
1代表头等舱,2代表经济舱
4-10为旺季,其他月份为淡季

*/

import java.util.Scanner;
public class AirTicketDiscount{
	public static void main(String[] args){
		int airTicketCount=5000;
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入月份");
		int moth = sc.nextInt();
		System.out.println("请输入仓位,1:头等舱, 2:经济舱");
		int sets = sc.nextInt();
		if(sets==1){
			switch(moth){
				case 1:
				case 2:
				case 3:
				case 11:
				case 12:
					System.out.println("Air Ticket count is: "+(0.8*airTicketCount));
					break;
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
				case 10:
					System.out.println("Air Ticket count is: "+(0.9*airTicketCount));
			}
		}else{
				switch(moth){
				case 1:
				case 2:
				case 3:
				case 11:
				case 12:
					System.out.println("Air Ticket count is: "+(0.4*airTicketCount));
					break;
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
				case 10:
					System.out.println("Air Ticke ount is: "+(0.5*airTicketCount));
					break;
				default:
					System.out.println("你的信息有误");
				
				}
			}
	}
}

6、while循环

当循环开始时,会计算一次“布尔表达式”的值,若条件为真,执行循环体。而对于后来每一次额外的循环,都会在开始前重新计算一次。

语句中应该使用循环趋向于结束的语句。否则会出现无限循环,死循环。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Px4KjaOW-1587198271497)(D:\file\java学习\javaStudyExercise\notes\images\while.PNG)]

/*
循环结构由四个部分组成:
	初始化:
	条件判断:
	循环体
	迭代

*/
public class WhileTest{
	public static void main(String[] args){
		int i = 0;
		int sum = 0;
		while(i <= 100){
			sum += i;//sum = sum + i;
			i++;
		}
		System.out.println("Sum="+sum);
	}
}

WhileDemo.java

/*
循环结构:
	1、while循环
		需要四部分组成
			初始化:变量的初始化
			条件判断:必须要求返回true或者false的值
			循环体:具体的要执行的逻辑
			迭代变量:
	2、 do while:
			先执行代码逻辑,再执行条件判断

*/

public class WhileDemo{
	public static void main(String[] args){
	    
		/*
		while循环样例
		while(i<=100){
			System.out.println("第"+i+"遍输出");
			i++;
		*/
		
		//求100内 的偶数和
		/*
		int i = 1;
		int sum = 0;
		while (i<=100){
			if(i % 2 == 0){
			  sum+=i;
			}
			i++;
		}
		System.out.println("100以内偶数的和是: "+sum);
		*/
		
		//do while
		int i = 1;
		do{
			System.out.println("第"+i"遍输出");
			i ++}while(i<=100);
	}
}

WhileForExactDivision.java

for循环请看后续内容

/*
用for和while,实现输出1-1000之前被5整除的数,并且每行输出三个
*/

public class WhileForExactDivision{
	public static void main(String[] args){
		int ia = 1;
		int ja = 0;
		while(ia<=1000){
			if(ia%5==0){
				System.out.print(ia+"\t");
				ja++;
			}		
			if(ja==3){
				System.out.println();
				ja = 0;
			}
			ia++;
		}
		
		System.out.println("重新开始");
		int jb = 0;
		for(int ib=1;ib<=1000;ib++){
			if(ib%5==0){
				System.out.print(ib+"\t");
				jb++;
			}
			if(jb==3){
				System.out.println();
				jb = 0;
			}
		}
	}
}

WhileForFactorial.java

/*
输入一个数,计算阶乘之和: 1!+2!+3!....
*/
import java.util.Scanner;
public class WhileForFactorial{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入想要计算的阶乘和的最高阶正整数:");
	    String inNumStr = sc.nextLine();
		Boolean results = inNumStr.matches("[0-9]{1,}");
		if(results==true){
			int numNow = Integer.valueOf(inNumStr);
			int sum = 0;
			
			//while(numNow>=1){
			//	int numNowNew = numNow;
			//	int numNowNewProduct = 1;
			//	while(numNowNew>=1){
			//		numNowNewProduct=numNowNew*numNowNewProduct;
			//		numNowNew--;
			//	}
			//	sum=sum+(int)numNowNewProduct;
			//	numNow--;	
			//}
			for(numNow=numNow;numNow>=1;numNow--){
				int  numNowNewProduct = 1;
				for(int  numNowNew = numNow;numNowNew>=1;numNowNew--){
					numNowNewProduct*=numNowNew;
				}
				sum+=numNowNewProduct;
			}
			
			System.out.println("最终结果:"+sum);
		}else{
			System.out.println("请输入一个正整数");
		}
	}
}

WhileForTenTwoTwo.java

/*
使用循环将10进制数转换位二进制数
*/

import java.util.Scanner;
public class WhileForTenTwoTwo{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个正整数");
		String inNumStr = sc.nextLine();
		Boolean results = inNumStr.matches("[0-9]{1,}");
		//if(results==true){
		//	int resultnum = Integer.valueOf(inNumStr);
		//	String binaryNum = "";
		//	//这里resultnum为商,只要商大于0,就能够继续除
		//	for(;resultnum>0;){
		//		//remainder代表余数
		//		int remainder;
		//		remainder=resultnum%2;
		//		binaryNum=remainder+binaryNum;
		//		resultnum/=2;
		//	}
		//	System.out.println("对应的二进制数为"+binaryNum);
		//}else{
		//	System.out.println("请输入一个正整数");
		//}
		
		
		if(results==true){
			int resultnum = Integer.valueOf(inNumStr);
			String binaryNum = "";
			//这里resultnum为商,只要商大于0,就能够继续除
			while(resultnum>0){
				//remainder代表余数
				int remainder;
				remainder=resultnum%2;
				binaryNum=remainder+binaryNum;
				resultnum/=2;
			}
			System.out.println("对应的二进制数为"+binaryNum);
		}else{
			System.out.println("请输入一个正整数");
		}
		
	}
}

EvenSum.java

/*
计算100以内的值
观察每一次循环中变量值的变化
声明整数型变量和num
循环条件 num <= 100
循环操作: 累加求和
*/

public class EvenSum{
	public static void main(String[] args){
		int num = 0;
		int sum = 0;
		while(num <= 100){
			if(num%2==0){
				sum+=num;
			}
		System.out.println("num: "+num);
		System.out.println("sum: "+sum);
		num++;
		}
	}
}

SettleAccount.java

/*
循环输入商品编号和购买数量
当输入n时结账
结账时计算应付金额并找零
T恤:245
网球鞋:570
网球拍:320
*/

import java.util.Scanner;
public class SettleAccount{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("**********************");
		System.out.println("请选择购买的商品编号:");
		System.out.println("1.T恤    2.网球鞋  3.网球拍");
		System.out.println("**********************");
		
		int sum = 0;
		int tShirt = 0;
		int tennisShoes = 0;
		int tennisPad = 0;
	
		while(true){
			System.out.print("请输入购买商品的编号: ");
			int productId = sc.nextInt();
			System.out.print("请输入购买商品的数量: ");
			int productNum = sc.nextInt();
			switch(productId){
				case 1:
					sum+=(productNum*245);
					System.out.println("T恤单价:245"+"\t数量:"+productNum+"\t"+"合计:"+sum);
					break;
				case 2:
					sum+=(productNum*570);
					System.out.println("网球鞋单价:570"+"\t数量:"+productNum+"\t"+"合计:"+sum);
					break;
				case 3:
					sum+=(productNum*320);
					System.out.println("网球拍单价:320"+"\t数量:"+productNum+"\t"+"合计:"+sum);
					break;
				default:
					System.out.println("商品编号有误");
			}
			System.out.println("是否继续(Y/N)");
			String conTinue = sc.next();
			String bujixu = "N";
			if(conTinue.equals(bujixu)){
				break;
			}
		}
		System.out.println("折扣:0.0");
		System.out.println("应付金额:"+sum);
		System.out.print("实付金额: ");
		//amountPaid:实付金额
		int amountPaid = sc.nextInt();
		while(true){
			if(amountPaid<sum){
				System.out.println("您付的钱少于应付金额,请重新付款");
				System.out.print("实付金额: ");
				int amountPaidNew = sc.nextInt();
				amountPaid = amountPaidNew;
			}else{
				System.out.println("找零:"+(amountPaid-sum));
				break;
			}
		}

	}
}

7、do-while循环

do-while:先执行,后判断。

while:先判断,后执行。

do-while总是保证循环体至少被执行一次。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9RIyt8fA-1587198271499)(D:\file\java学习\javaStudyExercise\notes\images\do-while.PNG)]

8、for循环

for循环语句时支持迭代的一种通用结构,是最有效,最灵活的循环结构

语法格式:

for(初始化表达式;布尔表达式;步进){
循环体;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MImuagSN-1587198271502)(D:\file\java学习\javaStudyExercise\notes\images\for.PNG)]

注意事项:

  • for循环在执行条件测试后,先执行程序部分,在执行步进。
  • 在for语句初始化部分声明的变量,其作用域为整个for循环体。
  • "初始化"和循环条件表达式部分可以使用都好来执行多个操作
  • 如果三个部分为空语句(分号不能省略),相当于一个无线循环

CustomerAgeSurvey.java

/*
用for循环统计10个客户的年龄比例

*/

import java.util.Scanner;
public class CustomerAgeSurvey{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		//thirtyUp统计年龄大于等于30客户的人数
		int thirtyUp = 0;
		//thirtyDown统计年龄小于30客户的人数
		int thirtyDown = 0;
		for(int i=1;i<=10;i++){
			System.out.print("请输入第"+i+"位顾客的年龄;");
			int ageCustomer = sc.nextInt();
			if(ageCustomer>=30){
				thirtyUp+=1;
			}else{
				thirtyDown+=1;
			}
		}
		System.out.println("30岁以上的比例是:"+(((double)thirtyUp/10)*100)+"%");
		System.out.println("30岁以下的比例是: "+(((double)thirtyDown/10)*100)+"%");
	}
}

9、跳转语句break和continue

在任何循环语句的主体部分,均可用控制的循环的流程。break用于强制退出循环,不执行循环中的剩余语句。

continue语句用在循环语句的主体中。用于终止某次循环过程。即跳出循环体中尚未执行的语句,接着进行下一次是否循环的判定。

continue只能用在循环体里。

BreakDemo.java

/*
生成0-100的随机数,直到生成88为止,停止循环!
	break: 跳出循环,当包含多层循环的时候,break只能跳出内层循环
*/

public class BreakDemo{
	public static void main(String[] args){
	   /* 
		int count = 0;
		while(true){			
			int i = (int)(Math.random()*101);
			if(i==88){
				break;
			}
			count++;
			System.out.println(count+"--"+i);
		}
		*/
		
		//请打印输出(1,1)(1,2)(1,3)....直到输出(6,6)停止
		for(int i = 1; i<10; i++){
			for(int j = 1; j<10; j++){
				System.out.println("("+i+","+j+")");
				if(i==6&&j==6){
					return;
				}
			}
		}
		
	}
}

10、跳转语句return

return从当前方法推出,返回到调用该方法的语句处。并从该语句的下条语句处继续执行程序。

返回语句的两种格式:

  • return expression (返回一个值给调用该方法的语句,返回值的数据类型必须和方法声明中的返回值一致或者是精度低于声明的数据类型)
  • return(当方法声明中用void返回类型为空时,应使用这种返回类型,它不返回任何值)

ReturnDemo.java

/*
return表示有两个基本用途
	1、返回方法的返回值
	2、终止当前程序
*/

public class ReturnDemo{
	public static void main(String[] args){
		System.out.println(get());
		for(int i = 0;i<10;i++){
			System.out.println(i);
			if(i==5){
				return;
				//System.exit(-1);
			}
			System.out.println("接着执行");
		}
	}
	
	public static int get(){
		return 100;
	}
}

11、多重循环(循环嵌套)

  • 一个循环体中又包含另一个完整的循环体结构

  • 任何两种循环都可以相互嵌套

  • 可以任意层次循环,但是一般不超过3层

    Orthogon.java

    //打印矩形
    public class Orthogon{
    	public static void main(String[] args){
    		for(int i=0;i<4;i++){
    			for(int j = 0;j<5;j++){
    				System.out.print("*");
    			}
    			System.out.println();
    		}
    	}
    }
    

ManyFor.java

public class ManyFor{
	public static void main(String[] args){
		//打印九九乘法表
		for(int i =1;i<10;i++){
			for(int j = 1;j<=i;j++){
				System.out.print(j+"*"+i+"="+j*i+"\t");
			}
			System.out.println();
		}
		


	}
}

BuyChicken.java

public class BuyChicken{
	public static void main(String[] args){
		for(int i = 0;i<=20;i++){
			for(int j = 0; j<=30;j++){
				for(int k=0;k<=300;k++){
					if(((i+j+k)==100) && ((5*i+3*j+k/3)==100) &&(k%3==0)){
						System.out.println("公鸡: "+i+"\t母鸡: "+j+"\t小鸡: "+k);
					}
				}
			}
		}
	}
}

12、递归结构

程序调用自身的编程技巧就成为递归。

递归结构包括两个部分:

  • 递归结束条件。什么时候不调用自身方法,如果没有条件,那么将进入死循环。
  • 递归体:社么时候需要调用自身方法。

递归体的优点:

  • 简单的程序

递归的缺点:

  • 递归会占用大量的系统堆栈,内存耗用多。
  • 在递归调用层次多时虚度要比循环慢。

Febonacci.java


import java.util.Scanner;
/*
斐波那契数列,可以选择打印多少个值
*/

public class Febonacci{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入要打印的斐波那契数列的个数");
		int count = sc.nextInt();
		int x = 1;
		int y = 1;
		int z = 0;
		/*
		for(int i = 0; i<=(count-1);i++){
			if(i==0 || i==1){
				System.out.print(1+"\t");
			}else{
				z=x+y;
				x=y;
				y=z;
				System.out.println(z+"\t");
			}
		}
		*/
		for(int i = 1;i<=count;i++){
			System.out.print(getNumber(i)+"\t");
		}
		
	}
	
	/*
	递归函数:
		在程序运行过程中,有时需要调用程序本身,此时可以使用递归
		注意:
			在程序中,能不用递归就不要递归
				使用递归有时会加大资源得消耗
				如果使用递归得层次比较深,会造成栈溢出
		    如果不使用递归就无法解决问题,就必须使用递归
				比如:输出某个磁盘目录下得所有文件名称
	*/
	
	public static int getNumber(int number){
		if(number==1 || number==2){
			return 1;
		}else{
			return getNumber(number-1)+getNumber(number-2);
		}
	}
}

五、数组

1、概述

数组时相同类型数据的有序集合。

  • 相同类型的若干数据,按照一定先后次数排列组合而成
  • 其中每一个数据称作一个数组元素
  • 每个数组元素可以通过一个下标来访问他们。

数组的特点:

  • 长度时固定的。数组一旦被创建,它的大小就是不可以改变的。
  • 其元素必须时相同类型,不允许出现混合类型。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型。

数组属于引用类型。

声明一个变量就是在内存中划出一块合适的空间。

声明一个数组就是在内存空间划出一串连续的空间。

数组只有一个名称,即标识符。

元素下标表明了元素在数组中的位置,从0开始。

数组中的每个元素都可以通过下标来访问。

数组长度固定不变,避免数组越界。

定义使用数组的步骤:

  1. 声明数组:int[] a; (告诉计算机数据类型是什么)
  2. 分配空间 a = new int[5]; (告诉计算机几个连续的空间)
  3. 赋值 a[0] = 8; (像分配的空间里存放数据)
  4. 处理数据:a[0] = a[0] * 10 (对数组内的数据进行操作)

注意:

  • 定义数组必须致命数组的大小

  • 数组使用不要超过数组的边界

  • 创建数组并赋值的语句必须在一条语句中完成

  • 每个数组都有一个属性length指明他的长度。a.length

    ArrayDemo.java

    /*
    数组表示存储相同数据类型数据的有序集合:
    	特点:
    		1、数组中存放的数据类型必须是同一个数据类型,可以是基本数据类型也可以是引用数据类型
    		2、数组在定义的时候必须要给定大小,且大小不可以改变
    		3、可以通过下标值来获取数据,下标从0开始
    		4、插入数组中的数据是有序集合,此时有序并不是指按大小排序,而是指插入的数据
    	使用:
    		1、声明
    		2、创建空间
    		3、赋值
    		4、数组操作
    */
    public class ArrayDemo{
    	public static void main(String[] args){
    		
    		/*
    		//声明数组,栈,存储了数组的元数据
    		int[] array;
    		//创建空间 :堆,new新数组的时候,分配的空间的第一个小空间存储了数组在栈中的地址
    		array = new int[5];
    		//数组赋值, 在堆里分配的空间填充数据
    		array[0] = 0;
    		array[1] = 1;
    		array[2] = 2;
    		array[3] = 3;
    		array[4] = 4;
    		//数组操作
    		System.out.println(array[0]);
    		
    		//数组的几种创建方式
    		//1\声明并申请空间
    		int[] arr = new int[5];
    		int [] arr3 = new int[5];
    		int arr4 [] = new int[5];
    		//声明数组并赋值
    		int[] arr2 = new int[]{1,2,3,4,5};
    		//3、直接开始初始化操作
    		int[] arr5 = {1,2,3,4,5};
    		
    		//获取数组的长度
    		System.out.println(arr5.length);
    		
    		//输入5个数值,求平均值
    		int[] arr6 = new int[]{1,2,3,4,5,6};
    		int sum = 0;
    		for(int i =0; i
    		/*
    			定义数组,数据是引用类型,当创建完成数组之后相当于是在方法外定义了一个变量,此时数组中的值是有默认值的
    				默认是什么,取决于你定义的数组的类型:
    				int: 0
    				string: null
    				boolean: false
    			数组可以根据下标获取值,但是下标的范围是[0~n-1]
    				
    		*/
    	}
    }
    

2、练习

练习中包含了该章节学些的内容,也包括第3,4小节内容。

ArrayDemos.java

/*
创建基本数据类型,并输出数组的元素值
*/

public class ArrayDemos{
	public static void main(String[] args){
		char[] s;
		s = new char[26];
		for(int i = 0;i<26;i++){
			s[i]=(char)('A'+i);
			System.out.println(s[i]);
		}
	}
}

ArrayInitTest.java

/*
数组的两种初始化方式
*/

public class ArrayInitTest{
	public static void main(String[] args){
		int[] a = null;
		a = new int[5];
		for(int i=0;i<5;i++){
			a[i] = i;
			System.out.print(a[i]);
		}
		
		System.out.println();
		int[] b = {1,2,3,4,5};
		for(int i=0;i<b.length;i++){
			System.out.print(b[i]);
		}
	}
}

ArrayExcerise.java

/*
有个数列,8,4,2,1,23,344,1 
(1)循环输出序列的值。
(2)求数列中所有数值的和
(3)猜数游戏,从键盘上输入任意数字,判断数组中是否包含此数
*/

import java.util.Scanner;
public class ArrayExcerise{
	public static void main(String[] args){
		int[] a = {8,4,2,1,23,344,1};
		
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]);
		}
		System.out.println();
		
		
		int sum = 0;
		for(int j=0;j<a.length;j++){
			sum+=a[j];
		}
		System.out.println(sum);
		
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个数字");
		int inputNum = sc.nextInt();
		boolean result = false;
		for(int k=0;k<a.length;k++){
			if(inputNum==a[k]){
				result = true;
			}
		}
		if(result==true){
			System.out.println("恭喜你,有这个数字");
		}else{
			System.out.println("猜错了,没有这个数字");
		}
	}
}

ArraySort.java

/*
数组相当于数据结构的一种实现,很多数据在进行存储的时候需要使用数组
	数据结构:
		线性表
		非线性表
		树
		图
		队列
		栈

数组经常用来考排序算法:
	面试需求:
		1、写出某种排序算法
			冒泡排序
			选择排序
			插入排序
			快速排序 
		2、排序算法的时间复杂度(空间复杂度)
			衡量一个数据结构是否合适的衡量标准
		3、排序算法的稳定性
			排序之后的值跟排序之前的值位置是否发生变化

*/

import java.util.Arrays;
public class ArraySort{
	public static void main(String[] args){
		//定义数组
		int[] array = new int[]{1,4,11,7,2,9,3,5,8,6};
		//https://visualgo.net/zh数据结构学习网站
		//将数组进行排序操作,从小到大
		//冒泡排序
		/*
		for(int i=0;iarray[j+1]){
					int tmp = array[j+1];
		 			array[j+1] = array[j];
					array[j] = tmp;
				}
			}
		}
		for(int i = 0;i
		
		//选择排序
		/*
		for(int i=0;i
		Arrays.sort(array);
		
		for(int i=0;i<array.length;i++){
			System.out.print(array[i]+"\t");
		}
		
		
	}
}

ContainerMember.java

/*
1.数组查找操作:定义一个长度为10 的一维字符串数组,在每一个元素存放一个单词;然后运行时从命令行输入一个单词,
程序判断数组是否包含有这个单词,包含这个单词就打印出“Yes”,不包含就打印出“No”。

*/
import java.util.Scanner;
import java.util.Arrays;
public class ContainerMember{
	public static void main(String[] args){
		String[] a = {"nihao","heheh","haha","hoho"};
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个单词:");
		String word = sc.nextLine();
		boolean isContainers = Arrays.asList(a).contains(word);
		if(isContainers){
			System.out.println("Yes");
		}else{
			System.out.println("No");
		}
	}
}

MaxAndMin.java

/*
2.获取数组最大值和最小值操作:利用Java的Math类的random()方法,编写函数得到0到n之间的随机数,n是参数。
并找出产生50个这样的随机数中最大的、最小的数,并统计其中>=60的有多少个。
提示:使用 int num=(int)(n*Math.random());获取随机数
*/
import java.util.Scanner;
public class MaxAndMin{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个基数:");
		int n = sc.nextInt();
		int[] a = new int[50];
		for(int i=0;i<50;i++){
			a[i] = (int)(Math.random()*n);
		}
		int max = 0;
		int totalUp60 = 0;
		for(int j=0;j<50;j++){
			if(a[j]>max){
				max = a[j];
			}
			if(a[j]>=60){
				totalUp60+=1;
			}
		}
		System.out.println("Max: "+max+"\t"+"TotalUp60: "+totalUp60);
		
	}
}

ReverseOrder.java

/*
3.数组逆序操作:定义长度为10的数组,将数组元素对调,并输出对调前后的结果。
思路:把0索引和arr.length-1的元素交换,把1索引和arr.length-2的元素交换…..
	只要交换到arr.length/2的时候即可。
*/
public class  ReversedOrder{
	public static void main(String[] args){
		int[] a = {1,2,3,4,5,6,7,8,9,10};
		for(int i=0;i<a.length/2;i++){
			int  tmp = a[i];
			a[i] = a[a.length-(i+1)];
			a[a.length-(i+1)] = tmp;
		}
		for(int j=0;j<10;j++){
			System.out.print(a[j]+" ");
		}
	}
} 

Merge.java

/*
4.合并数组操作:现有如下一个数组:???int?oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}???要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: int?newArr [] ={1,3,4,5,6,6,5,4,7,6,7,5}??
思路:?确定出不为0的个数,这样可以开辟新数组;从旧的数组之中,取出内容,并将其赋给新开辟的数组。
*/
public class Merge{
	public static void main(String[] args){
		int[] oldArr={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
		int zeroNum = 0;
		for(int i=0;i<oldArr.length;i++){
			if(oldArr[i]==0){
				zeroNum+=1;
			}
		}
		int[] newArr= new int[oldArr.length-zeroNum];
		int index=0;
		for(int i=0;i<oldArr.length;i++){
			if(oldArr[i]!=0){
				newArr[index]=oldArr[i];
				index++;
			}
		}
		for(int k=0;k<newArr.length;k++){
			System.out.println(newArr[k]);
		}
	}
}

BinarySearchDemo.java

/*
5.二分法查找操作:使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。
分析:二分法查找的前提是数组有序。
假如有一组数为3,12,24,36,55
,68,75,88要查给定的值24.可设三个变量front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2.  
1)开始令front=0(指向3),end=7(指向88),则mid=3(指向36)。因为mid>x,故应在前半段中查找。
2)令新的end=mid-1=2,而front=0不变,则新的mid=1。此时x>mid,故确定应在后半段中查找。
3)令新的front=mid+1=2,而end=2不变,则新mid=2,此时a[mid]=x,查找成功。
4)如要查找的数不是数列中的数,例如x=25,当第三次判断时,x>a[mid],按以上规律,令front=mid+1,即front=3,出现front>end的情况,表示查找不成功。
*/
import java.util.Scanner;
public class BinarySearchDemo{
	public static void main(String[] args){
		int[] a = {3,12,24,36,55,68,75,88};
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入要查找的数字:\t");
		int inputNum = sc.nextInt();
		int end = a.length-1;
		int front = 0;
		int mid = (front+end)/2;
		System.out.println("您要查找的数字是:"+inputNum);
        //下面语句存在多余判断条件,可以直接把外循环for替换成while(front
		for(int i=0;i<a.length;i++){
			if(front>end){
				System.out.println("查找失败:-1");
				break;
			}else if(inputNum<(int)a[mid]){
				System.out.println("当前mid值为: "+a[mid]);
				front = 0;
				end = mid -1;
				mid = (front+end)/2;
				continue;
				
			}else if(inputNum>(int)a[mid]){
				System.out.println("当前mid值为: "+a[mid]);
			    front = mid+1;
				end = end;
				mid = (front+end)/2;
				continue;
				
			}else if(inputNum==a[mid]){
				System.out.println("找到了,index: "+mid);
				break;
			}else{
				
			}
			
		}
		
	}
}

DoubleArrays.java

/*
6.二维数组遍历求和操作:用二重循环求出二维数组b所有元素的和:
 int[][] b={{11},{21,22},{31,32,33}}
*/
public class DoubleArrays{
	public static void main(String[] args){
		int[][] b = {{11},{21,22},{31,32,33}};
		int sum = 0;
		for(int i=0;i<b.length;i++){
			for(int j=0;j<b[i].length;j++){
				sum+=b[i][j];
			}
		}
		System.out.println("Sum is: "+sum);
	}
}

定义一个长度为10 的一维字符串数组,在每一个元素存放一个单词;然后运行时从命令行输入一个单词,程序判断数组是否包含有这个单词,包含这个单词就打印出“Yes”,不包含就打印出“No”。

public class Test {
	// 思路:遍历数组时当有值与输入字符串相同时使用一个boolean记录状态
	public static void main(String[] args) {
		String[] strArr = new String[10];
		strArr[0] = "java";		strArr[1] = "html";
		strArr[2] = "sql";		strArr[3] = "android";
		strArr[4] = "javascript";		strArr[5] = "ruby";
		strArr[6] = "c";
		strArr[7] = "c++";
		strArr[8] = ".net";
		strArr[9] = "ios";
		Scanner scanner = new Scanner(System.in);
		System.out.print("请输入需要查找的计算机编程语言:");
		String inputStr = scanner.next();
		boolean flag = false;
		for (String string : strArr) {
			if (string.equals(inputStr)) {
				flag = true;
			}
		}
		if (flag) {
			System.out.println("YES");
		} else {
			System.out.println("NO");
		}
	}
}

利用Java的Math类的random()方法,编写函数得到0到n之间的随机数,n是参数。
提示: int num=(int)(n*Math.random());
并找出产生50个这样的随机数中最大的、最小的数,并统计其中大于等于60的有多少个。

public class Test {
	public static void main(String[] args) {
		//创建一个长度为50的,每个元素在0-100之间的数组
		int[] arr = getArray(100);
		//遍历数组
		printArr(arr);		
		//获取最大值和最小值
		int min = getMin(arr);
		int max = getMax(arr);
		System.out.println("数组中最大值:" + max + "\t数组中最小值:" + min);
		//统计其中大于等于60的元素个数
		int count = count(arr,60);
		System.out.println("数组中大于或等于60的数有:" + count + " 个");
	}
	//遍历数组
	private static void printArr(int[] arr) {
		System.out.println("输出数组元素");
		for(int i=0;i<arr.length;i++){			
			if(i%10 ==0){
				System.out.println();
			}
			System.out.print(arr[i]+"\t");
		}		
	}
	//获取数组最大值
	private static int getMax(int[] arr) {
		int max = arr[0];
		for(int i=1;i<arr.length;i++){
			if(max<arr[i]){
				max = arr[i];
			}
		}	
		return max;
	}
	//获取数组最小值
	private static int getMin(int[] arr) {
		int min = arr[0];
		for(int i=0;i<arr.length;i++){
			if(min>arr[i]){
				min = arr[i];
			}
		}
		return min;
	}
	// 创建数组 并且初始化50个数据
	public static int[] getArray(int n) {
		int arr[] = new int[50];
		for (int i = 0; i < 50; i++) {
			arr[i] = (int) (n * Math.random());
		}
		return arr;
	}
	// 统计数组中大于等于60的数量的方法 思路:使用一个int值计数
	public static int count(int[] arr,int elem) {
		int count = 0;
		for (int i : arr) {
			if (i >= elem) {
				count++;
			}
		}
		return count;
	}
}

. 数组逆序操作:定义长度为10的数组,将数组元素对调,并输出对调前后的结果。

public class Test{
	public static void main(String[] args) {
		//定义一个数组,并进行静态初始化。
		int[] arr = {12,98,50,34,76,87,90,34,67,80};
		//逆序前
		System.out.println("逆序前:");
		printArr(arr);
		//逆序后
		System.out.println("逆序后:");		
		reverseArr(arr);
		printArr(arr);
	}	
	public static void reverseArr(int[] arr) {
		for(int x=0; x<arr.length/2; x++) {
			int temp = arr[x];
			arr[x] = arr[arr.length-1-x];
			arr[arr.length-1-x] = temp;
		}
	}
	//遍历数组
	public static void printArr(int[] arr) {
		System.out.print("[");
		for(int x=0; x<arr.length; x++) {
			if(x == arr.length-1) { //这是最后一个元素
				System.out.println(arr[x]+"]");
			}else {
				System.out.print(arr[x]+", ");
			}
		}
	}
}

现在有如下的一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: int newArr [] ={1,3,4,5,6,6,5,4,7,6,7,5}

思路: 确定出不为0的个数,这样可以开辟新数组;从旧的数组之中,取出内容,并将其赋给新开辟的数组。

public class Test {
	public static void main(String[] args) {
		int oldArr[] = { 1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 0, 5 };
		int newArr[] = selectArr(oldArr);
		for (int i : newArr) {
			System.out.print(i+" ");
		}
	}
	// 去掉数组中值为0的元素的方法
	public static int[] selectArr(int[] arr) {
		// 1.计算数组中元素不为0的个数
		int count = 0;
		for (int i : arr) {
			if (i != 0) {
				count++;
			}
		}
		// 2.创建一个新数组,长度为count
		int newArr[] = new int[count];
		// 3.复制不为0的元素到新数组中
		int size = 0;
		for (int i : arr) {
			if (i != 0) {
				newArr[size++] = i;
			}
		}
		return newArr;
	}
}

使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。

public class BinarySearch {
	public static void main(String[] args) {		
		int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		System.out.println(searchLoop(array, 9));
	}
	/**
	 * 循环二分查找,返回第一次出现该值的位置 
	 * @param array 已排序的数组
	 * @param findValue   需要找的值
	 * @return 值在数组中的位置,从0开始。找不到返回-1
	 */
	public static int searchLoop(int[] array, int findValue) {
		// 如果数组为空,直接返回-1,即查找失败
		if (array == null) {
			return -1;
		}
		// 起始位置
		int start = 0;
		// 结束位置
		int end = array.length - 1;
		while (start <= end) {			
			// 中间位置
			int middle = (start + end) / 2;
			// 中值
			int middleValue = array[middle];
			if (findValue == middleValue) {
				// 等于中值直接返回
				return middle;
			} else if (findValue < middleValue) {
				// 小于中值时在中值前面找
				end = middle - 1;
			} else {
				// 大于中值在中值后面找
				start = middle + 1;
			}
		}
		// 返回-1,即查找失败
		return -1;
	}
		}

用二重循环求出二维数组b所有元素的和:

int[][] b={{11},{21,22},{31,32,33}}
public class Test {
	public static void main(String[] args) {
		int sum=0;
		int[][] b={{11},{21,22},{31,32,33}};
		for(int i=0;i<b.length;i++){
			for(int j=0;j<b[i].length;j++){
				sum += b[i][j];
			}
		}
		System.out.println(sum);
	}
}

生成一百个随机数,放入数组,然后排序输出。

public class Test {
	public static void main(String[] args) {
		//1.生成100个随机数的数组
		int []arr = createArr();
		//2.从小到大排序 
		arr = sortArr(arr);
		//3.打印
		printArr(arr);
	}
	//生成100个随机数的方法
	public static int[] createArr(){
		int []arr = new int[100];
		for(int i=0;i<arr.length;i++){
			arr[i]= (int) (100*Math.random());
		}
		return arr;
	}
	//对数组进行排序的方法
	public static int[] sortArr(int arr[]){
		int temp;
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j <= i; j++) {
				if (arr[i] < arr[j]) {
					temp = arr[i];
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}
		}
		return arr;
	}
	//数组遍历输出打印的方法
	public static void printArr(int []arr){
		for(int i:arr){
			System.out.println(i);
		}
	}
}

题目:输入某年某月某日,判断这一天是这一年的第几天?

分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于3时需考虑多加一天。可以定义数组存储1-12月各个月的天

public class Test {
	public static void main(String[] args) {
		Scanner scanner1 = new Scanner(System.in);
		System.out.print("输出今年是第几年");
		int year = scanner1.nextInt();
		System.out.print("输出今年是第几月");
		int month = scanner1.nextInt();
		System.out.print("输出今年是第几日");
		int day = scanner1.nextInt();
		int daynum = 0; // 天数
		//一年365天
		int[] month1 = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 }; 
		//闰年366天
		if (year % 400 == 0 && year % 100 != 0 || year % 100 == 0) {
			month1 = new int[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 }; // 闰年里的每个月的天数			
		} 
		//判断这一天是第几天
		for (int index = 1; index <= month; index++) {
			if (index == 1) {
				daynum = day;
			} else {
				daynum += month1[index - 2];
			}
		}
		System.out.println("这一天是这一年的第" + daynum + "天!");
	}
}


使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。使用递归实现

public class BinarySearch {
	public static void main(String[] args) {		
		int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		System.out.println(searchRecursive(array, 0, array.length - 1, 20));
	}
	/**
	 * 执行递归二分查找,返回第一次出现该值的位置	 * 
	 * @param array  已排序的数组
	 * @param start 开始位置
	 * @param end 结束位置
	 * @param findValue  需要找的值
	 * @return 值在数组中的位置,从0开始。找不到返回-1
	 */
	public static int searchRecursive(int[] array, int start, int end,
			int findValue) {
		// 如果数组为空,直接返回-1,即查找失败
		if (array == null) {
			return -1;
		}	
		if (start <= end) {
			// 中间位置
			int middle = (start + end) / 1;
			// 中值
			int middleValue = array[middle];
			if (findValue == middleValue) {
				// 等于中值直接返回
				return middle;
			} else if (findValue < middleValue) {
				// 小于中值时在中值前面找
				return searchRecursive(array, start, middle - 1, findValue);
			} else {
				// 大于中值在中值后面找
				return searchRecursive(array, middle + 1, end, findValue);
			}
		} else {
			// 返回-1,即查找失败
			return -1;
		}
	}
}

现在给出两个数组:

数组A:“1,7,9,11,13,15,17,19:;

数组b:“2,4,6,8,10”

两个数组合并为数组c,按升序排列。

要求:使用Arrays类的方法快速实现。

public class Test {
	public static void main(String[] args) {
		int data1[] = new int[] { 1, 7, 9, 11, 13, 17, 19 };
		int data2[] = new int[] { 2, 4, 6, 8, 10 };
		int newArr[] = concat(data1, data2);
		print(newArr);
		Arrays.sort(newArr);
		print(newArr);
	}
	public static int[] concat(int src1[], int src2[]) {
		int len = src1.length + src2.length; // 新数组的大小
		int arr[] = new int[len]; // 新数组
//		int count = 0;
//		for (int i : src1) {
//			arr[count++] = i;
//		}
//		for (int i : src2) {
//			arr[count++] = i;
//		}
		// 还可以通过系统的方法拷贝数组
		 System.arraycopy(src1, 0, arr, 0, src1.length); // 拷贝第一个数组
		 System.arraycopy(src2,0,arr,src1.length, src2.length); //拷贝第二个数组
		return arr;
	}
	public static void print(int[] temp) {
		for (int x = 0; x < temp.length; x++) {
			System.out.print(temp[x] + "、");
		}
		System.out.println();
	}
}

3、二维数组

int [][] [] [] a = {{1,3},{2,4,5,},{5,6,7}};

java中多维数组的声明和初始化应该按照从高维到低维的顺序进行

int [][] a = new int[][];
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];

PrimitiveArray.java

/*
编写一个应用程序:创建基本的数组类型二维数组并输出各组的元素
*/

public class PrimitiveArray{
	public static void main(String[] args){
		int a[][] = {{1,3,4},{2,5},{3,6,9}};
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[i].length;j++){
				System.out.print(a[i][j]+"\t");
			}
			System.out.println();
		}
	}
}

TwoArray.java

/*
二维数组可以称作数组的数组
	定义二维数组的时候一定要注意,必须要给定数组的长度
*/

public class TwoArray{
	public static void main(String[] args){
		int[] arr = new int[6];
		int[][] arr2 = new int[3][];
		arr2[0] = new int[5];
		arr2[1] = new int[2];
		arr2[2] = new int[4];
		
		//赋值
		 arr2[0][0] = 1;
		 arr2[0][1] = 2;
		 arr2[0][2] = 3;
		 arr2[0][3] = 4;
		 arr2[0][4] = 5;
		 arr2[1][0] = 6;
		 arr2[1][1] = 7;
		 arr2[2][0] = 8;
		 arr2[2][1] = 9;
		 arr2[2][2] = 10;
		 arr2[2][3] = 11;
		 
		 for(int i = 0;i<arr2.length;i++){
			 for(int j = 0;j<arr2[i].length;j++){
				 System.out.print(arr2[i][j]+"\t");
			 }
			 System.out.println();
		 }
		 
	}
}

4、数组的拷贝

使用Java.lang.System类的静态方法

可以从原数组src的第n项考试拷贝到目标数组dest从第n项开始赋值。

如果源数据数量超过目标数组边界会抛出异常。(IndexOutOfBoundsException)

ArrayCopyDemo.java

import java.lang.System;
public class ArrayCopyDemo{
	public static void main(String[] args){
		String[] s =  {"MS","IBM","Sun","Oracle","Apple","AM"};
		String[] sBack = new String[6];
		//从s的0号元素开始拷贝,从sBack的0号元素开始粘贴,一共拷贝s.length个元素
		System.arraycopy(s,0,sBack,0,s.length);
		for(int i=0;i<sBack.length;i++){
			System.out.print(sBack[i]+"\t");
		}
		System.out.println();
		
	}
}

Java.util.Arrays类:

  • 提供了关于数组操作的方法
  • 打印数组: toString方法
  • 比较两个数组是否相同—equals方法
  • 数组排序—sort方法。
  • 数组查找–binarySearch

六、面向对象

1、概述

  • 类是抽象的概念,仅仅是模板,比如说:“人”
  • 对象是一个你能看得到,摸得着的具体实体。

1.1对象和类的总结:

  • 对象和类的关系:特殊到一般,具体到抽象。
  • 类:我们叫class
  • 对象:我们叫做object,instance(实例)。
  • 类可以看成一类对象的模板,对象可以堪称该类的一个具体实例。
  • 类是用于描述同一类的对象的一个抽象的概念,类中定义了这一类对象所应该具有的静态和动态属性。
  • 对象是java程序的核心,在java中万物皆对象。
  • jdk提供了很多类供人员使用,开发也可以自定义自己的类。

1.2 对象的特征:

  • 属性–对象具有的各种特征;每个对象的属性都拥有特定值

    • 属性 field,或叫做成员变量
    • 属性用于定义该类或者该类对象包含的数据或者说是静态属性。
    • 属性作用范围是整个类体。
    • 定义成员变量时可以对其初始化 ,如果不初始化,java使用默认的值对其初始化。
    • 定义格式 [修饰符] 属性类型 属性名 = [默认值]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f82WhXYq-1587198271506)(D:\file\java学习\javaStudyExercise\notes\images\图1.2.1属性定义的格式.PNG)]

  • 方法-对象执行的操作

    方法定义格式: [修饰符] 方法返回值类型 方法名(形参列表) {

    ​ // n条语句

    }

    java中方法的参数传递:值传递

    对象:用来描述客观事物的一个实体。由一组属性和方法构成

    抽取处对象的属性和方法的共同特征就构成了类。

定义类的方法:

  1. 定义类名
  2. 编写类的属性
  3. 编写类的方法

定义类的时候需要包含以下组件:

  • 私有属性
  • 构造方法(无参构造方法和自定义构造方法)
  • set/get方法
  • 普通方法
/*
* 所有类定义的时候可以添加属性和方法,但是不是必须要写的
*   一个java文件中可以定义N多个class,但是只能有一个public class并且public class的类名跟文件名保持一致
* 属性:
*   语法:
*   [访问修饰符]    数据类型      属性名称  =  值;
*
*   注意:
*       定义属性的时候可以有值也可以没有值
*       必须要包含类型和名称
*
*
* 方法:表示行为
*   语法:
*       [访问修饰符]  返回值类型(任何类型)  方法名称(形参列表){
*               逻辑代码
*
*       }
*   注意:
*       1、方法的访问修饰符可以不写
*       2、方法可以有返回值,也可以没有,void表示没有返回值的意思
*       3、形参列表可以有,也可以没有
*       4、java中方法的传参都是值传递(后续会讲)
*
* 对象的创建和使用
*       1、使用new关键字来创建对象
*       ClassName objectName = new ClassName();
*       2、对象的使用
*           使用对象的时候可以通过 对象名称.属性 或者 对象名称.方法 来使用属性和方法
* */
public class Student {

    //属性的定义
    int stuNumber;
    String name;
    int age = 20;

    //方法的定义
    void study(){
        System.out.println("我正在学习");
    }

    void eat(String food){
        System.out.println("我在吃"+food);
    }

    public static void main(String[] args) {
        //创建对象
        Student student = new Student();
        //使用属性
        System.out.println(student.name);
        System.out.println(student.age);
        System.out.println(student.stuNumber);
        //修改属性值,给属性赋值
        student.name="张三";
        student.age=40;
        student.stuNumber=20190818;
        System.out.println(student.name);
        System.out.println(student.age);
        System.out.println(student.stuNumber);
        //调用方法
        student.study();
        student.eat("apple");
    }

AdministratorDemo.java

/*
定义管理员类
*/
public class AdministratorDemo{
	public static void main(String[] args){
		AdminiStrator  newadmin = new AdminiStrator();
		newadmin.name = "zhanghua";
		newadmin.age = 25;
		newadmin.introduce();
		
		
		TestAdminiStrator newtestadmin = new TestAdminiStrator();
		newtestadmin.name = "test";
		newtestadmin.age = 26;
		newtestadmin.sex = "F";
		newtestadmin.testintro();
	}
}

class AdminiStrator{
	String name;
	int age;
	public void introduce(){
		System.out.println("name: "+name+"\tage: "+age);
	}
}

class TestAdminiStrator{
	String name;
	int age;
	String sex;
	public void testintro(){
		System.out.println("name: "+name+"\tage: "+age+"\tsex: "+sex);
	}
}

UpdateAdminPasswd.java

/*
输入旧的用户名和密码,如果正确,则有权更新账户和密码,否则不断提示用户账户和密码错误。
*/
import java.util.Scanner;
public class UpdateAdminPasswd{
	public static void main(String[] args){
		Admin newad = new Admin();
		newad.name = "admin";
		newad.passwd = 1234;
		Scanner sc = new Scanner(System.in);
		while(true){
			System.out.println("请输入用户名:");
			String newName = sc.next();
			System.out.println("请输入密码: ");
			int newPasswd = sc.nextInt();
			if(newName.equals(newad.name) && newPasswd==1234){
				System.out.println("请输入新用户名:");
				String newName1 = sc.next();
				System.out.println("请输入新密码: ");
				int newPasswd1 = sc.nextInt();
				newad.name = newName1;
				newad.passwd = newPasswd1;
				break;
			}else{
				System.out.println("信息错误,请重试");
				continue;
			}
		}
		
	}
}

class Admin{
	String name;
	int passwd;
	public void intro(){
		System.out.println("name: "+name+"\tpasswd: "+passwd);
	}
}

2、创建和使用对象

  • 使用对象的步骤

    • 创建对象:

      • 类名 对象名 = new 类名();

        Person person = new Person()

    • 应用对象成员:使用"."进行以下操作

      • 引用类的属性: 对象名.属性
      • 引用类的方法:对象名.方法名()
        • person.name = “王一一” //给name属性赋值
        • person.introduce(); //调用introduce方法

CreateOodDemo.java

public class CreateOodDemo {
    String name;
    int age;
    String gender;

    public static void main(String[] args){
        CreateOodDemo createOodDemo = new CreateOodDemo();//创建对象
        System.out.println("**初始化变量前**");
        createOodDemo.name = "王一一";
        createOodDemo.age = 20;
        createOodDemo.gender = "男";
        System.out.println("**初始化变量后**");
        createOodDemo.introduce();

    }

    public void introduce(){
        System.out.println(name+" "+age+" "+gender);
    }
}

StudentTeacher.java

/*
编写学生类,输出学生相关信息;编写教员类,输出教 员相关信息
*/

public class StudentTeacher {
    public static void main(String[] args){
    Students li = new Students();
    li.name="李同学";
    li.age=12;
    li.classes=12;
    li.favorite="篮球";
    li.Stuinfo();

    Teach ma = new Teach();
    ma.name="马老师";
    ma.projects="自动化控制";
    ma.courses="51单片机";
    ma.teachingYear=20;
    ma.Teachinfo();


    }
}

class Students{
    String name;
    int age;
    int classes;
    String favorite;
    public void Stuinfo(){
        System.out.println("学生信息,名字: "+name+"\t班级"+classes+"\t兴趣:"+favorite+"\t爱好:"+favorite);
    }

}

class Teach{
    String name;
    String projects;
    String courses;
    int teachingYear;
    public void Teachinfo(){
        System.out.println("姓名: "+name+"\t专业方向:"+projects+"\t课程:"+courses+"\t教龄:"+teachingYear );
    }

}

AdministratorReview.java

/*
*上机练习1—定义管理员类
 实现思路:
– 1、定义管理员类Administrator
– 2、定义其属性和方法
– 3、定义测试类TestAdministrator
– 4、创建两个管理员类的对象,并输出他们的信息
* */

public class AdministratorReview {
    public static void main(String[] args){
        Admin sun = new Admin();
        sun.name="孙管理员";
        sun.age=18;
        sun.adminInfo();

        TestAdmin testChen = new TestAdmin();
        testChen.name="陈测试";
        testChen.age=20;
        testChen.testadminInfo();
    }

}

class Admin{
    String name;
    int age;
    public void adminInfo(){
        System.out.println("姓名:"+name+"年龄: "+age);
    }
}

class TestAdmin{
    String name;
    int age;
    public void testadminInfo(){
        System.out.println("测试姓名:"+name+"年龄: "+age);
    }
}

UpdatePasswdReview.java

/*
* —更改管理员密码
▪ 需求说明:
– 输入旧的用户名和密码,如果正确,斱有权限更新
– 从键盘获取新的密码,迚行更新
▪ 实现思路:
– 1、创建管理员类的对象
– 2、利用while实现循环执行
* */
import java.util.Scanner;
public class UpdatePasswdReview {
    public static void main(String[] args){
        AdminUpdate luo = new AdminUpdate();
        Scanner sc = new Scanner(System.in);
        while(true){
            System.out.println("请输入用户名");
            String name = sc.next();
            System.out.println("请输入密码");
            String passStr = sc.next();
            int pass = Integer.valueOf(passStr);
            if(name.equals(luo.name) && pass==luo.passwd){
                System.out.println("请输入修改后的用户名");
                String newname = sc.next();
                System.out.println("请输入修改后的密码");
                String newpassStr = sc.next();
                int newpass = Integer.valueOf(newpassStr);
                luo.name = newname;
                luo.passwd = newpass;
                luo.AdminUpdateInfo();
                break;

            }else{
                System.out.println("账户信息错误,请重新输入");
            }

        }

    }

}

class AdminUpdate{
    String name = "李四";
    int passwd = 1234;
    public void AdminUpdateInfo(){
        System.out.println("用户名:"+name+"\t密码:"+passwd);
    }
}

3、局部变量和成员变量

局部变量:

  • ​ 定义在方法中的变量称为局部变量
  • 作用域:从定义的位置开始到整个方法结束
  • 局部变量不包含默认值,如果没有使用当前变量的话,可以不赋值
  • 注意:局部变量只能在当前方法中使用,其他地方无法使用

成员变量:

  • 定义在方法外,类内的变量叫做成员变量(全局变量)
  • 成员变量包含初始值,int 0, String null , boolean false
  • 作用域: 整个类体内。
public class VarDemo {
    int age = 20;

   public void test(){
       System.out.println(age);
       age = 10;
       System.out.println(age);
       int age = 30;
       System.out.println(age);
   }
    public void show(){
        //局部变量
        int a ;
        String name = "zhangsan";
        System.out.println(age);
//        System.out.println(a);
    }


    public static void main(String[] args) {
       VarDemo vd = new VarDemo();
        System.out.println(vd.age);
        vd.test();
        System.out.println(vd.age);


    }
}

区别:

  • 声明位置不同: 成员变量在类中,局部变量在方法中
  • 作用范围不同:成员变量当前类, 局部变量当前方法
  • 内存存放的位置:成员变量:堆; 局部变量:栈
  • 成员变量又默认值,局部变量没有默认值

4、相关内存分析

栈:

  • 存放局部变量
  • 先进后出,自下而上存储
  • 方法执行完毕,自动释放空间

堆:

  • 存放new出来的对象
  • 需要垃圾回收器来回收:System.gc();

方法区:

  • 存放:类的信息(代码),static变量,字符串常量等。

5、构造方法

构造器:

  • constructor构造方法,一个在创建对象时被自动调用的特殊方法。

构造器的作用:

  • 为对象进行初始化(成员变量)工作。

构造器是一种特殊的方法:

  • 构造器的方法名必须和类名一致。
  • 构造器虽然有返回值,但是不能定义返回类型(返回值的类型肯定是本类),不能在构造器里面调用return.
  • 通过new关键字调用
  • 构造方法也可以重载
  • 如果我们没有定义构造器,则系统会自动定义一个无参的构造方法。如果已定义则编译器不会添加无参构造方法

形参和实参:

  • 定义方法的参数时形式参数
  • 调用方法的参数时实际参数
  • 调用方法时要求参数个数相同,类型兼容

参数传递:

  • 基本数据类型的参数传递

    • 无法通过方法调用改变变量的值。
  • 引用数据类型的参数传递

    • 可以通过方法调用改变变量的值。

      ArgsDemo.java

      public class ArgsDemo{
      	public static void main(String[] args){
      		for(int i = 0;i<args.length;i++){
      			System.out.print(args[i]+"\t");
      		}
      	}
      }
      

构造方法:

  • 创建对象的时候默认会调用构造方法来创建对象,(在堆中开辟空间),可以完成成员变量的某些初始化操作

  • 构造方法的语法:

    • 方法名称:构造方法的方法名称必须跟类的名称保持一致
    • 访问修饰符:
    • 形参:可以用户自定义添加,跟方法的普通参数一样
    • 方法体:完成对象的初始化功能
    • 返回值:没有返回值

注意:

  1. 创建完类之后,如果没有手动调用构造方法,会有一个默认的无参的构造方法供调用
  2. 当用户自定义了构造方法之后,默认的无参数构造方法就不能使用了,必须要手动定义无参构造方法
  3. 同一类中可以包含多个同名的构造方法

重载:在一个类中可以包含多个重名的方法,但是注意方法的参数列表不能相同

  1. 参数的个数不同

  2. 参数的类型不同

  3. 参数的顺序不同

    注意:一般构造方法都会进行重载(一个类中可能包含多个属性,当只需要给部分属性初始化的时候需要调用不同的构造方法)

public class Teacher {

    String name;
    int age;

    public Teacher(){

    }

    public Teacher(String xname){
        System.out.println("one argument");
        name = xname;
    }
    //构造方法
    public Teacher(String xname,int xage){
        System.out.println("two argument");
        System.out.println("new......");
        name = xname;
        age =xage;
    }

    public void teach(String a,int b){

    }

    public void teach(int b,String a ){
        System.out.println("上课");
    }

    public static void main(String[] args) {
        Teacher teach = new Teacher();
        teach.name="连";
        teach.age=18;
        System.out.println(teach.name);
        System.out.println(teach.age);
        Teacher teacher2 = new Teacher("lisi",29);
        System.out.println(teacher2.name);
        System.out.println(teacher2.age);
        Teacher t3 = new Teacher("wangwu");
        System.out.println(t3.name);
    }
}

6、This关键字

this的作用:

  • this表示当前对象本身,表示对当前对象的指针
  • 更准确的说,this代表当前对象的一个引用。

普通方法中使用this:

  • ​ 区分类成员属性和方法的形参
  • ​ 调用当前对象的其他方法
  • ​ 位置:任意

this的用处

  1. 构造方法,当构造方法中的参数名称跟类的成员变量名称一致的时候,可以使用this代表当前对象。

    注意:当有了this之后,可以将构造方法的参数跟成员变量保持一致。

    当构造方法中需要调用其他的构造方法时,可以使用this(name)调用其他构造方法,但是必须位于方法体的第一行。

  2. 普通方法中:

    当多个普通方法之间需要调用的时候,可以使用this来进行调用,指的时当前的对象的其他方阿飞

  3. 成员变量的使用:

    当方法中的参数名称跟成员变量保持一致的时候,使用this.变量名称, 表示的时对象的值,而使用变量名称表示形参列表中的值。

public class ThisDemo {

    String name;
    int age;

    public ThisDemo(){

    }

    public ThisDemo(String name){
        System.out.println("one");
        this.name = name;
    }

    public ThisDemo(String name,int age){
        this(name);
        System.out.println("two");
        this.age = age;

    }

    public void test1(){
        System.out.println("test1");
        this.test2("hehe");
    }
    public void test2(String name){
        System.out.println("test2");
        test1();
        System.out.println(name);
        System.out.println(this.name);
    }


    public static void main(String[] args) {
        ThisDemo td = new ThisDemo("zhangsan",12);
        System.out.println(td.name);
        System.out.println(td.age);
        td.test2("lisi");
    }

}

构造方法中使用this:

  • 使用this来调用其他构造方法
  • 位置:必须是第一条语句
  • this不能用于static方法

ThisDemoReview.java

public class ThisDemoReview {
    int a,b,c;
    ThisDemoReview(){
        System.out.println("正要new一个对象");
    }

    ThisDemoReview(int a,int b){
        //Hello(); //这样是无法调用构造方法的
        this();//调用无参构造方法,且必须位于第一行。

        a = a;//这里都是指的局部变量而不是成员变量
        this.a = a; //这样就区分了成员变量和局部变量,这种情况占了使用情况的大多数!
        this.b = b;
    }
    ThisDemoReview(int a,int b,int c){
        this(a,b); //调用有两个参数的构造方法
        this.c = c; //调用成员变量
    }


    void sing(){}

    void chifan(){
        this.sing();//调用了ThisDemoReview类的sing()方法
        System.out.println("你妈妈喊你回家吃饭");
    }

    public static void main(String[] args){
        ThisDemoReview hi = new ThisDemoReview(2,3);
        hi.chifan();
    }
}

7、static关键字

在类中,用static声明的变量为静态成员变量,或者叫做:类属性,类变量,它为该类的公用变量,属于类,被该类的所有实例共享,在类载入时被显示初始化,对于该类的所有变量所有对象来说,static 成员变量只有一份。被该类的所有对象共享!可以使用“对象,类属性”来调用。不过,一般都是用“类名.属性名”,static变量置于方法区中。

用static 声明的方法为静态方法:

不需要对象,就可以调用(类名.方法名)

在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。

静态方法不能以任何方式引用this和super关键字。

StaticReview.java

public class StaticReview {
    int a;
    static int width;
    static void gg(){
        System.out.println("gg");
    }
    void tt(){
        System.out.println("tt");
    }

    public static void main(String[] args){
        StaticReview hi = new StaticReview();
        StaticReview.width = 2;
        StaticReview.gg();//不用创建对象的情况下直接调用类下的方法
        hi.gg();//通过引用也可以访问static变量或者static方法,不过,一般还是使用类名.static成员来访问。
    }
}

注意:

  • 使用static声明的成员变量成为静态变量

    ​ 普通变量在使用的时候,必须要通过对象名进行调用

    ​ 类变量或者静态变量可以使用对象名调用也使用类名进行调用

  • 使用static声明的方法称为静态方法

    普通方法在使用的时候,必须要通过对象名进行调用

    类方法或者静态方法也可以使用类名,也可以使用对象名

  • 静态变量与静态方法又称为类变量和类方法

注意:

  1. 静态变量,在创建对象之前被初始化,或者说在类被载入之前进行初始化
  2. 静态变量被所有的对象共享,属于公共变量,对象和类都可以直接调用,但是推荐使用类来调用
  3. 成员变量放在堆中,而静态变量放在方法中静态区
  4. 静态变量不能定义在静态方法中
  5. 静态方法可以在非静态方法中进行调用
  6. 静态方法中不能直接调用非静态方法
  7. 静态方法中不允许出现this调用
  8. 一般工具类中的方法定义为static

静态属性的访问形式:

  • ​ 对象名.属性
  • ​ 类名,属性

静态方法

  • 访问修饰符 static 返回值类型 方法名(){}

访问形式

  • 对象名.方法名();
  • 类名.方法名();

static 修饰与非static修饰的区别

static,非private修饰 非static,private修饰
属性 类属性、类变量 实例属性、实例变量
方法 类方法 实例方法
调用方式 类名.属性;类名.方法();对象.属性;对象.方法() 对象.属性;对象.方法()
归属 单个对象

8、代码块

概念:使用{}括起来的额一段代码:

分类:根据位置分类

  • 普通代码块:直接在方法或语句中定义的代码块

  • 构造代码块:直接写在类中的代码块

    定义在类中的使用{}括起来的代码叫做构造代码块
    *           注意:每次代码运行的时候会将构造代码块中的代码添加到构造方法的前面
    *                   构造代码块中的代码会添加到每一个构造方法中,当使用this(参数)的时候不会添加
    
  • 静态代码块:使用static声明的代码块,在程序载入的时候优先执行,数据库连接等其他提前需要准备好的代码会放在static代码块

  • 同步代码块:多线程时会学到,用来给共享空间进行加锁操作(后面讲)

静态初始化块:

  • 如果希望加载后,对整个类进行某些初始化操作,可以使用static初始化块。
  • 类第一次被载入时先执行static代码块;类多次载入时,static代码块只执行一次;Static经常用来进行static变量的初始化。
  • 实在类初始化时执行,不是在创建对象时执行。
  • 静态初始化块中不能访问非static成员。(static是在类加载的时候就开始加载,而非static成员是在创建对象的时候,即new操作的时候才初始化,所以静态初始化块中不能访问非static成员,因为这个时候对象根本还没有创建)

执行顺序:静态代码块–》动态代码块(创建对象的时候才会用到)–>普通代码块。

package com.mashibingReview;

public class CodeBlockReview {
    int a;
    int b;
    static{
        System.out.println("静态代码块");
    }
    public CodeBlockReview(){
        System.out.println("无参");
        System.out.println("构造方法");
    }

    public CodeBlockReview(int a){
        this.a = a;
    }
    public CodeBlockReview(int a,int b){
        this(a);
        this.b = b;
    }
    {
        System.out.println("构造代码块");
    }

    public void test(){
        System.out.println("test");
        {
            System.out.println("我应该是什么分类");
        }
    }
    public static void main(String[] args){
        CodeBlockReview codeBlockReview = new CodeBlockReview(1,2);
        codeBlockReview.test();
        {
            System.out.println("main");
        }
    }

}

9、pakcage

为什么需要package:

  • 为了解决类之间的重命名。
  • 为了便于管理类:合适的类位于合适的包,将具体处理功能的代码放到同一个目录下

package用法:

  • 通常是类的第一句非注释性语句。
  • 包名:域名倒着写就可以。加上模块名,并与内部管理类。

使用:

​ 一般定义package 会放置在java文件的第一行

​ package 域名的倒写

​ package com.mashibing.

完全限定名: 报名+类名

注意事项:

  • 写项目时都要加包,不要使用默认包。
  • com.gao和com.gao.car,没有任何关系,是两个安全独立的包,只是看起来逻辑上后者是前者的一部分。

JDK中的主要包:

  • java.lang: 包含一些Java语言的核心类,如String,,Integer,System.Thread,提供常用功能。
  • java.awt: 包含了构成抽象窗口工具集(Abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面。
  • java.net:包含执行与网络相关的操作的类。
  • java.io:包含提供多种输入/输出功能的类。
  • java.util: 包含一些使用工具类,如定义系统特性,使用与日期日历相关的函数。
public class PackageDemo {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
    }
}

10、import

import:

  • 当需要引入非lang包的其他java类的时候,需要使用import工具

  • 如果不适用import,每次在使用某个类的时候必须要将类的完全限定名加商才可以使用,太过于繁琐

  • 用法:

    import java.包名.类名; //导入具体的类,推荐使用

    import 包名.*; //将当前包下的所有类文件都进行导入

  • 注意:当一个java文件需要使用多个同名类的时候,只能选择导入一个,另一个使用完全限定名的方式导入.java.util.Date();

  • 静态导包:当需要使用某个类的方法的时候,同时又不想频繁写该类的名称,可以使用静态导包。

package com.mashibing;
import static java.lang.Math.*;
public class ImportDemo {

//    public void sqrt(){
//        System.out.println("sqrt");
//    }
    public static void main(String[] args) {
//        java.util.Date date = new java.util.Date();
//        Date date = new Date();
//        java.sql.Date date1 = new java.sql.Date();
        System.out.println(Math.sqrt(2));
        System.out.println(Math.abs(-2));
        System.out.println(sqrt(2));
        System.out.println(abs(-2));
    }
}

通过import可以导入其他包下面的类,从而可以在本类中直接通过类名来调用。

使用方式

import java.util.Date;

import java.util.*; //导入该包下所有的类。因此这些类我们可以直接使用

注意:如果导入两个同名的类,只能用报名+类名来显示调用相关类

java.util.Date date = new java.util.Date();

import static : 静态导入的作用:用于导入指定类的静态属性

JDK5.0后增加

示例:import static java.lang.Math.*; //导入Math类的所有静态方法

import static java.lang.Math.PI;//导入Math类的Pi属性

然后就可以在程序中直接使用System.out.println(PI)

11、封装

面向对象的三大概念之一 封装

封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

封装解决的问题:

  • 如果任何一个处理类都可以直接对Dog进行赋值操作,那么当值不准确的时候,可能会产生额外的结果。
  • 再赋值的时候添加一些逻辑判断

封装得好处:

  • 只能通过规定方法访问数据,其他方法无法访问呢
  • 隐藏类得实现细节
  • 方便加入控制语句,根据需求添加复杂的逻辑判断语句
  • 方便修改实现

面向对象的封装(狭义)可以用一句话概述: 为了保证数据安全和规范:将类中的属性设置为私有,提供共有的外部方法供程序进行调用,可以实现丰富的细节操作。

广义的封装:可以将完成特定功能的代码块封装成一个方法,供不同程序进行调用。

11.1、封装的步骤

  • 修改属性的可见性:设为private
  • 创建共有的getter/setter方法: 用于属性的读写
  • 在getter/settter方法中加入属性控制语句: 对属性值的合法性进行判断

12、面向对象的三大特征

  • 继承:inheritance

    1. 子类 父类
    2. 子类可以从父类继承属性和方法
    3. 子类可以体哦那个自己单独的属性和方法
  • 封装/隐藏 encapsulation

    1. 对外隐藏某些属性和方法
    2. 对外公开某些属性和方法
  • 多态 polymorphism

    1. 为了适应需求的多种变化,使代码变得更加通用!

面向过程只有封装性(功能的封装,而没有数据的封装),没有继承和多态。

  • 成员变量(成员或者成员方法)访问权限共有四种:

    1. public公共的:可以被项目中所有的类访问(项目可见性)

    2. protected受保护的: 可以被这个类本身访问:同一个包中的所有其他的类的访问:被它的子类(同一个包以及不同包中的子类)访问

    3. default/firendly 默认的/友好的(包可见性):被同一个包中的类访问,即,可以被当前类访问,也可以被当前包访问。

    4. private:私有的: 只能被这个类访问

      注意:四种访问修饰符可以修饰属性和方法

      类的访问修饰符只有两个,public default

    public class AccessControlDemo {
    
    
        public AccessControlDemo(){
    
        }
    
        protected AccessControlDemo(int a,int b){
    
        }
        private String str = "test";
    }
    
    class Test{
    
    

封装的权限表格示意

同一个类 同一个包 子类 所有类
pirvate *
default * *
protected * * *
public * * * *

封装的要点:

  • 类的属性的处理
  1. 一般使用private(除非本属性确定会让子类继承)
  2. 提供相应的get/set方法来访问相关属性。这些方法通常是public,从而提供对属性的读取操作。(注意:boolean变量的get方法是用:is开头!)
  • 一些只用于本类的辅助性方法可以用Private,希望其他类调用的方法用public

方法调用中的参数传递(重中之重)

  • 基本数据类型的参数传递:不能改变参数的值
  • 引用数据类型的参数传递:不能改变参数的值

方法参数的值是否改变:

  • 方法中的参数列表叫做形式参数,没有具体的值,只是为了方便在方法体中使用

  • 调用方法的时候实际传入的值叫实际参数,代表具体的数值,用来替换在方法中代码逻辑的值进行运算

  • 注意:

    1. 形式参数的变量名称也是局部变量
    2. 当方法的参数值是基本数据类型的时候,不会改变原来的值。
    3. 当方法的参数值是引用类型的时候,如果改变了该引用类型的值,会改变原来对象的值
    4. java中的参数传递是传递。
package com.mashibing;

public class ArgumentReview {
    public static void test(int a,int b){
        int tmp = a;
        a = b;
        b = tmp;
    }

    public static void test2(PointReivew pointReivew){
        int x = pointReivew.getX();
        int y = pointReivew.getY();
        int tmp = x;
        x = y ;
        y = tmp;
        pointReivew.setX(x);
        pointReivew.setY(y);
    }

    public static void main(String[] args){
        PointReivew pointReivew = new PointReivew(2,3);
        test2(pointReivew);
        System.out.println(pointReivew.getX());
        System.out.println(pointReivew.getY());
    }
}

package com.mashibing;

public class PointReivew {
    private int x;
    private int y;

    public int getX(){
        return x;
    }
    public void setX(int x){
        this.x = x;
    }

    public int getY(){
        return y;
    }
    public void setY(int y){
        this.y = y;
    }

    public PointReivew(int x, int y ){
        this.x = x;
        this.y = y;
    }
}


this

  • This代表当前对象的自身的引用(必须new)
  • This可以修饰属性,区别成员变量和局部变量
  • This修饰方法
  • This修饰构造方法(必须是第一条语句)

static

  • static变量:只有一份,属于类,可以类名.static变量
  • static方法:类名.Static方法,不能出现this和super.
  • static代码块: 只执行一次,最早执行的(类第一次调用)

package import

  • 包:作用
  • 导入:import com.bjsxt.oop.*;
  • 静态导入:import static java.lang.Math.PI;

12、继承

继承:

  • 表示父类跟子类之间的关系
  • 当两个类或者多个类具备相同的属性和方法的时候,可以提取出来,变成父类,子类可以继承
  • 子类跟父类是is-a的关系。

使用:

  1. 使用继承的时候需要使用extend关键字
  2. 使用继承关系后,父类中的属性和方法都可以在子类中进行使用(非私有属性和非私有方法)
  3. java中是单继承关系(如果包含的多个父类,同时父类中包含重名方法,无法决定该调用谁)
  • 类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建筑。
  • 提高代码的复用性。
  • extand的意思是扩展。子类是父类的扩展。
  • 不同的叫法:超类、父类,基类,子类,派生类。

使用继承的方法:

class Pet{
//公共的属性和方法
}

编写子类,继承父类
class Penguin extands(继承关键字) Pet(只能继承一个父类){

}

子类不能继承父类的某些资源:

  • 不能直接访问private成员
  • 子类与父类不在同一个包,使用默认访问权限的成员
  • 构造方法

访问修饰符总结

访问修饰符号 本类 同包 子类 其它
private *
默认(friendly) * *
protected * * *
public * * * *

多重继承关系的初始化顺序是:

父类属性—》父类构造方法–》子类属性–》子类构造方法

  • 通过继承可以简化类的定义,实现代码的复用

  • 子类继承父类的成员变量和成员方法,但不能继承父类的构造方法

  • java中只有单继承

  • java的多继承,可以通过接口实现

  • 如果定义一个类时,没有调用extends,则它的父类时java.lang.Object.

13、Super关键字

  • Super关键字是直接父类对象的引用。
  • 可以通过super来访问父类中被子类覆盖的方法或属性。
  • 普通方法:
    • 没有顺序限制,可以随便调用
  • 构造函数中:
    • 任何类的构造函数中,若是构造函数的第一行代码没有显示的调用super(…);那么java都会默认调用super();作为父类的初始化函数。所以这里的super();加不加都无所谓。

子类访问父类成员

  • 访问父类构造方法:

    super();

    super(name);

  • 访问父类属性

    ​ super.name;

  • 访问父类方法

    ​ super.print();

Supser关键字访问父类成员:

  • super关键字只能出现在子类的方法和构造方法中
  • super调用构造方法时,只能是第一句,super和this不能同时出现在构造方法中
  • super不能访问父类成员中的private成员
  • super和this都不同出现在static方法中(因为static是在类初始化时就存在的,而此时对象还没有创建,super和this故而不能出现在static方法中)

super用途:

  1. 可以在子类中调用父类中被子类覆盖的方法, super.父类方法名称
  2. 当super在普通方法中使用的话,可以任意位置编写
  3. 当super在构造方法中使用的话,会调用父类的构造方法,一定要将super放在第一行
  4. 在构造方法中super关键字和this关键字不能同时出现
  5. 父类中私有的属性和方法都不能被调用,包括构造方法
  6. 子类的构造方法中都会默认使用super关键字调用父类的无参数构造方法,因此在定义类的时候,无论自己是否自定义了构造方法,最好将无参构造方法写上。
  7. 如果构造方法中显示指定了super的构造方法,那么无参的构造方法就不会被调用

总结:

  1. 在创建子类对象的时候一定会优先创建父类对象
  2. 所有的java类都具备同一个老祖宗类,称之为Object,是所有类的根类

14、方法重写

必须要存在继承关系,当父类中的方法无法满足子类需求的时候,可以选择使用重写的方式

注意:

  1. 重写表示的是子类覆盖父类的方法,当覆盖之后,调用同样方法的时候会优先调用子类。

  2. 重写的方法名称,返回值类型,参数列表必须跟父类一样

  3. 子类重写的方法不允许比父类的方法具有更小的访问权限

    父类 Public 子类 public

    父类 protected 子类 public protected

    父类 protected 子类 Public protected default

    父类的静态方法子类可以进行调用,但是子类不可以重写

  • 在子类中可以根据需要对从父类中继承来的方法进行重写。
  • 重写方法必须和被重写方法具有相同的方法名称,参数列表,和返回类型一致
  • 重写方法不能使用比被重写方法更严格的访问权限(多态决定)

方法的重写与重载

位置 方法名 参数列表 返回值 访问修饰符
方法重写 子类 相同 相同 相同或者是其子类 不能比父类更严格
方法重载 同类 相同 不相同 无关 无光

15、抽象类(Abstract)

由于某些类(比如宠物,)没有实例化的意义,因为就算实例化了,那么也不知道到底是什么宠物,因此可以将这样的类定义为抽象类。

抽象类:

  1. 创建抽象类的时候需要添加abstract关键字
  2. 抽象类不能实例化,也就是不能new对象
  3. 抽象类中的某些方法需要子类进行更丰富的实现,父类实现没有意义,此时可以将抽象类中的方法定义为抽象方法,没有具体的实现,只包含方法名称,返回值,参数列表,访问修饰符。
  4. 使用abstract关键字修饰的方法就叫抽象方法,可以不写方法的实现。
  5. 子类在继承抽象父类的时候,必须要将父类中的抽象方法进行实现或者将子类也定义为抽象类。
  6. 有抽象方法的类一定是抽象类,但是抽象类不一定包含抽象方法
package com.mashibing.abstracts;


public abstract class Pet {

    private String name;
    private int age;

    public abstract void print();

    public void play(){
        System.out.println("play....");
    }

所有java中使用抽象类,限制实例化

public abstract class Pet{

}

abstract也可用于方法—抽象方法

抽象方法没有方法体

  • 抽象方法必须在抽象类里

  • 抽象方法必须在子类中被实现,除非子类是抽象类。

    public abstract void print();//没有方法体
    
    

16、final的用法

使用fainal修饰引用变量,变量的值是固定不变的,而变量所指向的对象的属性值是可变的。

  • final可以修饰变量:表示变量的值不可变,只能在初始化时赋值。
  • final可以修饰方法: 表示方法不可被子类重写
  • final可以修饰类: 表示类不可以被继承

17、Object类

一个类如果没有使用extends显性的继承另外一个类,那么这个类继承自Object类。

object类的主要方法:

  • toString()方法
  • equals()方法:

对象的比较-- ==和equals()

==:

  • 比较两类基本类型变量的值是否相等
  • 比较两个引用类型的值即内存地址是否相等,即是否指向同一对象。

equals():

两对象的内容是否一致。

注意:自定义类必须重写equals(),否则其对象比较结果总是false.

父类方法的重写:

父类方法的重写:

– “ ==”:方法名、形参列表相同。

– “≤≤”:返回值类型和异常类型,子类小于等于父类。

– “≥”:访问权限,子类大于等于父类

构造方法调用顺序

– 根据super的说明,构造方法第一句 总是:super(…)来调用父类对应的构造

方法。

– 先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直

到当前子类为止。

Object类的6个常用方法:

  1. public String toString() 获取对象信息的方法
  2. public boolean equals(Object obj) 对象相等判断方法,此方法必须被重写
  3. public native int hashCode() 对象签名
  4. public final native Class<> getClass() 返回此object的运行时的类。
  5. protected native Object clone() protected的修饰方法
  6. protected void finalize()

18、多态

多态:对应同一个指令(调用同一个名称的方法),不同的对象给予不同的反应(不同的方法实现),

规范(多态实现的前提):

  1. 必须要有继承
  2. 子类方法必须重写父类的方法
  3. 父类引用指向子类

多态的目的:

  1. 为了提高代码的扩展性和维护性
  2. 方便代码逻辑的缩写

多态的两种表现形式:

1、父类作为方法的参数

2、父类作为方法的返回值类型

使用多态的思路:

  • 编写父类
  • 编写子类,子类重写父类方法
  • 运行时,使用父类的类型,子类的对象

实现多态的两种形式:

  • 使用父类作为方法形参实现多态
  • 使用父类作为方法返回值实现多态

类型转换:

向上转型:子类转为父类,自动进行类型转换

向下类型:父类转换为子类,结合instanceof运算符进行强制类型转换

引用类型的转换跟基本数据类型的转换类似:

  1. 当父类需要转换成子类时,需要进行强制转换,但是在强制转换之前一定要先判断父类引用指向的子类对象到底是谁,如果无法确定,在运行过程中可能会出错。
  2. 当子类需要向父类转换的时候,直接自动转化,不需要进行任何判断。

多态存在的必要条件

  • 没有继承
  • 要有方法重写
  • 父类引用指向子类

引用数据类型的类型转换

子类转换为父类:自动转换

– 上转型对象丌能操作子类新增的成员变量和方法。

– 上转型对象可以操作子类继承或重写的成员变量和方法

– 如果子类重写了父类的某个方法,上转型对象调用该方法时,是调用的重写

方法。

▪ 父类转换为子类:强制转换

– (绝丌是做手术,而是父类的真面目就是一个子类,否则会出现类型转换错

误)

多态示例:

public abstract  class Pet {
    public abstract void fed();
    public void play(){
        System.out.println("Playing...");
    }
}
public class Cat extends Pet {
    @Override
    public void fed() {
        System.out.println("猫在吃鱼");
    }
}
public class Dog extends Pet {
    @Override
    public void fed() {
        System.out.println("狗在吃骨头");
    }
}

public class Penguin extends Pet {
    @Override
    public void fed() {
        System.out.println("企鹅在吃。。。");
    }
}

public class Person {
    public void feed(Pet pet){
        pet.fed();
    }

    public void play(Pet pet){
        pet.play();
    }

    public Pet buyPet(int type){
        if(type==1){
            return new Dog();
        }else if(type == 2){
            return new Cat();
        }else{
            return new Penguin();
        }
    }

    public static void main(String[] args){
        Person p = new Person();
        Pet dog = new Dog();
        Pet cat = new Cat();
        Pet penguin = new Penguin();
        p.feed(dog);
        p.feed(cat);
        p.feed(penguin);
        p.play(dog);
        p.play(cat);
        Pet pet = p.buyPet(2);
        if(pet instanceof Dog){
            System.out.println("买的是一只狗");
        }else if(pet instanceof Cat){
            System.out.println("买的是一只猫");
        }else{
            System.out.println("买的是一只企鹅");
        }

    }
}

19、接口

java中的继承是单继承,如果拥有多个父类的时候,可以考虑使用接口进行实现。

java中的接口具备广泛的使用:

​ 用法:

  • 使用interface来修饰
  • 接口中可以包含多个方法,且方法跟抽象类中的抽象方法一致,可以不写实现,子类在实现的时候必须要实现。
  • 子类接口使用implements关键字。

特征:

  1. 接口中的所有方法都是抽象方法,不能包含方法的实现。
  2. 接口中的所有方法的访问修饰权限都是public,不写并不是默认的访问权限,而是Public.
  3. 接口不能被实例化。
  4. 接口的子类必须要实现接口中的所有方法,跟抽象类不同,抽象类中的抽象方法必须要被子类实现。
  5. 子类可以拥有实现多个接口。
  6. 接口中的变量都是静态常量,如果变量没有使用static关键字修饰,它也表示静态常量。不用final也表示静态常量。因为jvm编译时会自动加入static,final关键词。
  7. 接口中的方法和常量无论是否添加public修饰,默认的权限有且只有一个,就是public.

接口的使用:

  • 接口代表一种能力,接口中可以定义N多个放过发,子类在进行实现的时候,必须要实现这些方法
  • 将这些方法进行实现,就意味着具体了某种能力
  • 关心实现类有何能力,而不关心实现细节

抽象类和接口的区别:

  1. 抽象类中的方法可以有抽象方法,也可以有普通方法,但是接口中只能包含抽象方法。
  2. 抽象类需要使用abstract关键字来修饰,而接口使用interface关键字来修饰。
  3. 子类使用extends关键字来继承抽象类,使用implements来实现接口。
  4. 子类继承抽象类的时候,必须要实现所有的抽象方法,普通方法可以不重写,而接口中的所有方法都必须要重写。
  5. 抽象类可以定义成员变量,而接口中只能定义静态常量。
  6. 抽象类中在子类实现的时候是单继承,而接口时多继承。
  7. 抽象类和接口都不能实例化,但是抽象类中可以有构造方法,而接口中不能有构造方法。
  8. 抽象类中可以实现接口并且不能实现接口中的方法,而接口只能继承接口,不能实现接口。

注意:

  • 在实际的项目中,如果可以使用接口,尽量使用接口,将单继承的父类留在最关键的地方。
  • 可以定义一个新接口,用extends去继承一个已有的接口。
  • 可以定义一个类,用implements去实现一个接口中的所有方法。
  • 可以定义一个抽象类,用implements去实现一个接口中的部分方法。
  • 接口不能创建实例,但是可用于声明引用变量类型。
  • 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是Public的。
  • java的类只支持单继承,接口支持多继承。
  • 外部类不能直接使用内部类的成员和方法
  • 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己成员变量或者方法,如果访问外部类的成员变量,需要使用this关键字。
//外部类
public class Outer{
    String name = "张三";
    public class Inner//内部类
    {
       String name = "李四";
        public void print(){
            System.out.println("外部类:name"+Outer.this.name);
            System.out.println("内部类:name"+name);
        }
    };
    public static void main(String[] args){
        Outer o = new Outer(); //创建外部类对象
        o.new Inner().print();
    }
 }

定义接口的格式:

[访问修饰符] interface 接口名 [extends 父接口1,父接口2…]{

​ 常量定义 //总是public static final

方法定义 //总是public abstract

}

要求实现防盗门的功能
门有“开”和“关”的功能,锁有“上锁”和“开锁” 的功能 将门和锁分别定义为抽象类
防盗门可以继承门的同时又继承锁吗?
如何解决这个问题呢?

将门定义为抽象类,锁定义为接口 防盗门继承门,实现锁的接口

package com.mashibing.interfacedemo;

public abstract class Door {

    public abstract void openDoor();

    public abstract void closeDoor();
}

package com.mashibing.interfacedemo;

public interface DoorBell {
    void photo();
}

package com.mashibing.interfacedemo;

public interface Lock {

   static  int a = 100;

   void openLock();
   void closeLock();

}

package com.mashibing.interfacedemo;

public class LockDoor extends Door implements Lock,DoorBell {
    @Override
    public void openDoor() {
        System.out.println("开门");
    }

    @Override
    public void closeDoor() {
        System.out.println("关门");
    }

    @Override
    public void openLock() {
        System.out.println("开锁");
    }

    @Override
    public void closeLock() {
        System.out.println("关锁");
    }

    @Override
    public void photo() {
        System.out.println("拍照存档");
    }
}

package com.mashibing.interfacedemo;


public class TestLockDoor {
    public static void main(String[] args){
        LockDoor lockDoor = new LockDoor();
        lockDoor.openDoor();
        lockDoor.openLock();
        lockDoor.closeDoor();
        lockDoor.closeLock();
        lockDoor.photo();
        System.out.println(LockDoor.a);

    }
}

使用程序描述USB接口:

USB风扇,USB鼠标,U盘

package com.mashibing.interfacedemo2;

public interface Usb {
    public void DataTransfer();


}
package com.mashibing.interfacedemo2;

public class Upan implements Usb {
    @Override
    public void DataTransfer() {
        System.out.println("upan可以传输数据");
    }
}

package com.mashibing.interfacedemo2;

public class Mouse implements  Usb{

    @Override
    public void DataTransfer() {
        System.out.println("鼠标来点击屏幕");
    }


}
package com.mashibing.interfacedemo2;

public class Fengshan implements Usb {
    @Override
    public void DataTransfer() {
        System.out.println("Usb风扇可以吹风");
    }
}
package com.mashibing.interfacedemo2;

public class Test {
    public static void main(String[] args){
        Mouse mouse = new Mouse();
        mouse.DataTransfer();
        Upan up = new Upan();
        up.DataTransfer();
        Fengshan fengshan = new Fengshan();
        fengshan.DataTransfer();
    }
}

模拟实现打印机

package com.mashibing.interfacedemo3;

public interface InkBox {
    public void getWriteAndBlock();

    public void getcolor();
}
package com.mashibing.interfacedemo3;

public interface Paper {
    public void getA4();
    public void getB5();
}

package com.mashibing.interfacedemo3;

import com.mashibingReview.CodeBlockReview;

public class CopyMachine implements InkBox,Paper{
    @Override
    public void getWriteAndBlock() {
        System.out.println("使用黑白磨合打印");
    }

    @Override
    public void getcolor() {
        System.out.println("使用彩色墨盒打印");
    }

    @Override
    public void getA4() {
        System.out.println("使用A4纸");
    }

    @Override
    public void getB5() {
        System.out.println("使用B5纸");
    }

    public static void main(String[] args){
        CopyMachine copyMachine = new CopyMachine();
        copyMachine.getWriteAndBlock();
        copyMachine.getA4();
    }
}

训练要点: – 接口的基础知识 – 理解接口表示一种约定 ▪ 需求说明: – 采用面向接口编程思想组装一台计算机。 – 计算机的主要组成部分有: ▪ CPU ▪ 硬盘 ▪ 内存

package com.mashibing.interfacedemo4;

public interface CPU {
    public String getBrand();
    public String getHz();
}

package com.mashibing.interfacedemo4;

public interface HardDisk {
    public String getVolumn();
}

package com.mashibing.interfacedemo4;

public interface Memory {
    public void getCapacity();

package com.mashibing.interfacedemo4;

public class AmdCpu implements CPU {
    @Override
    public String getBrand() {
        return "amd";
    }

    @Override
    public String getHz() {
        return "1000";
    }
}

package com.mashibing.interfacedemo4;

public class InterCpu implements CPU{
    
    @Override
    public String getBrand() {
        return "inter";
    }


    @Override
    public String getHz() {
        return "2000";
    }
}

package com.mashibing.interfacedemo4;

public class SXHardDisk implements HardDisk {
    @Override
    public String getVolumn() {
        return "三星";
    }
}

package com.mashibing.interfacedemo4;

public class JSDHardDisk implements HardDisk {
    @Override
    public String getVolumn() {
        return "金士顿";
    }
}

package com.mashibing.interfacedemo4;

public class Computer  {
    public void show(CPU cpu,HardDisk hardDisk) {
        System.out.println("计算机的组成如下");
        System.out.println("cpu:"+cpu.getBrand()+",主频是:"+cpu.getHz());
        System.out.println("硬盘容量是:"+hardDisk.getVolumn());
    }
}

package com.mashibing.interfacedemo4;

public class Test {
    public static void main(String[] args){
        Computer computer = new Computer();
        CPU cpu = new InterCpu();
        HardDisk hardDisk = new JSDHardDisk();
        computer.show(cpu,hardDisk);
    }
}

20、内部类

内部类(当作类中的一个普通成员变量,只不过此成员变量是class的类型):

  • 一个java文件中可以包含多个class,但是只能有一个public class
  • 如果一个类定义在另一个类的内部,此时可以称之为内部类

使用:

  • 创建内部类的时候,跟之前的方法不一样,需要在内部类的前面添加外部类来进行修饰
  • InnerClassDemo.InnerClass inner = new InnerClassDemo().new InnerClass();

特点:

  • 内部类可以方便的访问外部类的私有属性。
  • 内部类作为外部类成员,可声明为private ,默认,protected或public.
  • 内部类成员只有在内部类的范围内是有效的。
  • 用内部类定义在外部类中不可访问的属性,这样就在外部类实现了比外部类的private的海啸的访问权限。
  • 外部类不能访问内部类的私有属性,但是如果创建了内部类的对象,此时可以在外部类中访问私有属性。
  • 内部类中不能定义静态属性
  • 当内部类和外部类具有相同的私有属性的时候,在内部类中访问的时候,可以直接访问内部类的属性,如果需要访问外部类的属性,那么需要添加 外部类类名.this.属性。

在外部访问内部类:

语法:

外部类 外部类对象 = new 外部类();

外部类.内部类 内部类对象 = 外部类对象.new 内部类();

public static void main(String[] args){
	Outer out = new Outer(); //创建外部类的对象
    Ounter.Inner inner = out.new Inner(); //创建内部类的对象
    inner.print();//访问内部类的方法。
}

注意,如果主方法在外部类内部,则可以省略Outer

Inner inner = out.new Inner();

package com.mashibing.innerdemo2;

public class Outer {
    private String name = "zhangsan";
    class Inner{
        private String name = "lisi";

        public void show() {
            System.out.println(name);
            System.out.println(this.name);
            System.out.println(Outer.this.name);
        }
    }

    public static void main(String[] args){
        Outer.Inner inner = new Outer().new Inner();
        inner.show();
    }
}

package com.mashibing.innerdemo;

public class InnerClassDemo {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("show");
        InnerClass inner = new InnerClass();
        System.out.println(inner.age);

    }

    class InnerClass{
        private int age;

        public void test(){
            System.out.println("test");
            System.out.println(id);
            System.out.println(name);
        }

        class InnerInner{
            private int id;
            public void print(){
                System.out.println("print");
            }
        }
    }
    public static void main(String[] args){
        InnerClass innerClass = new InnerClassDemo().new InnerClass();
    }
}
package com.mashibing.innerdemo;

public class TestInnerClass {

    public static void main(String[] args){
        System.gc();
        InnerClassDemo innerClassDemo = new InnerClassDemo();
        innerClassDemo.show();
        System.out.println(innerClassDemo.getId());
        InnerClassDemo.InnerClass inner = new InnerClassDemo().new InnerClass();
        inner.test();

        InnerClassDemo.InnerClass.InnerInner innerInner= new InnerClassDemo().new InnerClass().new InnerInner();
    }
}

分类:

  • 匿名内部类:当定义了一个类,实现了某个接口的时候,在使用过程中只需要使用一次,没有其他用途,此时考虑到代码编写的简洁,可以考虑不创建具体的类,而采用new interface(){添加未实现的方法},就叫做匿名内部类

    package com.mashibing.innerdemo2;
    
    public class NoNameInnerClassDemo {
        public static void main(String[] args){
            System.out.println("有一万行代码");
            new Thread(new Runnable() {
                @Override
                public void run() {
    
                }
            });
            System.out.println("有一万行代码");
        }
    }
    
    
    class Runner implements Runnable{
    
        @Override
        public void run() {
    
        }
    }
    
  • 静态内部类:在内部类中可以定义静态内部类,使用static关键字进行修饰,使用规则,外部类.内部类 类的引用名称 = new 外部类.内部类();

  • 语法如下:

  • new 外部类类名.内部类().方法名

    外部类类名.内部类 内部类对象名 = new 外部类类名.内部类类名();

package com.mashibing.innerdemo2;

public class StaticClass {
    private int id;

    public void test(){
        System.out.println("test");
    }

    static class InnerClass{
        private String name;
        public void show(){
            System.out.println("show");
        }
    }

    public static void main(String[] args) {
        InnerClass innerClass =new StaticClass.InnerClass();
    }
}
  • 方法内部类:在外部类的方法中可以定义类,此时叫做方法内部类(了解即可)。使用的时候需要注意,只能在方法中创建对象,因为此class的作用域就是当前方法。当方法在传递参数的时候需要注意。

  • 方法内部类不能在外部类的方法以外的地方使用,所以,方法内部类不能使用访问控制符和static修饰符

    package com.mashibing.innerdemo2;
    
    public class MethodInnerClass {
        public void show(int number){
            System.out.println("show");
    
            class InnerClass{
                private String name;
                public void test(int a){
                    System.out.println("test");
                    System.out.println(a);
                    System.out.println(number);
                }
            }
    
            new InnerClass().test(12);
    
        }
    
        public static void main(String[] args) {
            MethodInnerClass methodInnerClass = new MethodInnerClass();
            methodInnerClass.show(134);
    
        }
    }
    

21、垃圾回收机制

对象空间的分配:

  • 使用new关键字创建对象即可

对象空间的释放:

  • 对于传统的c/c++,需要程序员主动回收已经分配的内存。显示回收内存的缺点如下:

    1. 程序忘记回收时,导致内存泄漏 ,降低系统性能。
    2. 程序错误回收程序核心类库的内存,导致系统崩溃。
  • java语言不需要程序员主动控制回收内存,由JRE在后台自动回收不再使用的内粗,称为垃圾回收机制(Garbage Collection)

    1. 可以提高编程效率
    2. 保护程序的完整性
    3. 其开销影响性能。

垃圾回收机制的要点:

  • 垃圾回收机制只回收JVM堆内存里的对象空间。
  • 对其他物理连接,比如数据库练级额,输入流输出流,Socket无能为力。
  • 现在jvm有多种垃圾回收实现算法,变现各异。
  • 垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。
  • 可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。
  • 程序员可以通过System.gc()或者Runntime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是以系统是否进行垃圾税收依然不确定。
  • 垃圾回收机制回收任何对象之前,总会调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。
  • 永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。

22、小练习

设计Dog和Penguin类

运用面向对象思想抽象出Dog类和Penguin

package com.mashibing.extend;

public class Pet {
    private String name;
    private int age;
    private String gender;
    protected String abc;

    public Pet(){
        System.out.println("pet 无参构造方法");
    }

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

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public int getAge(){
        return age;
    }

    public void setAge(int age){
        this.age = age;
    }

    public String getGender(){
        return gender;
    }
    public void setGender(String gender){
        this.gender = gender;
    }

    private void play(){
        System.out.println("static test");
    }
    public static void test(){
        System.out.println("static test");
    }
    @Override
    public String toString(){
        return "my name is"+this.name+",my age is"+this.age+",my gender is "+this.gender;
    }

}
package com.mashibing.extend;

public class Dog extends Pet {
    private String sound;

    public Dog(){
        System.out.println("Dog 无参数构造");
    }

    public Dog(String name,int age,String gender,String sound){
        this.sound = sound;
    }

    public String getSound(){
        return sound;
    }

    public void setSound(String sound){
        this.sound = sound;
    }
    public void play(){
        System.out.println("dog is playing ball");
    }

    public String toString(){
        return super.toString()+",my sound is "+this.sound;
    }

}

package com.mashibing.extend;

public class Penguin extends Pet {
    private String color;
    public Penguin(){

    }

    public Penguin(String name,int age,String gender, String color){
        super(name,age,gender);
        this.color = color;
    }

    public String getColor(){
        return color;
    }

    public void setColor(){
        this.color = color;
    }

    public void play(){
        System.out.println("Penguin is playing ice");
    }
}

public class PetTest {

    public static void main(String[] args) {

//        Dog dog = new Dog("小黑",12,"男","汪汪");
//        dog.setName("大黄");
//        System.out.println(dog.getName());
//        dog.play();
//        dog.p

        Pet pet = new Pet();
        System.out.println(pet);
        Dog dog = new Dog();
        System.out.println(dog);
        dog.test();
    }

某汽车租赁公司出租多种车辆,车辆以及租金情况如下:

轿车 轿车 轿车 客车 客车
车型 别克商务舱GL8 宝马550i 别克林荫大道 <=16座 >16座
日消费(元/天) 600 500 300 800 1500

案例分析:

发现类: MotoVehicle(机动车,抽象类)

​ Car

​ Bus

发现类的属性:MotoVehicle(No车牌号,Brand品牌)

​ Car: type 型号

​ Bus: SeatCount

发现类的方法: MotoVehicle:( CalcRent(int dats)): 抽象方法

​ Car(final): Car(no, brand,type)

​ Bus(final): Bus(no, brand, seatCount)

优化设计: 抽取父类,检查abstract,final

编写程序入口:实例化类的对象; 调用CalcRent方法计算租金

编写测试代码运行:实例化类的对象; 调用CalcRent方法计算租金

代码如下:

package homeworkReview;

public abstract class MotoVehicleReview {
    private int no;
    private String brand;
    public MotoVehicleReview(){
    }

    public MotoVehicleReview(int no,String brand){
        this.no = no;
        this.brand = brand;
    }

    public int getNo(){
        return no;
    }

    public void setNo(int no){
        this.no = no;
    }

    public String getBrand(){
        return brand;
    }

    public void setBrand(String brand){
        this.brand = brand;
    }

    public abstract int calcRent(int day);

}

package homeworkReview;

public class Bus extends MotoVehicleReview {
    private int seatcount;

    public Bus(){

    }

    public Bus(int no ,String brand,int seatcount){
        super(no,brand);
        this.seatcount = seatcount;
    }

    public int getSeatcount(){
        return seatcount;
    }

    public void setSeatcount(int seatcount){
        this.seatcount = seatcount;
    }

    @Override
    public int calcRent(int day) {
        if(seatcount>16){
            return 1500*day;
        }else{
            return 800*day;
        }
    }
}
package homeworkReview;

public class Car extends MotoVehicleReview {
    private  String type;
    public Car(){
    }

    public Car(String type){
        this.type = type;
    }

    public Car(int no, String brand,String type){
        super(no,brand);
        this.type = type;
    }

    public String getType(){
        return type;
    }

    public void setType(String type){
        this.type = type;
    }


    @Override
    public int calcRent(int day) {
        if(type.equals("0")){
            return 600*day;
        }else if(type.equals("1")){
            return 500*day;
        }else if(type.equals("2")){
            return 300*day;
        }else{
            System.out.println("类型不匹配");
            return 0;
        }
    }
}

package homeworkReview;

import java.lang.annotation.Target;

public class Track extends MotoVehicleReview {
    private int weight;

    public Track(){

    }

    public Track(int no,String brand,int weight){
        super(no,brand);
        this.weight = weight;
    }

    @Override
    public int calcRent(int day) {
        return 50*day*weight;
    }
}
package homeworkReview;

public class TestMotoVehicle {

    public static void main(String[] args){
        MotoVehicleReview[] moto = new MotoVehicleReview[5];
        moto[0] = new Car(1,"宝马","1");
        moto[1] = new Car(1,"宝马","1");
        moto[2] = new Car(2,"别克","2");
        moto[3] = new Bus(3,"金龙",34);
        moto[4] = new Track(4,"解放",50);
        int totalMOney = calcTotal(moto);
        System.out.println("总租金是:"+totalMOney);
    }

    public static int calcTotal(MotoVehicleReview[] moto){
        int totalMoney = 0;
        for(int i = 0;i<moto.length;i++){
            totalMoney += moto[i].calcRent(5);
        }
        return totalMoney;
    }
}

/*

  • 1.请定义一个交通工具(Vehicle)的类其中有: 属性: 速度(speed)、 体积(size)等,
  • 方法:移动(move())、设置速度(setSpeed(int speed))、加速 speedUp()、减速 speedDown()等。最后在测试类 Vehicle 中的 main()中实例化一个交通工具对象并通过方法给它初始化 speed,size 的值并且通过打印出来。另外调用加速、减速的方法对速度进行改变。1.请定义一个交通工具(Vehicle)的类其中有: 属性: 速度(speed)、
  • 体积(size)等,方法:移动(move())、设置速度(setSpeed(int speed))、加速 speedUp()
  • 、减速 speedDown()等。最后在测试类 Vehicle 中的 main()中实例化一个交通工具对象并通
  • 过方法给它初始化 speed,size 的值并且通过打印出来。另外调用加速、减速的方法对速度
  • 进行改变。
  • */

package com.mashibing.excerise;

public class VehicleReview {
    //定义属性
    private int size;
    private int speed;
    //设定move方法
    public void move(){
        System.out.println("正在行驶,速度为:"+speed);
    }

    //设置移动速度
    public void setSpeed(int speed){
        this.speed = speed;
        System.out.println("设置移动速度为:"+speed);
    }
    //设置加速器
    public void speedUp(){
        this.speed+=1;
        System.out.println("加速后的移动速度为:"+speed);
    }

    //设置减速器
    public void speedDown(){
        this.speed-=1;
        System.out.println("减速后的移动速度为: "+speed);
    }

    //设置体积
    public void setSize(int size){
        this.size = size;
        System.out.println("设置体积为:"+size);
    }

    public static void main(String[] args){
        VehicleReview ve = new VehicleReview();
        ve.setSize(10);
        ve.setSpeed(30);
        ve.move();
        ve.speedUp();
        ve.move();
        ve.speedDown();
        
    }
}

  1. 编写 Java 程序_用于显示人的姓名和年龄。定义一个人类Person。 该类中应该有两个私有属性: 姓名 (name) 和年龄 (age) 。定义构造方法用来初始化数据成员。再定义显示(display()) 方法将姓名和年龄打印出来。在 main 方法中创建人类的实例然后将信息显示。
package com.mashibing.excerise.PersonReview;



public class PersonReview {
    private String name;
    private int age;
    public PersonReview(String name ,int age){
        this.name = name;
        this.age = age;
    }
    public void display(){
        System.out.println("姓名:"+name);
        System.out.println("年龄:"+age);
    }

    public static void main(String[] args) {
        PersonReview personReview = new PersonReview("张三",20);
        personReview.display();
    }

}

3、 定义一个圆类——Circle,在类的内部提供一个属性:半径®,同时 提供 两个 方 法 : 计算 面积 ( getArea() ) 和 计算 周长(getPerimeter()) 。 通过两个方法计算圆的周长和面积并且对计算结果进行输出。最后定义一个测试类对 Circle 类进行使用。

package com.mashibing.excerise;
/*
* 3.定义一个圆类——Circle,在类的内部提供一个属性:半径(r),同时 提供 两个 方 法 :
*  计算 面积 ( getArea() )
*  和 计算 周长(getPerimeter()) 。
* 通过两个方法计算圆的周长和面积并且对计算结果进行输出。
* 最后定义一个测试类对 Circle 类进行使用。
* */


public class CircleReview {
    private int r;

    public CircleReview(){

    }
    public CircleReview(int r){
        this.r = r;
    }
    public void setR(int r){
        this.r = r;
    }

    public void getArea(){
        double area = Math.PI*r*r;
        System.out.println("圆的面积为:"+area);
    }
    public void getPerimeter(){
        double zc = Math.PI*r*2;
        System.out.println("周长为:"+zc);
    }
}
package com.mashibing.excerise;

public class TestCircleReview {
    public static void main(String[] args) {
        CircleReview circleReview = new CircleReview();
        circleReview.setR(3);
        circleReview.getArea();
        circleReview.getPerimeter();
    }
}

4、 构造方法与重载:定义一个网络用户类,要处理的信息有用户 ID、用户密码、 email 地址。在建立类的实例时把以上三个信息都作为构造函数的参数输入, 其中用户 ID 和用户密码时必须缺省时 email地址是用户 ID 加上字符串"@gameschool.com"。

package com.mashibing.excerise.PersonReview;

public class AddUserReview {
   private String id;
   private String passwd;
   private String email;
   public AddUserReview(String id,String passwd,String email){
       this.id = id;
       this.passwd = passwd;
       this.email = email;
   }

   public AddUserReview(String id,String passwd){
       this.id = id;
       this.passwd = passwd;
       this.email = id+"@"+passwd;
   }
   public void show(){
       System.out.println("用户id:"+id);
       System.out.println("密码不告诉你");
       System.out.println("邮件地址:"+email);
   }

    public static void main(String[] args) {
        AddUserReview addUserReview = new AddUserReview("1213","123124");
        addUserReview.show();
        AddUserReview addUserReview1 = new AddUserReview("1234","123445","123@321");
        addUserReview1.show();
   }
}

5、定义一个类 Calculaion, 其中包含四个方法: 加(add()) 、 减(sub()) 、乘(times()) 和除(div()) 。 创建一个具有 main()函数的类。 在 main()函数中创建一个 Calculation 的实例对象并对其中的方法进行调用。

package com.mashibing.excerise;

public class CalculationReivew {
    private double a;
    private double b;
    private double c;

    public CalculationReivew(){

    }
    public void setNum(double a,double b){
        this.a = a;
        this.b = b;
    }

    public void add(){
        this.c = a+b;
        System.out.println("add is: "+c);
    }

    public void  sub(){
        this.c = a-b;
        System.out.println("sub is: "+c);
    }

    public void times(){
        this.c = a*b;
        System.out.println("times is: "+c);
    }

    public void div(){
        this.c = a/b;
        System.out.println("div is :"+c);
    }

    public static void main(String[] args) {
        CalculationReivew cal = new CalculationReivew();
        cal.setNum(10,2);
        cal.add();
        cal.sub();
        cal.times();
        cal.div();
    }
}

定义一个类 Calculaion, 其中包含四个方法: 加(add()) 、 减(sub()) 、乘(times()) 和除(div()) 。 创建一个具有 main()函数的类。 在 main()函数中创建一个 Calculation 的实例对象并对其中的方法进行调用。

public class Calculaion {		
	private double a;
	private double b;
	public Calculaion(double a,double b){
		this.a=a;
		this.b=b;
	}
	public void add(){
		System.out.println("a加b :"+(a+b));
	}
	public void sub(){
		System.out.println("a减b :"+(a-b));
	}
	public void times(){
		System.out.println("a乘b :"+(a*b));
	}
	public void div(){
		System.out.println("a除以b :"+(a/b));
	}
	public static void main(String[] args) {
		Calculaion c = new Calculaion(7.0,3.0);
		c.add();
		c.sub();
		c.times();
		c.div();
	}
}
  1. 定义一个类 Draw , 在 类 中 提供 3 个 方法:输出直角三角形(drawTrian()) 、 输出矩形(drawRec()) 及平行四边形(drawPra()) 。通过方法可以输出由“*” 组成的一个图形。 同时在类中包含两个属性:星号的个数(count) 、行数(lines) 。最后在测试类中进行调用。
package com.mashibing.excerise.PersonReview;

public class DrawReview {
    private int line;
    private int starnum;

    public void setLineAndStarnum(int line,int starnum){
        this.line = line;
        this.starnum = starnum;
    }

    public void drawTrian(){
        for(int i=0;i<line;i++){
            for(int j=0;j<=i;j++){
                System.out.print("*");
            }
            System.out.println();
        }
        System.out.println();
    }

    public void drawRec(){
        for(int i=0;i<line;i++){
            for(int j=0;j<=starnum;j++){
                System.out.print("*");
            }
            System.out.println();
        }
        System.out.println();
    }

    public void drawPra(){
        for(int i=0;i<line;i++){
            for(int k=0;k<=i-1;k++){
                System.out.print(" ");
            }
            for(int j=0;j<=starnum;j++){
                System.out.print("*");
            }
            System.out.println();
        }
        System.out.println();
    }
}

package com.mashibing.excerise.PersonReview;

public class DrawReviewTest {
    public static void main(String[] args) {
        DrawReview dra = new DrawReview();
        dra.setLineAndStarnum(6,6);
        dra.drawRec();
        dra.drawPra();
        dra.drawTrian();
    }
}

7、 创建一个空调,并调用制冷、制热、通风功能。空调包含的属性有品牌、匹数、温度,功能有加热、制冷、通风等功能。

package com.mashibing.excerise.PersonReview;

public class AirConditionReview {
    //brand空调品牌
    private String  brand;
    //airNum空调匹数
    private int airNum;
    //temprature温度
    private int temprature;

    public void setAirCondition(String brand,int airNum,int temprature){
        this.brand = brand;
        this.airNum = airNum;
        this.temprature = temprature;
    }

    public void heating(){
        this.temprature+=1;
        System.out.println("加热后的温度为:"+temprature);
    }

    public void refrigeration(){
        this.temprature-=1;
        System.out.println("制冷后的温度为:"+temprature);
    }

    public void  ventilate(){
        System.out.println("空调正在通风");
    }

    public static void main(String[] args) {
        AirConditionReview newair = new AirConditionReview();
        newair.setAirCondition("格力",3,26);
        newair.heating();
        newair.refrigeration();
        newair.ventilate();
    }


}

public class AirConditioning {
	// 空调属性
	String name;
	String pinpai;
	String hp;// 匹数
	int tempeture;
	// 定义制冷行为
	void cool() {
		tempeture--;
	}
	// 定义加热行为
	void hot() {
		tempeture += 7;
	}
	//通风功能
	void ventilate(){
		System.out.println("空气通畅,温度不变");
	}
	// 主函数
	public static void main(String[] args) {
		AirConditioning kt = new AirConditioning();
		kt.hp = "2匹";
		kt.tempeture = 20;
		kt.pinpai = "格力";
		kt.cool();
		System.out.println("空调的温度是" + kt.tempeture);
		kt.hot();
		System.out.println("空调的温度是" + kt.tempeture);		
		kt.ventilate();
	}
}

8、 定义一个表示学生信息的类 Student,要求如下:

(1)类 Student 的属性如下:

sNO 表示学号; sName 表示姓名; sSex 表示性别; sAge 表示

年龄;sJava:表示 Java 课程成绩。

(2)类 Student 带参数的构造方法:

在构造方法中通过形参完成对成员变量的赋值操作。

(3)类 Student 的方法成员:

getNo():获得学号;

getName():获得姓名;

getSex():获得性别;

getAge()获得年龄;

getJava():获得 Java 课程成绩

(4) 根据类 Student 的定义,创建五个该类的对象,输出每个学生的信息,计算并输出这五个学生 Java 语言成绩的平均值,以及计算并输出他们 Java 语言成绩的最大值和最小值

package com.mashibing.excerise.PersonReview;

public class StudentReview {
    private int sNo;
    private String sName;
    private String sGener;
    private int sAge;
    //sJava。java课程的成绩
    private int sJava;

    public StudentReview(int sNo,String sName,String sGener,int sAge,int sJava){
        this.sNo = sNo;
        this.sName = sName;
        this.sGener = sGener;
        this.sAge = sAge;
        this.sJava = sJava;
    }

    public int getNo(){
        return sNo;
    }

    public String getName(){
        return sName;
    }

    public String getGender(){
        return sGener;
    }

    public int getAge(){
        return sAge;
    }

    public int getJava(){
        return this.sJava;
    }

    public void showInfo(){
        System.out.print("学号是:"+sNo+" ");
        System.out.print("姓名是:"+sName+" ");
        System.out.print("性别是:"+sGener+" ");
        System.out.print("年龄是:"+sAge+" ");
        System.out.println("java成绩是:"+sJava+" ");
    }

}
package com.mashibing.excerise.PersonReview;

public class StudentPerson {
    public static void main(String[] args) {
        StudentReview s1 = new StudentReview(1,"zhang1","M",20,98);
        StudentReview s2 = new StudentReview(2,"zhang2","F",21,96);
        StudentReview s3 = new StudentReview(3,"zhang3","F",22,92);
        StudentReview s4 = new StudentReview(4,"zhang4","F",23,91);
        StudentReview s5 = new StudentReview(5,"zhang5","M",25,90);
        s1.showInfo();
        s2.showInfo();
        s3.showInfo();
        s4.showInfo();
        s5.showInfo();


        double a1 = s1.getJava();
        double a2 = s2.getJava();
        double a3 = s3.getJava();
        double a4 = s4.getJava();
        double a5 = s5.getJava();
        double averageNum = ((a1+a2+a3+a4+a5)/5);
        System.out.println("java平均分为:"+ averageNum);

        double[] javaList = new double[5];
        javaList[0] = a1;
        javaList[1] = a2;
        javaList[2] = a3;
        javaList[3] = a4;
        javaList[4] = a5;

        double maxNum=javaList[0];
        for(int i=0;i<5;i++){
            if(javaList[i]>maxNum){
                maxNum = javaList[i];
            }
        }
        System.out.println("最大分数为:"+maxNum);

        double minNum=javaList[0];
        for(int i=0;i<5;i++){
            if(javaList[i]<minNum){
                minNum = javaList[i];
            }
        }
        System.out.println("最小分数为: "+minNum);
    }
}

9、1.使用面向对象的思想,编写自定义描述狗的信息。设定属性包括:品种,年龄,心情,名字;方法包括:叫,跑。
要求:
1)设置属性的私有访问权限,通过公有的get,set方法实现对属性的访问
2)限定心情只能有“心情好”和“心情不好”两种情况,如果无效输入进行提示,默认设置“心情好”。
3)设置构造函数实现对属性赋值
4)叫和跑的方法,需要根据心情好坏,描述不同的行为方式。
5)编写测试类,测试狗类的对象及相关方法(测试数据信息自定义)

public class DogReview {
    private String kind;
    private int age;
    private String mood;

    public String getKind(){
        return kind;
    }

    public void setKind(String kind){
        this.kind = kind;
    }

    public  int getAge(){
        return  age;
    }

    public void setAge(int age){
        this.age = age;
    }

    public String getMood(){
        return mood;
    }

    public void setMood(String mood){
        if(mood=="good" || mood == "bad") {
            this.mood = mood;
        }else{
            System.out.println("Only two mood: good or bad.default good");
            this.mood = "good";
        }
    }

    public void shout(){
        if(mood == "good"){
            System.out.println("Happy to shout");
        }else{
            System.out.println("bad to shout");
        }
    }

    public void run(){
        if(mood == "good"){
            System.out.println("happy to run");
        }else{
            System.out.println("bad to run");
        }
    }

    public DogReview(){

    }

    public DogReview(String kind,int age,String mood){
        this.kind = kind;
        this.age = age;
        if(mood=="good" || mood == "bad") {
            this.mood = mood;
        }else{
            System.out.println("Only two mood: good or bad.default good");
            this.mood = "good";
        }
    }



}
public class DogReviewTest {
    public static void main(String[] args) {
        DogReview newdog = new DogReview();
        newdog.setKind("二哈");
        newdog.setAge(2);
        newdog.setMood("good");
        System.out.println(newdog.getAge());
        System.out.println(newdog.getKind());
        System.out.println(newdog.getMood());
        newdog.shout();
        newdog.run();

        DogReview newdog2 = new DogReview("边牧",1,"dd");
        System.out.println(newdog2.getAge());
        System.out.println(newdog2.getKind());
        System.out.println(newdog2.getMood());
        newdog2.shout();
        newdog2.run();
    }
}

10、\1. 以面向对象的思想,编写自定义类描述IT从业者。设定属性包括:姓名,年龄,技术方向,工作年限, 工作单位和职务;方法包括:工作

要求:

  1. 设置属性的私有访问权限,通过公有的get,set方法实现对属性的访问

  2. 限定IT从业人员必须年满15岁,无效信息需提示,并设置默认年龄为15。

  3. 限定“技术方向”是只读属性

  4. 工作方法通过输入参数,接收工作单位和职务,输出个人工作信息

  5. 编写测试类,测试IT从业者类的对象及相关方法(测试数据信息自定义)

public class ItWorkReview {
    private String name;
    private int age;
    //tecDirection :技术方向
    private String techDirection;
    //workingSeniority;工作年龄
    private int workingSeniority;
    //jobTitle工作职务
    private String jobTitle;
    //jobCompany 工作公司
    private String jobCompany;

    public ItWorkReview(){

    }
    public ItWorkReview(String name,int age,String techDirection,int workingSeniority,String jobTitle,String jobCompany){
        this.name = name;
        if(age<15){
            System.out.println("年龄必须满15岁,已设定默认年龄15");
            this.age = 15;
        }else{
            this.age = age;
        }
        this.techDirection=techDirection;
        this.workingSeniority=workingSeniority;
        this.jobTitle=jobTitle;
        this.jobCompany=jobCompany;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age<15){
            System.out.println("年龄必须满15岁,已设定默认年龄15");
            this.age = 15;
        }else{
            this.age = age;
        }

    }

    public String getTechDirection() {
        return techDirection;
    }


    public int getWorkingSeniority() {
        return workingSeniority;
    }

    public void setWorkingSeniority(int workingSeniority) {
        this.workingSeniority = workingSeniority;
    }

    public String getJobTitle() {
        return jobTitle;
    }

    public void setJobTitle(String jobTitle) {
        this.jobTitle = jobTitle;
    }

    public String getJobCompany() {
        return jobCompany;
    }

    public void setJobCompany(String jobCompany) {
        this.jobCompany = jobCompany;
    }

    public  void work(String jobCompany,String jobTitle){
        System.out.println("姓名: "+name);
        System.out.println("年龄:"+age);
        System.out.println("技术方向: "+techDirection);
        System.out.println("工作年限:"+workingSeniority);
        System.out.println("就职公司:"+jobCompany);
        System.out.println("职务是:"+jobTitle);
        System.out.println("===============================================");
    }
}
public class itWorkReviewTest {
    public static void main(String[] args) {
       ItWorkReview newwork = new ItWorkReview("马龙",35,"数据库维护",10,"数据库工程师","腾讯");
       newwork.work("腾讯","数据库工程师");
        ItWorkReview newwork2 = new ItWorkReview("马2龙",12,"数据库维护",10,"数据库工程师","腾讯");
        newwork2.work("腾讯","数据库工程师");
    }

}

第10题写法2,参考

public class ITWork {
	private String name; //姓名
	private int age;//年龄
	private String tend;//技术方向
	private int workAge;//工作年限
	public ITWork() {
	}	
	public ITWork(String name, int age, String tend, int workAge) {
		super();
		this.name = name;
		//this.age = age;
		this.setAge(age);
		this.tend = tend;
		this.workAge = workAge;	
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		if(age < 15){
			this.setAge(15);
			System.out.println("年龄信息无效!已修改默认年龄为15");
		}else{
			this.age = age;
		}
	}
	public String getTend() {
		return tend;
	}
	public void setTend(String tend) {
		this.tend = tend;
	}
	public int getWorkAge() {
		return workAge;
	}
	public void setWorkAge(int workAge) {
		this.workAge = workAge;
	}	
	public void work(String company,String position){
		System.out.println("姓名:"+name);
		System.out.println("年龄:"+age);
			System.out.println("技术方向:"+tend);
		System.out.println("工作年限:"+workAge);
		System.out.println("目前就职于:"+company);
		System.out.println("职务是:"+position);
	}	
}

public class Test {
	public static void main(String[] args) {		
		ITWork it = new ITWork("马未龙", 35, "数据库维护", 10);
		it.work("腾讯实业","数据库维护工程师");
		System.out.println("======================");
		ITWork it2 = new ITWork("张凯", 10, "Java开发", 15);
		it2.work("鼎盛科技","Java开发工程师");		
	}	
}

11、 以面向对象的思想,编写自定义类描述图书信息。设定属性包括:书名,作者,出版社名,价格;方法包括:信息介绍

要求:

  1. 设置属性的私有访问权限,通过公有的get,set方法实现对属性的访问

  2. 限定介格必须大于10,如果无效进行提示

  3. 限定作者,书名为只读属性

  4. 设计构造方法实现对属性赋值

  5. 信息介绍方法描述图书所有信息

  6. 编写测试类,测试图书类的对象及相关方法(测试数据信息自定)

import java.sql.SQLSyntaxErrorException;

public class BookInfo {
    private String bookName;
    private String bookAuth;
    //bookPress出版社
    private String bookPress;
    private double bookPrice;

    public BookInfo(){

    }

    public BookInfo(String bookName,String bookAuth,String bookPress,double bookPrice){
        this.bookName=bookName;
        this.bookAuth=bookAuth;
        this.bookPress=bookPress;
        if(bookPrice<10){
            System.out.println("价格必须大于10,正在退出程序");
            System.exit(10);
        }else{
            this.bookPrice=bookPrice;
        }
    }

    public String getBookName() {
        return bookName;
    }



    public String getBookAuth() {
        return bookAuth;
    }

    public void setBookAuth(String bookAuth) {
        this.bookAuth = bookAuth;
    }

    public String getBookPress() {
        return bookPress;
    }

    public void setBookPress(String bookPress) {
        this.bookPress = bookPress;
    }

    public double getBookPrice() {
        return bookPrice;
    }

    public void setBookPrice(int bookPrice) {
        this.bookPrice = bookPrice;
    }

    public void bookInfo(){
        System.out.println("书名:"+bookName+"\t作者:"+bookAuth+"\t出版社: "+bookPress+"\t价格"+bookPrice);
        System.out.println("===========================================================");
    }
}
public class BookInfoTest {
    public static void main(String[] args) {
        BookInfo newbook =  new BookInfo("鹿鼎记","金庸","人民文学出版社",120);
        System.out.println(newbook.getBookAuth());
        System.out.println(newbook.getBookName());
        System.out.println(newbook.getBookPress());
        System.out.println(newbook.getBookPrice());
        newbook.bookInfo();

        BookInfo newbook2 =  new BookInfo("绝代双骄","古龙","中国长安出版社",55.5);
        System.out.println(newbook2.getBookAuth());
        System.out.println(newbook2.getBookName());
        System.out.println(newbook2.getBookPress());
        System.out.println(newbook2.getBookPrice());
        newbook2.bookInfo();

    }
}

写法2

public class Book {
	private String name;
	private String author;
	private String publisher;
	public  double price;	
	public Book() {
		super();
	}	
	public Book(String name, String author, String publisher, double price) {
		super();
		this.name = name;
		this.author = author;
		this.publisher = publisher;
		//this.price = price;
		this.setPrice(price);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getPublisher() {
		return publisher;
	}
	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		if(price<=10){
			System.out.println("价格必须大于10");
			this.price = price;
		}else{
			this.price = price;
		}		
	}
	/**
	 * 显示图书信息
	 */
	public void showInfo(){
		System.out.println("书名:"+this.name);
		System.out.println("作者:"+this.author);
		System.out.println("出版社:"+this.publisher);
		System.out.println("价格:"+this.price);		
	}	
}

public class TestBook {
	public static void main(String[] args) {
		Book book1 = new Book();
		book1.setName("鹿鼎记");
		book1.setAuthor("金庸");
		book1.setPublisher("人民文学出版社");
		book1.setPrice(120);
		book1.showInfo();		
		System.out.println("=============================");		
		Book book2 = new Book("绝代双骄", "古龙", "中国长安出版社", 55.5);
		book2.showInfo();
	}
}

12、. 某公司要开发名为”我爱购物狂”的购物网站,请使用面向对象的思想设计描述商品信息

要求:

  1. 分析商品类别和商品详细信息属性和方法,设计商品类别类和商品详细信息类

  2. 在商品详细信息类中通过属性描述该商品所属类别

  3. 设置属性的私有访问权限,通过公有的get,set方法实现对属性的访问

  4. 编写测试类,测试商品类别类和商品详细信息类的对象及相关方法(测试数据信息自定)

  5. 创建包info—存放商品类别类和商品详细信息类,创建包test—存放测试类

    参考分析思路:

商品类别类:

属性:类别编号,类别名称

商品详细信息类:

属性:商品编号,商品名称,所属类别,商品数量(大于0),商品价格(大于0),

方法:盘点的方法,描述商品信息。内容包括商品名称,商品数量,商品价格,现在商品总价以及所属类别信息

别忘记了,使用其他自定义类需要import,idea会自动帮你完成此工作,但不代表不需要这项操作。

package info;

public class ProductKind {
    private int kindNum;
    private String kindName;

    public void setkindNum(int kindNum){
        this.kindNum=kindNum;
    }
    public int getKindNum(){
        return kindNum;
    }

    public void setKindName(String kindName){
        this.kindName=kindName;
    }

    public String getKindName(){
        return kindName;
    }

    public ProductKind(){

    }
    public ProductKind(int kindNum,String kindName){
        this.kindNum=kindNum;
        this.kindName=kindName;
    }
}
package info;

public class ProductInfo {
    //商品编号
    private int productNum;
    //商品名称
    private String productName;
    //商品数量
    private int productSum;
    //商品价格
    private double productPrice;

    //商品的类别
    private ProductKind productKind;

    public int getProductNum() {
        return productNum;
    }

    public void setProductNum(int productNum) {
        this.productNum = productNum;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public int getProductSum() {
        return productSum;
    }

    public void setProductSum(int productSum) {
        if(productSum>0){
            this.productSum=productSum;
        }else{
            System.out.println("商品数量必须大于0,正在退出程序");
            System.exit(10);
        }
    }

    public double getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(double productPrice) {
        this.productPrice = productPrice;
    }

    public ProductKind getProductKind(){
        return productKind;
    }

    public void setProductKind(ProductKind productKind){
        this.productKind=productKind;
    }

    public void productInfoSum(){
            System.out.println("商品编号:"+productNum);
            System.out.println("商品名称:"+productName);
            System.out.println("商品数量:"+productSum);
            System.out.println("商品总价:"+(productPrice*productSum));
            System.out.println("商品类别:"+productKind.getKindName());
    }

    public ProductInfo(){

    }
    public ProductInfo(int productNum,String productName,int productSum,double productPrice){
        this.productNum=productNum;
        this.productName=productName;
        if(productSum>0){
            this.productSum=productSum;
        }else{
            System.out.println("商品数量必须大于0,正在退出程序");
            System.exit(10);
        }
        this.productPrice=productPrice;
    }
    
}
package test;

import info.ProductInfo;
import info.ProductKind;

public class ProductTest {
    public static void main(String[] args) {

        ProductInfo newproduct = new ProductInfo();
        //设置商品编号
        newproduct.setProductNum(1);
        //设置商品名称
        newproduct.setProductName("王老吉");
        //设置商品数量
        newproduct.setProductSum(100);
        //设置商品价格
        newproduct.setProductPrice(2.5);
        //设置商品类别,因为商品类别的类型沿用了商品类别的类,有两个属性,需要新建对象
        ProductKind newproductKind = new ProductKind(1,"饮料");
        newproduct.setProductKind(newproductKind);
        newproduct.productInfoSum();
    }
}

写法2

package info;
public class ProductCategory {
	private String cid;
	private String name;
	public ProductCategory() {
		super();
	}
	public ProductCategory(String cid, String name) {
		super();
		this.cid = cid;
		this.name = name;
	}
	public String getCid() {
		return cid;
	}
	public void setCid(String cid) {
		this.cid = cid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

package info;
public class Product {
	private String pid;
	private String name;
	private int amount;
	private double price;
	private ProductCategory category;	
	public Product() {
		super();
	}
	public Product(String pid, String name, int amount, double price) {
		super();
		this.pid = pid;
		this.name = name;
		this.amount = amount;
		this.price = price;
	}
	public Product(String pid, String name, int amount, double price,
			ProductCategory category) {
		super();
		this.pid = pid;
		this.name = name;
		this.setAmount(amount);
		this.price = price;
		this.category = category;
	}
	public String getPid() {
		return pid;
	}
	public void setPid(String pid) {
		this.pid = pid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAmount() {
		return amount;
	}
	public void setAmount(int amount) {
		if(amount<0){
			System.out.println("库存数量异常,请联系管理员");
			this.amount = 0;
		}else{
			this.amount = amount;
		}		
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public ProductCategory getCategory() {
		return category;
	}
	public void setCategory(ProductCategory category) {
		this.category = category;
	}
	public void check(){
		System.out.println("商品名称:"+this.name);
		System.out.println("所属类别:"+this.category.getName());
		System.out.println("库存数量:"+this.price);
		System.out.println("商品售价:"+this.amount);
		System.out.println("商品总价:"+this.price*this.amount);

	}	
}

public class TestProduct {
	public static void main(String[] args) {
		//指定商品信息并盘点
		ProductCategory category1 = new ProductCategory("11", "洗发水");
		Product p1 = new Product("111", "潘婷洗发水400ml",
				16, 40.5, category1);
		p1.check();
		
		System.out.println("==============");
		//指定商品信息并盘点
		Product p2 = new Product();
		p2.setPid("222");
		p2.setName("蜂花洗发水250ml");
		p2.setPrice(11.5);
		p2.setAmount(-5);
		p2.setCategory(category1);
		p2.check();
	}
}

13、 编写应用程序,创建类的对象,分别设置圆的半径、圆柱体的高,计算并分别显示圆半径、圆面积、圆周长,圆柱体的体积。(7分)

****提示:****(1)编写一个圆类Circle,该类拥有:

  1. 一个成员变量,radius(私有,浮点型);//存放圆的半径;

  2. 两个构造方法

Circle() //将半径设为0

Circle(double r ) //创建Circle对象时将半径初始化为r

  1. 三个成员方法

double getArea() //获取圆的面积

double getPerimeter() //获取圆的周长

void show() //将圆的关径、周长、面积输出到屏幕

​ (2) 编写一个圆柱体类Cylinder,它继承于上面的Circle类。还拥有:

  1. 一个成员变量,double hight (私有,浮点型); //圆柱体的高;

  2. 构造方法

//创建Cylinder对象时将半径初始化为r,高度初始化为h

Cylinder(double r,double h)

  1. 成员方法

double getVolume() //获取圆柱体的体积

void showVolume() //将圆柱体的体积输出到屏幕

public class CircleReview {
    private double radius;

    public CircleReview(){
        radius = 0;
    }
    public CircleReview(double r){
        radius = r;
    }
    public double getArea(){
        double areas =  Math.PI*radius*radius;
        return  areas;
    }
    public double getPerimeter(){
        double perimeters=2*Math.PI*radius;
        return perimeters;
    }
    public void show(){
        System.out.println("圆的半径:"+radius);
        System.out.println("圆的面积:"+getArea());
        System.out.println("圆的周长:"+getPerimeter());
    }
}
public class CylinderReview extends CircleReview {
    private  double hight;
    public  CylinderReview(){

    }

    public CylinderReview(double r,double h){
       super(r);
       this.hight=h;
    }

    public double getVolume(){
        double volumes = super.getArea()*hight;
        return volumes;
    }
    public void showVolume(){
        System.out.println("圆柱体面积是:"+this.getVolume());
    }

    public static void main(String[] args) {
        CylinderReview newCylinder = new CylinderReview(2,5);
        newCylinder.showVolume();
        newCylinder.show();

    }
}

写法2

public class Circle {
	private double radius;
	public Circle(){ //将半径设为0
		this.radius = 0;
	}
	public Circle(double  r ){ //创建Circle对象时将半径初始化为r
		this.radius = r;
	}
	public double getArea(){ //获取圆的面积
		return Math.PI * this.radius * this.radius ;
	}
	public double getPerimeter(){//获取圆的周长
		return Math.PI * this.radius * 2 ;
	}
	/** 将圆的面积 ,周长 */
	public void show(){
		System.out.println("圆的半径:"+this.radius);
		System.out.println("圆的面积:"+this.getArea());
		System.out.println("圆的周长:"+this.getPerimeter());
	}
}

public class Cylinder extends Circle {
	private double hight;
	/** 构造时设置圆的高,并调用父类的构造设置半径 */
	public Cylinder(double r,double h){
		super(r);
		this.hight = h;
	}
	/** 获得体积 */
	public double getVolume(){
		double area = super.getArea();
		return area * hight;
	}
	/**打印半径,周长,面积,体积*/
	public void showVolume(){
		super.show();
		System.out.println("圆的体积是:"+this.getVolume());
	}
}
public class Test {
	public static void main(String[] args) {
		Cylinder c = new Cylinder(10,10);
		c.showVolume();
	}
}

14、请使用面向对象的思想,设计自定义类,描述出租车和家用轿车的信息。

设定

  1. 出租车类:

属性包括:车型,车牌,所属出租公司;方法包括:启动,停止

  1. 家用轿车类:

属性包括:车型,车牌,车主姓名;方法包括:启动,停止

要求

  1. 分析出租车和家用轿车的公共成员,提取出父类—汽车类

  2. 利用继承机制,实现出租车类和家用轿车类

  3. 编写测试类,分别测试汽车类,出租车类和家用轿车类对象的相关方法

定义名为car的包存放汽车类,出租车类,家用轿车类和测试类

package car;

public class CarReview {
    private String carKind;
    private String carBand;

    public void setCarKind(String carKind){
        this.carKind=carKind;
    }

    public String getCarKind(){
        return  carKind;
    }

    public void setCarBand(String carBand){
        this.carBand = carBand;
    }

    public String getCarBand(){
        return carBand;
    }

    public void carmove(){
        System.out.println("我是车,我启动");
    }

    public void carstop(){
        System.out.println("我是车,我停止");
    }

}
package car;

public class taxiReview extends CarReview {
    private String taxiCompany;

    public void setTaxiCompany(String taxiCompany){
        this.taxiCompany=taxiCompany;
    }

    public String getTaxiCompany(){
        return taxiCompany;
    }

    public void start(){
        System.out.println("乘客您好");
        System.out.println("我是景顺出租车公司的,我的车牌是京B123,您要去哪里");
    }
    public void stop(){
        System.out.println("目的地已经到了,请您付费下车,欢迎再次乘坐");
    }

}

package car;

public class familyCarReview extends CarReview {
    private String carMaster;
    public void setCarMaster(String carMaster){
        this.carMaster=carMaster;
    }
    public String getCarMaster(){
        return carMaster;
    }

    public void start(){
        System.out.println("我是"+carMaster+",我的汽车我做主");
    }
    public void stop(){
        System.out.println("目的地到了,我们去玩吧");
    }
}
package car;

public class CarTest {
    public static void main(String[] args) {
        CarReview newcar = new CarReview();
        newcar.carmove();
        newcar.carstop();
        taxiReview newtaxi = new taxiReview();
        newtaxi.start();
        newtaxi.stop();
        familyCarReview newfamily = new familyCarReview();
        newfamily.setCarMaster("武松");
        newfamily.start();
        newfamily.stop();
    }
}

15、\1. 某公司要开发新游戏,请用面向对象的思想,设计游戏中的蛇怪和蜈蚣精

设定

  1. 蛇怪类:

属性包括:怪物名字,生命值,攻击力

方法包括:攻击,移动(曲线移动),补血(当生命值<10时,可以补加20生命值)

  1. 蜈蚣精类:

属性包括:怪物名字,生命值,攻击力

方法包括:攻击,移动(飞行移动)

要求

  1. 分析蛇怪和蜈蚣精的公共成员,提取出父类—怪物类

  2. 利用继承机制,实现蛇怪类和蜈蚣精类

  3. 攻击方法,描述攻击状态。内容包括怪物名字,生命值,攻击力

  4. 编写测试类,分别测试蛇怪和蜈蚣精的对象及相关方法

  5. 定义名为mon的包存怪物类,蛇怪类,蜈蚣精类和测试类

package mon;
/*
*这里应该把"怪物xx展开攻击");
		当前生命值:xx
		攻击力是:xx
		直接写到父类Monster中去,在父类中添加一个输出怪物基础信息的方法
		没有添加血量低于10,增加血量的逻辑。
		详情请看写法2,补充即可。
*/
public class Monster {
    //怪物名字
    private String monsterName;
    //怪物生命值
    private int HP;
    //怪物攻击力
    private int CE;

    public void setMonsterName(String monsterName){
        this.monsterName=monsterName;
    }

    public String getMonsterName(){
        return monsterName;
    }

    public void setHP(int HP){
        this.HP=HP;
    }
    public int getHP(){
        return HP;
    }
    public void setCE(int CE){
        this.CE=CE;
    }
    public int getCE(){
        return CE;
    }


}
package mon;

public class SnakeMonster extends Monster {
    public void snakeaddHP(){
        int oldHP = super.getHP();
        int newHP = oldHP+20;
        super.setHP(newHP);
        System.out.println("施展大蛇补血术.....当前生命值是:"+super.getHP());
    }
    public void snakeAttack(){
        System.out.println("怪物蛇妖正在展开攻击");
    }
    public void snakeMove(){
        System.out.println("我是蛇怪,我走S型路线");
    }
}

package mon;

public class CentipedeMonster extends Monster{
     public void centipedeAttack(){
         System.out.println("怪物蜈蚣正在展开攻击");
     }
     public void centipedeMove(){
         System.out.println("我是蜈蚣精,御风飞行");
     }

}
package mon;

public class MonTest {
    public static void main(String[] args) {
        SnakeMonster newsnake = new SnakeMonster();
        newsnake.setMonsterName("美杜莎");
        newsnake.setHP(5);
        newsnake.setCE(20);
        newsnake.snakeAttack();
        System.out.println("当前生命值是:"+newsnake.getHP());
        System.out.println("攻击力是:"+newsnake.getCE());
        newsnake.snakeaddHP();
        newsnake.snakeMove();
        System.out.println("=================");
        CentipedeMonster newcentipede = new CentipedeMonster();
        newcentipede.setMonsterName("大蜈蚣");
        newcentipede.setHP(200);
        newcentipede.setCE(50);
        newcentipede.centipedeAttack();
        System.out.println("当前生命值是:"+newcentipede.getHP());
        System.out.println("攻击力是:"+newcentipede.getCE());
        newcentipede.centipedeMove();
    }

}

写法2

public class Monster {
	private String name;//怪物名
	private int hp;//血量
	private int aggressivity;//攻击力
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHp() {
		return hp;
	}
	public void setHp(int hp) {
		this.hp = hp;
	}
	public int getAggressivity() {
		return aggressivity;
	}
	public void setAggressivity(int aggressivity) {
		this.aggressivity = aggressivity;
	}
	/** 攻击 */
	public void attack() {
		System.out.println("怪物"+this.getName()+"展开攻击");
		System.out.println("当前生命值:"+this.getHp());
		System.out.println("攻击力是:"+this.getAggressivity());
	}
	/** 移动 */
	public void move() {
	}
}

/** 怪蛇类 */
public class Snake extends Monster {
	/** 加血 */
	public void addHp(){
		this.setHp(this.getHp()+20);
		System.out.println("实施大蛇补血术......,当前的生命值是"+this.getHp());
	}

	/** 重写父类的移动方法*/
	public void move() {
		System.out.println("我是蛇,我走S线路");
	}
}

/** 蜈蚣类 */
public class Centipede extends Monster {
	/** 重写父类的移动方法*/
	public void move() {
		System.out.println("我是蜈蚣精,我御风飞行");
	}
}

public class Test {
	public static void main(String[] args) {
		Snake sn = new Snake();//生产一个蛇精
		sn.setName("怪蛇甲");
		sn.setHp(5);
		sn.setAggressivity(20);
		sn.attack();//调用攻击方法
		if(sn.getHp()<10){//当生命少于10时,加20血
			sn.addHp();
		}
		sn.move();//蛇移动
		System.out.println("======================");
		
		Centipede ct = new Centipede();//new一个蜈蚣
		ct.setName("蜈蚣精乙");
		ct.setHp(60);
		ct.setAggressivity(15);
		ct.attack();//蜈蚣攻击
		ct.move();
	}
}

16、 请用面向对象的思想,设计自定义类描述演员和运动员的信息

设定

  1. 演员类:

属性包括:姓名,年龄,性别,毕业院校,代表作

方法包括:自我介绍

  1. 运动员类:

属性包括:姓名,年龄,性别,运动项目,历史最好成绩

方法包括:自我介始

要求

  1. 分析演员和运动员的公共成员,提取出父类—人类

  2. 利用继承机制,实现演员类和运动员类

  3. 编写测试类,分别测试人类,演员类和运动员类对象及相关方法

  4. 定义名为act的包存人类,演员类,运动员类和测试类

package act;
/*
如果在每个类中,包括子类都写一个自我介绍方法,能减少实现类过程中输出的代码
*/
public class HumanReveiw {
    private String name;
    private int age;
    private String gender;

    public void setName(String name){
        this.name=name;
    }

    public String getName(){
        return name;
    }

    public void  setAge(int age){
        this.age = age;
    }

    public int getAge(){
        return age;
    }

    public void setGender(String gender){
        this.gender=gender;
    }

    public String getGender(){
        return gender;
    }

    public void selfIntroduce(){
        System.out.println("大家好!我是"+name);
        System.out.println("我今年"+age);
    }
    public void laobaixing(){
        System.out.println("我就是一个普通的老百姓");
        System.out.println("====================");
    }

}
package act;

public class AtheleteReview extends HumanReveiw {
    //定义运动项目
    private String sportProject;
    //定义历史最好成绩
    private String historyBestGrade;

    public AtheleteReview(){

    }

    public AtheleteReview(String sportProject,String historyBestGrade){
        this.sportProject=sportProject;
        this.historyBestGrade=historyBestGrade;
    }

    public void setSportProject(String sportProject){
        this.sportProject=sportProject;
    }

    public String getSportProject(){
        System.out.println("我擅长的运动项目是:"+sportProject);
        return sportProject;
    }

    public void setHistoryBestGrade(String historyBestGrade){
        System.out.println("历史最好成绩是:"+historyBestGrade);
        this.historyBestGrade=historyBestGrade;

    }

    public String getHistoryBestGrade(){
        System.out.println("历史最好成绩是:"+historyBestGrade);
        return historyBestGrade;
    }

}
package act;

public class actReview extends HumanReveiw {
    //定义毕业院校
    private String graduateInstitutions;
    //定义代表作
    private String represetnWork;

    public actReview(){

    }

    public actReview(String graduateInstitutions,String represetnWork){
        this.graduateInstitutions=graduateInstitutions;
        this.represetnWork=represetnWork;
    }

    public String getGraduateInstitutions() {
        System.out.println("我毕业于:"+graduateInstitutions);
        return graduateInstitutions;
    }

    public void setGraduateInstitutions(String graduateInstitutions) {
        this.graduateInstitutions = graduateInstitutions;
    }

    public String getRepresetnWork() {
        System.out.println("代表作有: "+represetnWork);
        return represetnWork;
    }

    public void setRepresetnWork(String represetnWork) {
        this.represetnWork = represetnWork;
    }
}
package act;

public class HumanTestReview extends HumanReveiw {
    public static void main(String[] args) {
        AtheleteReview newAth = new AtheleteReview("200米短跑","22秒30");
        newAth.laobaixing();
        newAth.setName("刘小翔");
        newAth.setAge(23);
        newAth.selfIntroduce();
        newAth.getSportProject();
        newAth.getHistoryBestGrade();
        System.out.println("====================");

        actReview newact = new actReview("北京电影学院","《寄望天国的家书》");
        newact.setName("章依");
        newact.setAge(27);
        newact.selfIntroduce();
        newact.getGraduateInstitutions();
        newact.getRepresetnWork();
    }
}
 

写法2

public class Person {
	//姓名,年龄,性别
	String name;
	int age;
	String sex;
	public Person(){}
	public Person(String name, int age, String sex) {
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	//介绍
	public void introduction(){
		System.out.println("大家好,我是一个老百姓");
	}
}

public class Sportsman extends Person{//运动员类
	private String item;
	private String bestResult;
	public Sportsman(){}
	public Sportsman(String name,int age,String sex,String item,String best) {
		super(name,age,sex);
		this.item = item;
		this.bestResult = best;
	}
	public void introduction() {
		System.out.println("大家好,我是"+this.name);
		System.out.println("今年"+this.age);
		System.out.println("我擅长的项目是:"+this.item);
		System.out.println("历史最好成绩是:"+this.bestResult);
	}
}

public class Performer extends Person {//演员类
	private String school;//学校
	private String production;//作品
	public Performer(){}
	public Performer(String name,int age,String sex,String school,String pro) {
		super(name,age,sex);
		this.school = school;
		this.production = pro;
	}
	public void introduction() {
		System.out.println("大家好,我是"+this.name);
		System.out.println("今年"+this.age);
		System.out.println("我毕业于:"+this.school);
		System.out.println("代表作有:"+this.production);
	}
}

public class Test {
	public static void main(String[] args) {
		Person p = new Person();
		p.introduction();
		System.out.println("==============");
		Sportsman sm = new Sportsman("刘小翔",23,"男",
"200米短跑","22秒30");
		sm.introduction();
		System.out.println("==============");
		Performer pf = new Performer("章依",27,"女","北京电影学院",
"《寄往天国的家书》");
		pf.introduction();
	}
}

七、异常处理

1、概念以及常见的异常类型

在程序运行过程中出现的不正常情况叫做异常

注意:

  1. 在相同的代码在运行的时候,根据输入的参数或者操作的不通,有可能会发生异常,有可能不会发生异常、应该在写代码的时候极可能保证代码的正确性,不要到处都是bug。

  2. 如果要解决写代码过程中出现的异常,需要添加非常复杂的代码逻辑来进行判断,会使得代码变得非常臃肿,不利于维护,可读性比较差,因为,推荐大家使用异常机制来使用这种情况。

  3. 程序在运行过程中如果出现了问题,会导致后面的代码无法正常运行,而是用异常机制之后,可以对异常情况进行处理,同时后续的代码会继续执行,不会中断整个程序。

  4. 在异常的处理过程中,不要只简单的输出错误,要尽可能的详细的将异常信息进行输出。

    e.printStackTrack():打印异常的堆栈信息。可以从异常信息的最后一行开始追踪,寻找自己编写的java类。

异常类型 说明
Exception 异常层次结构的父类
ArithemeticException 算术错误情况,如以零作除数
ArrayIndexOutOfBoundsExceptions 数组下标越界
NullPointerException 尝试访问null对象成员
ClassNotFoundException 不能加载所需的类
IllegalArgumentException 方法接收到非法参数
ClassCastException 对象强制类型转换出错
NumberFormatException 数字格式转换异常

5个异常分类:

  1. Exception和Error类的父类
  2. 仅靠程序本身无法恢复的严重错误
  3. 由Java应用程序抛出和处理的非严重错误
  4. 运行时异常,不要求程序必须做出处理
  5. Checked异常,程序必须处理该异常

throw:是直接抛出异常信息

throws是声明异常

  • 在异常的使用可以使用try…catch…finally的方式对异常进行处理,除此之外,可以异常向外抛出。
  • 在方法调用过程中,可以存在N多个方法间的调用 ,此时假如每个方法中都包含了异常情况。那么就需要将每个方法中都进行try…catch,另一个比较简单的方式,就是在方法的最外层调用处理,使用throws的方法,对所有执行过程中的所有方法出现的异常进行统一集中处理。
  • 如何判断是使用throws还是try…catch:最稳妥的方法是每个方法中都进行异常处理,偷懒的方式是判断在整个调用的过程中,外层的调用方法是否对有异常的处理,如果有,直接使用throws,如果没有,就使用try…catch.

5个常见得运行时异常:

异常分为checked异常和运行时异常

  • Checked异常必须捕获或者声明抛出
  • 运行时异常不要求必须捕获或者声明抛出。

2、try-catch捕获异常

try-catch捕获异常的方式如下:

try{代码逻辑}catch(Exception e){异常处理逻辑}
try{代码逻辑}catch(Exception e){异常处理逻辑}catch(Exception e){异常处理逻辑}
可以将更具体的处理不同类型的异常

当使用多重catch的时候一定要注意相关异常的顺序,将子类放在最前面的父类放在最后面的catch:执行过程中可能出现的情况:

  1. 正常执行,只执行try中的代码

  2. 遇到异常情况,会处理try中异常代码之前的逻辑,后面的逻辑不会执行,最后会执行中的代码

  3. 使用多重的时候,会遇到异常子类不匹配的时候,此时依然会报错,建议在catch的最后将所有的异常的父类写上

    public class TestException {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            try {
                System.out.print("请输入被除数:");
                int num1 = in.nextInt();
                System.out.print("请输入除数:");
                int num2 = in.nextInt();
                System.out.println(String.format("%d / %d = %d",
                        num1, num2, num1 / num2));
    //        }catch (Exception e){
    ////            System.out.println("出现异常");
    //            e.printStackTrace();
    //            System.out.println(e.getMessage());
    //        }
            }catch (ArithmeticException e){
                System.out.println("数学异常");
                e.printStackTrace();
            }catch (InputMismatchException e){
                System.out.println("输入的参数值类型不匹配");
                e.printStackTrace();
            }catch (NullPointerException e){
                System.out.println("空指针异常");
                e.printStackTrace();
            }
                System.out.println("感谢使用本程序!");
            }
        }
    

需求说明

编写数据转换类,定义数据转换方法,具有String类型的参数,

实现将参数转换为整型数据后输出,要求使用多重catch语句处

理异常

编写测试类,调用数据类型转换方法,分别传递参数“a”、20

分析

使用NumberFormatException、Exception异常类型

package exceptionReview;

public class TryCatchReveiw {
    public TryCatchReveiw(){

    }
    public void transfer(String inputstr){
        try{
           int newinputstr = Integer.valueOf(inputstr);
           System.out.println("您输入的数字成功转换,转为:"+newinputstr);
        }catch (NumberFormatException e){
            //NumberFormatException 转换过程中,因为精度问题造成的异常可以用它来捕获
            System.out.println("数字格式转换失败,需要输入数精度范围内的数字字符串");
            e.printStackTrace();
        }catch (Exception e){
            System.out.println("转换失败,需要您输入数字字符串");
            e.printStackTrace();
        }

    }
    
}
package exceptionReview;

public class TryCatchTestReview {
    public static void main(String[] args) {
        TryCatchReveiw newtry= new TryCatchReveiw();
        newtry.transfer("20a");
    }
}

3、try-catch-finally捕获异常

try-catch-finally中存在return,需要等finally执行完再执行return语句

finally代码块不执行: 代码块里执行exit相关语句

在程序运行过程中,如果处理异常包含finnaly的处理,那么无论代码是否正常运行,那么finally中的代码总会执行。
finally包含哪些处理逻辑:
1、IO流的关闭操作一般设置在finally中。
2、数据库的连接关闭操作设置在finally中。

package com.mashibing;

public class TryTest {
    public static void main(String[] args){
        System.out.println(test().num);
    }

    private static Num test(){
        Num number = new Num();
        try{
            System.out.println("try");
            return number;
        }catch(Exception e){
            System.out.println("error");
        }finally{
            if (number.num > 20){
                System.out.println("number.num>20 : " + number.num);
            }
            System.out.println("finally");
            number.num = 100;
        }
        return number;
    }
}
class Num{
    public int num = 10;
}
package com.mashibing;

import java.util.InputMismatchException;
import java.util.Scanner;

public class ExerciseDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入课程编号");
        try{
            int i = scanner.nextInt();
            if(i==0){
                System.out.println("java");
            }else if(i==1){
                System.out.println("scala");
            }else {
                System.out.println("python");
            }
        }catch(InputMismatchException e){
            e.printStackTrace();
        }finally {
            System.out.println("欢迎选课");
        }

    }
}

需求说明:

– 按照控制台提示输入1~3乊间任一个数字,程序将输出相应的

课程名称

– 根据键盘输入进行判断。如果输入正确,输出对应课程名称。

如果输入错误,给出错误提示

– 丌管输入是否正确,均输出“欢迎提出建议”语句

package exceptionReview;

import java.util.Scanner;

public class InputLesoonReview {
        public InputLesoonReview(){

        }
        public void intpulesson(String  strnum) {
            try{
                int intnum = Integer.valueOf(strnum);
                if(intnum == 1){
                    System.out.println("欢迎选择课程1");
                }else if(intnum == 2){
                    System.out.println("欢迎选择课程2");
                }else if(intnum == 3){
                    System.out.println("欢迎选择课程3");
                }else {
                    throw new Exception("只能输入数字1-3 ,哈哈哈");
                }
            }catch (Exception e){
                System.out.println("只能输入数字字符串");
                e.printStackTrace();
            }finally {
                System.out.println("欢迎提出建议");
            }
        }

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入数字1-3");
        String newNum = sc.next();
        InputLesoonReview newlesson = new InputLesoonReview();
        newlesson.intpulesson(newNum);

    }
}

4、自定义异常

当JDk中的异常类型不能满足程序的需求时,可以自定义异常类

使用自定义异常的步骤:

  1. 定义异常类
  2. 编写构造方法,继承父类实现
  3. 实例化自定义异常对象
  4. 使用throw抛出
package com.mashibing;

public class GenderException extends Exception {
    public GenderException(){
        System.out.println("性别异常");
    }

    public GenderException(String msg){
        System.out.println(msg);
    }
}
public class Exception2 {
    public static void main(String[] args)  {
        try {
            show();
        }catch (GenderException e){
            e.printStackTrace();
        }

        System.out.println("hehehe");
    }

    public static void show() throws GenderException{
        String gender = "1234";
        if(gender.equals("man")){
            System.out.println("man");
        }else if(gender.equals("woman")){
            System.out.println("woman");
        }else{
            throw new GenderException("gender is wrong");
        }
    }

什么时候需要自定义异常类:

  • 一般情况下不需要
  • 但是公司要求明确,或者要求异常格式规范统一的时候必须要自己实现的。

需求说明

1、自定义异常

2、在setAge(int age) 中对年龄进行判断,如果年龄介于1到

100直接赋值,否则抛出自定义异常

3、在测试类中创建对象并调用setAge(int age)方法,使用try

catch捕获并处理异常

package exceptionReview;

public class MyselfExceptionReveiw extends Exception{
     public MyselfExceptionReveiw(){
         System.out.println("年龄异常,仅限于1-100");
     }

     public MyselfExceptionReveiw(String msg){
         System.out.println(msg);
     }
}
package exceptionReview;

public class MyselfExceptionTest {
    public static void main(String[] args) {
        try{
            setAge(900);
        }catch (MyselfExceptionReveiw e){
            e.printStackTrace();
        }

        System.out.println("自定义异常演示");
    }

    public static  void  setAge(int age) throws MyselfExceptionReveiw{
        if(age>=1 && age <= 100){
            System.out.println("your age is formal.");
        }else{
            throw new MyselfExceptionReveiw("年龄在1-100之间!");
        }
    }
}

八、常用类

1、包装类

包装类是将基本类型封装到一个类中:包含属性和方法,方便对象操作。

包装类位于java.lang包中。

在使用过程中,会涉及到自动装箱和自动拆箱

装箱:将基本数据类型转换成包装类

拆箱:将包装类装换成基本数据类型

基本数据类型转换为包装类:

Integer intvalue = new Integer(21);
或者Integer intvalue = new Integer("21");
Integer intvalue = Integer.valueOf("21")

包装类转为基本数据类型

Integer inteferId = new Integer(25);
int intid = inteferID.intValue();

基本类型和包装类的自动转换

Integer intObject = 5;
int intvalue = intObject;

自动装箱

– 基本类型就自动地封装到与它相同类型的包装中,如:

– Integer i = 100;

– 本质上是,编译器编译时为我们添加了:

– Integer i = Integer.valueOf(100);

▪ 自动拆箱

– 包装类对象自动转换成基本类型数据。如:

– int a = new Integer(100);

– 本质上,编译器编译时为我们添加了:

– int a = new Integer(100).intValue();

2、String类

java字符串就是Unicode字符序列,例如串"Java"就是四个unicode字符J,a,v,a组成的

注意:常量池在1.7之后放置在了堆之中。
字符串的使用:
1、创建
String str = “abc”;
String str2 = new String(“abc”);
两种方式都可以用,只不过第一种使用比较多
2、字符串的本质
字符串的本质是字符数组或者叫做字符序列
String类使用final修饰,不可以被继承
使用equals方法比较的是字符数组的每一个位置的值。
String是一个不可变的对象

java允许使用符号"+"把两个字符串连接起来。

  • String s1 = “Hello”; String s2 = “world”;
  • String s = s1+s2;

String类的常用方法如下:

package ClassReview;

public class StringClassReview {
    public static void main(String[] args) {
        String str = " 12A34567890A ";
        //String类的常用方法如下
        //char charArt(int index)返回字符串中index索引得字符
        System.out.println(str.charAt(0));
        //boolean equals(String other),如果字符串与other相等,返回true
        System.out.println(str.equals("1234567890"));
        //boolean equalsIgnoreCasse(String other),如果字符串与other相等(忽略大小写),返回true
        System.out.println(str.equalsIgnoreCase("1234567890a"));
        //int indexOf(String str)返回字符位于字符串得那一个索引(从左向右查询,只获取遇到得第一个字符得索引)
        System.out.println(str.indexOf("2"));
        //lastIndexOf(String str,int idx)(从左向右查询字符串,核对str字符在字符串中得位置,一直查询到索引idx得字符,如果不指定idx,那么就查询到字符串得最末尾,获取最后一次匹配到字符的索引)
        System.out.println(str.lastIndexOf("A",11));
        //int length(),获取字符串的长度
        System.out.println(str.length());
        //String replace(char oldChar,char newChar),将字符串中的每一个子串oldchar替换为新子串newChar
        System.out.println(str.replace("A","B"));
        //boolean startsWith(String prefix)//判断字符串是否以prefix开头
        System.out.println(str.startsWith("12A"));
        //boolean endsWith(String prefix)判断字符串是否以prefix结尾
        System.out.println(str.endsWith("90A"));
        //String substring(int beginIndex)/,获取从索引beginIndex开始到最末尾的子串
        System.out.println(str.substring(9));
        //String toLowerCase(),字符串大写变小写,所有
        System.out.println(str.toLowerCase());
        //String toUpperCase(),字符串都变成大写
        System.out.println(str.toUpperCase());
        //String trim();删除了开头和尾部的空格
        System.out.println(str.trim());
        
        //concat()方法,能够连接两个字符串
        //join()方法,能以指定的连接符号,拼接两个字符串,str.joing(".",str1,str2)
        System.out.println(str.concat("hahahah"));
        //split()方法,将一个字符串分割为子字符串,结果作为字符串数组返回
        //contains() 判断一个字符串是否包含某个字符
        String[] newstr = str.split(" ");
        System.out.println(newstr[1]);
    }
}

练习:训练要点:

– String类的使用。

– 带参方法的定义和使用

▪ 需求说明:

– 实现会员注册,要求用户名长度不小于3,密码长度不小于6,注册时两次

输入密码必须相同

▪ 实现思路:

– 1、创建类Register

– 2、创建验证方法verify()

– 3、调用方法测试程序

▪ 难点指导:

– 创建验证方法verify()

package ClassReview.VipLoginReveiw;

import java.util.Scanner;

public class Register {
    private String name;
    private String passwd;
    Scanner sc = new Scanner(System.in);
    Verify newveri = new Verify();
    private    void setName(){
        System.out.println("请输入用户名");
        String uname = sc.next();
        if(!newveri.verifyusernameLength(uname)){
            System.out.println("用户名长度不能小于3");
            System.exit(19);
        }

    }
    private void setPasswd(){
        System.out.println(

你可能感兴趣的:(java学习)