Java基础SE.03.Java面向对象

Java基础SE.03.Java面向对象

1.Java面向对象概述

1.编程思想

编程思想主要分为:面向过程(Procedure Oriented Programming),面向对象(Object Oriented Programming)。

面向对象思想:“万事万物皆对象”

2.面向对象的两个要素:类和对象

类:对一类事物的描述,是抽象的,概念上的定义
对象:是实际存在的该类事物的每个个体,也称为实例(instance)

说明:类中主要包含①成员变量(属性)②构造方法:用于类的对象的实例化③方法:用于实现类实例化对象的某些的功能

匿名对象:不声明对象的名称而直接作为形参调用方法,只能调用一次

//案例
public class PersonTest{
	public static void main(String[] args){
		//创建Person类的对象
		Person p1 = new Person();
		//调用对象的结构:属性,方法
		//调用属性
		p1.name = "Tom";
		p1.isMale = true;
		System.out.println(p1.name);
		//调用方法
		p1.eat();
		p1.sleep();
		p1.talk("Chinese");
		
		Person p2 = new Person();
		System.out.println(p2.name);//null因为p2具有Person类的属性和方法,但是name属性没有赋值,所以初始化值为null
		//和数组类似,赋值的p1地址值给p3
		Person p3 = p1;
		p3.age = 10;
		System.out.println(p1.age);//10
		//匿名对象
		//new Person().eat();常用下面这种方法
		PersonCall per = new PersonCall();
		per.show(new Person());
	}
}
class PersonCall{
	public void show(Person person){
		person.eat();
		person.sleep();
	}
}
class Person{
	//属性
	String name;
	int age;
	boolean isMale;
	//方法
	public void eat(){
		System.out.println("人可以吃饭");
	}
	public void sleep(){
		System.out.println("人可以睡觉");
	}
	public void talk(String language){
		System.out.println("人可以说" + language);
	}
}

3.类的方法

1.普通方法的声明:

​ 权限修饰符 返回值类型 方法名(形参列表){
​ 方法体
}

注意:方法内可以调用其他方法,也可以调用自身方法,调用自身被称为递归方法

方法中不可以在声明方法

//案例 编写程序,声明一个method方法,打印10*8的*型矩形,在main里调用
public class Exer3Test{
	public static void main(String[] args){
		Exer3Test test = new Exer3Test();
		test.method();
	}
	public void method(){
		for(int i = 0;i < 10;i++){
			for(int j = 0;i < 8;j++){
				System.out.print("*");
			}
			System.out.println();
		}
	}
}
//案例 打印矩形并计算面积并返回面积
public class Exer3Test{
	public static void main(String[] args){
		Exer3Test test = new Exer3Test();
		int area = test.method();
		System.out.println(area);
		//System.out.println(test.method());
	}
	public int method(){
		for(int i = 0;i < 10;i++){
			for(int j = 0;i < 8;j++){
				System.out.print("*");
			}
			System.out.println();
		}
		return 10 * 8;
	}
}
//案例 打印吗m*n的矩形并计算面积
public class Exer3Test{
	public static void main(String[] args){
		Exer3Test test = new Exer3Test();
		int area = test.method(8,8);
		System.out.println(area);
		//System.out.println(test.method(8,8));
	}
	public int method(int m,int n){
		for(int i = 0;i < m;i++){
			for(int j = 0;i < n;j++){
				System.out.print("*");
			}
			System.out.println();
		}
		return m * n;
	}
}
2.构造方法(构造器)

1.构造器的作用
①创建对象
②初始化对象的信息

2.说明
①没有显式的定义构造器,则系统默认提供一个空参的构造器
②定义构造器:权限修饰符 类名(形参列表){}
③一个类中定义的多个构造器也构成重载
④一旦显式的定义构造器,将不再提供默认的空参构造器,但至少要有一个构造器

3.属性赋值的先后顺序

①.默认初始化值
②.显式初始化值
③.构造器中赋值
④.通过"对象.方法"和"对象.属性"的方式赋值
⑤在代码块中赋值
先后顺序为:① - ② - ③ - ④ - ⑤

//案例
public class PersonTest(){
	public static void main(String[] args){
		//创建类的对象:new + 构造器
		Person p = new Person();
		//初始化对象的属性
		Person p = new Person("Tom");
	}
}
class Person{
	String name;
	int age;
	//构造器
	public Person(){
		System.out.println("这是构造器");
	}
	public Person(String n){
		name = n;
	}
	public void eat(){
		System.out.println("吃饭");
	}
	public void talk(){
		System.out.println("说话");
	}
}
//案例
public class PersonTest(){
	public static void main(String[] args){
		//创建的每一个对象的年龄默认值都是18
		Person p1 = new Person();
		System.out.println(p1.getAge());
		person p2 = new Person(21,"Tom");
		System.out.println(p2.getAge() + p2.getName());
	}
}
class Person{
	pravite String name;
	pravite int age;
	//构造器
	public Person(){
		age = 18;
	}
	public Person(int a,String n){
		age = a;
		name = n;
	}
	public int getAge(){
		return age;
	}
	public int getName(){
		return name;
	}
}
//案例
public class TriAngleTest{
	public static void main(String[] args){
		TriAngle t1 = new TriAngle();
		t1.setBase(2.0);
		t1.setHeight(2.4);
		System.out.println(t1.getBase() +t1.getHeight());
		TriAngle t2 = new TriAngle(2.0,2.4);
		System.out.println(t2.getBase() +t2.getHeight());
	}
}
//不同类
public class TriAngle{
	private double base;
	private double height;
	public TriAngle(){
		
	}
	public TriAngle(double b,double h){
		base = b;
		height = h;
	}
	public void setBase(double b){
		base = b;
	}
	public double getBase(){
		return base;
	}
	public void setHeight(double b){
		height = b;
	}
	public double getHeight(){
		return height;
	}
}
public class OrederTest {
	public static void main(String[] args) {
		Order order = new Order();
		System.out.println(order.orderId);//4
		Order1 order1 = new Order1();
		System.out.println(order1.orderId1);//3
	}
}

class Order{
	int orderId = 3;
	{
		orderId = 4;
	}
}

class Order1{
	{
		orderId1 = 4;
	}
	int orderId1 = 3;
}

4.权限修饰符

1.权限修饰符:①private、缺省(就是什么也不写)、protected、public

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eY8CeEmC-1602930317567)(/image-20200929220723801.png)]

②.四种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
③.修饰类只能用缺省、public

5.引用数据类型内存解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7rkRdYYd-1602930317570)(/image-20201009111734955.png)]

其本质就是先声明数组,然后在数组中的每一个元素内建立新的对象实例,并改变属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LdCrJ8Dw-1602930317572)(/image-20201009111851522.png)]

//案例 对象数组
public class StudentTest{
	public static void main(String[] args){
		Student[] stus = new Student[20];
		for(int i = 0;i < stus.length;i++){
			stus[i] = new Student();
			stus[i].number = i + 1; 
			stus[i].state = (int)(Math.random() * 6 +1);
			stus[i].score = (int)(Math.random() * 100 +1)
		}
		//StudentTest test = new StudentTest();
		//打印同学所有信息
		for(int i = 0;i < stus.length;i++){
			//System.out.println(stus[i].number);
			//System.out.println(stus[i].state);
			//System.out.println(stus[i].score);
			System.out.println(stus[i].info());
		}
		//test.print(stus);
		//打印三年级的信息
		for(int i = 0;i < stus.length;i++){
			if(stus[i].state == 3){
				System.out.println(stus[i].info());
			}
		}
		//test.searchState(stus,3);
		//冒泡排序学生成绩,并遍历
		for(int i = 0;i < stus.length - 1;i++){
			for(int j = 0;j < stus.length - 1 - i;j++){
				Student temp = stus[j];
				stus[j] = stus[j + 1];
				stus[j + 1] = temp;
			}
		}
		for(int i = 0;i < stus.length;i++){
			System.out.println(stus[i].info());
		}
		//test.sort(stus);
		//test.print(stus);
	}
	//***************************************************
	//将上述方法封装
	//遍历学生信息
	public void print(Student1[] stus){
		for(int i = 0;i < stus.length;i++){
			if(stus[i].state == 3){
				System.out.println(stus[i].info());
			}
		}
	}
	//查找三年级学生的成绩
	public void searchState(Student[] stus,int state){
		for(int i = 0;i < stus.length;i++){
			if(stus[i].state == 3){
				System.out.println(stus[i].info());
			}
		}
	}
	//给学生成绩排序
	public void sort(Student[] stus){
		for(int i = 0;i < stus.length - 1;i++){
			for(int j = 0;j < stus.length - 1 - i;j++){
				Student temp = stus[j];
				stus[j] = stus[j + 1];
				stus[j + 1] = temp;
			}
		}
	}
}
class Student{
	int number;//学号
	int state;//年级
	int score;//成绩
	public String info(){
		return "学号" + number + "年级" + state + "成绩" + score;
	}
}
//案例 自定义工具类
public class ArrayUtilTest{
	public static void main(String[] args){
		ArrayUtil util = new ArrayUtil();
		int[] arr = new int[]{20,48,9,4,1,18,66,88,19};
		int max = util.getMax();
		int min = util.getMin();
		System.out.println("Max" + max + "Min" + min);
		util.print(arr);
		System.out.println(arr);
		util.sor(arr);
		System.out.println(arr);
		int index = util.getIndex(arr,1);
		if(index >= 0){
			System.out.println(index);
		}else{
			System.out.println("没找到");
		}
	}
}
//不同类文件
public class ArrayUtil{
	//求数组的最大值
	public int getMax(int[] arr){
		int maxValue = arr[0];
		for(int i = 0;i < arr.length;i++){
			if(maxValue < arr[i]){
				maxValue = arr[i];
			}
		}
		return maxValue;
	}
	//求数组的最小值
	public int getMin(int[] arr){
		int minValue = arr[0];
		for(int i = 0;i < arr.length;i++){
			if(minValue > arr[i]){
				minValue = arr[i];
			}
		}
		return minValue;
	}
	//求数组的总和
	public int getSum(int[] arr){
		int allValue = 0;
		for(int i = 0;i < arr.length;i++){
			allValue += arr[i];
		}
		return allValue;
	}
	//求数组的平均值
	public int getAvg(int[] arr){
		return getSum(arr) / arr.length;
	}
	//反转数组
	public void reverse(){
		for(int i = 0;i < arr.length / 2;i++){
			String temp = arr[i];
			arr[i] = arr[arr.length - i - 1];
			arr[arr.length - i - 1] = temp;
		}
	}
	//复制数组
	public int[] copy(int[] arr){
		String[] arr = new String[arr.length];
		for(int i = 0;i < arr.length;i++){
			arr[i] = arr[i];
		}
	}
	//数组排序
	public void sort(int[] arr){
		int[] arr = new int[]{8,9,1,5,-10,48,55,4,20};
		int dest = 0; 
		for(int i = 0;i < arr.length - 1;i++){
			for(int j = 0;j < arr.length - 1 - i;j++){
				if(arr[j] > arr[j+1]){
					dest = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = dest;
				}
			}
		}
		for(int i = 0;i < arr.length;i++) {
			System.out.print(arr[i] + " ");
		}
	}
	//遍历数组
	public void print(int[] arr){
		for(int i = 0;i < arr.length;i++) {
		System.out.print(arr[i] + " ");
		}
	}
	//查找指定元素
	public int getIndex(int[] arr,int dest){
		boolean ifFlag = true;
		for(int i = 0;i < arr.length;i++){
			if(dest.equals(arr[i])){
				return i;
			}
		}
		return - 1;
	}
}

2.面向对象的三大特征

1.封装

1.程序设计追求“高内聚,低耦合”
高内聚:类的内部数据操作细节自己完成,不允许外部干涉
低耦合:仅对外暴露少量的方法用于使用

2.封装性的体现
①私有化属性
②私有化方法(类的内部使用)
③单例模式(私有化构造器)等

说明:使用get和set方法获取对象属性的值,可以添加限定条件防止用户输入不合法数值

//案例
public class AnimalTest{
	public static void main(String[] args){
		Animal a = new Animal();
		a.name = "dahuang";
		a.age = 1;
		a.legs = 4;
		a.show();
		//限制legs只能输入大于0的数,且为双数
		a.setLegs(6);
		a.show();
	}
}
class Animal{
	String name;
	int age;
	private int legs;//腿的个数,加private权限修饰符,使得主方法中无法直接访问,必须通过访问方法来访问这个属性
	//对属性的设置
	public void setLegs(int l){
		if(l >= 0 && l % 2 ==0){
			legs = l;
		}else{
			legs = 0;//默认值为0
		}
	}
	//获取属性的值
	public int getLegs(){
		return legs;
	}
	public void eat(){
		System.out.println("动物进食");
	}
	public void show(){
		System.out.println(name + " " + age + " " + legs);
	}
}

2.继承

1.继承的概述

1.继承性的优点:
①减少了代码的冗余,提高了代码的复用性
②便于功能的扩展
③为多态提供了前提
2.继承性的格式 class A extends B{}
A:子类、派生类、subcalss
B:父类、超类、基类、superclass
体现:子类一旦继承父类以后,子类获得父类中声明的结构、属性、方法
3.子类继承父类以后还可以声明自己特有的方法和属性,实现功能的一个拓展
4.Java中关于继承性的规定
①单继承性:一个子类只能有一个父类
②一个父类可以派生多个子类
③子父类是相对概念,…A–>B–>C C继承B类B继承A,称B是C的直接父类,A是C的间接父类,所以C获取了直接父类和所有间接父类的结构,方法和属性

2.子类对象实例化的全过程

1.从结果来看:子类继承父类以后,就获取了父类中声明的属性和方法
创建子类的对象,在堆空间中,就会加载所有父类中声明的属性
2.从过程来看:我们通过子类的构造器创建对象,我们一定会直接或间接的调用直接父类和间接父类的构造器,直到java.lang.Object类中的空参构造器,正因为加载过所有的父类的结构,所以才可以看到内存中有父类的结构,子类对象才可以考虑进行调用
3.虽然子类创建对象时调用了父类的构造器,但是创建的对象还是为子类的一个new的对象

//案例
public class CheckAccount extends Account{
	
	private double overdraft;//可透支限额
	
	public CheckAccount(int id, double balance, double annualInterestRate,double overdraft) {
		super(id,balance,annualInterestRate);
		this.overdraft = overdraft;
	}
	
	public void withdraw(double amount) {
		if(getBalance() >= amount) {//余额足够
			//setBalance(getBalance() - amount);
			super.withdraw(amount);
		}else if(overdraft >= amount - getBalance()) {//透支额度
			overdraft -= amount - getBalance();
			//setBalance(0);
			super.withdraw(getBalance());
		}else {
			System.out.println("超过可透支限额");
		}
	}

	public double getOverdraft() {
		return overdraft;
	}

	public void setOverdraft(double overdraft) {
		this.overdraft = overdraft;
	}
}
//
public class Account {
	private int id;//账号
	private double balance;//余额
	private double annualInterestRate;//年利率
	
	public Account() {
		super();
	}

	public Account(int id, double balance, double annualInterestRate) {
		super();
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}

	public int getId() {
		return id;
	}

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

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}

	public double getAnnualInterestRate() {
		return annualInterestRate;
	}

	public void setAnnualInterestRate(double annualInterestRate) {
		this.annualInterestRate = annualInterestRate;
	}
	//月利率
	public double getMonthlyInterest() {
		return annualInterestRate / 12;
	}
	//取钱
	public void withdraw(double amount) {
		if(balance >= amount) {
			balance -= amount;
			return;
		}
	}
	//存钱
	public void deposit(double amount) {
		if(amount > 0) {
			balance += amount;
		}
	}
}
//
public class CheckAccountTest {
	public static void main(String[] args) {
		
		CheckAccount acct = new CheckAccount(1122, 20000, 0.045, 5000);
		
		acct.withdraw(5000);
		System.out.println("你的账户余额" + acct.getBalance());
		System.out.println("你的可透支额度为" + acct.getOverdraft());
		acct.withdraw(18000);
		System.out.println("你的账户余额" + acct.getBalance());
		System.out.println("你的可透支额度为" + acct.getOverdraft());
		acct.withdraw(3000);
		System.out.println("你的账户余额" + acct.getBalance());
		System.out.println("你的可透支额度为" + acct.getOverdraft());
		
	}
}
//
public class AccountTest {
	public static void main(String[] args) {
		Account acct = new Account(1122,20000,0.045);
		
		acct.withdraw(30000);
		System.out.println("我的余额" + acct.getBalance());
		acct.withdraw(2500);
		System.out.println("我的余额" + acct.getBalance());
		
		acct.deposit(3000);
		System.out.println("我的余额" + acct.getBalance());
		
		System.out.println("月利率" + (acct.getMonthlyInterest() * 100));
	}
}

3.多态

1.多态性(polymorphism)运行时行为

1.多态性(polymorphism)运行时行为
①有了对象的多态性以后,我们在编译期只能调用父类声明的方法,但在运行期,我们实际执行的是子类重写父类的方法
②:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
③例:Person p = new Man();
p.eat();
调用方法,编译时看左边,运行时看右边
2.多态性使用的前提
①类的继承关系②要有方法的重写
3.多态性的作用:
在调用方法时就可以直接将创建的子类的对象作为形参列表调用父类的方法,从而得到子类的方法的输出,这样可以减少方法编写的冗余
4.对象的多态性只适用于方法,不适用于属性
当多态调用属性时,只看左边
5.多态的使用,虚拟方法调用Virtual Method Invocation
多态情况下,子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同于子类对象,动态调用属于子类的该方法,这样的方法调用在编译期是无法确定的

//案例
public class Man extends Person{
	
	boolean isSmoking;
	
	public void earnMoney() {
		System.out.println("男人挣钱");
	}
	
	public void eat() {
		System.out.println("eat more man");
	}
	
	public void walk() {
		System.out.println("walk more man");
	}
}
//
public class Person {
	
	String name;
	int age;
	
	public void eat() {
		System.out.println("eat");
	}
	
	public void walk() {
		System.out.println("walk");
	}
}
//
public class woman extends Person{
	
	boolean isBeauty;
	
	public void goShopping() {
		System.out.println("goshopping woman");
	}
	
	public void eat() {
		System.out.println("eat little woman");
	}
	
	public void walk() {
		System.out.println("walk little woman");
	}
}
//
public class PersonTest {
	public static void main(String[] args) {
		
		Person p1 = new Person();
		p1.eat();
		
		Man man = new Man();
		man.eat();
		man.age = 25;
		man.earnMoney();
		
		//对象的 多态性:父类的引用指向子类的对象
		Person p2 = new Man();
		p2.eat();//调用的是子类重写父类的方法,只能调用Person类里声
明的方法
		//对象的 多态性:父类的引用指向子类的对象
		Person p2 = new Man();
		p2.eat();//调用的是子类重写父类的方法,只能调用Person类里声明的方法
		
		//不能调用子类所特有的方法,属性,编译时,p2是Person类
		//p2.earnMoney();
		
		//有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为
		//父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能调用
		//向下转型,使用强制类型转换将Person的p2转换为Man类的m1
		Man m1 = (Man)p2;
		m1.earnMoney();
		
		//使用强转时可能出现ClassCastException异常
		//Woman m2 = (Woman)p2;
		//m2.goShopping();//异常
		
		//instanceof关键字
		//a instanceof A:判断对象a是否是类A的实例,如果是,返回true,如果不是,返回false
		//为了避免向下转型时出现异常,我们在向下转型之前先进行instanceof判断,出现ture才可以进行转型
		if(p2 instanceof Woman) {
			Woman m2 = (Woman)p2;
			m2.goShopping();
		}
		
		//如果a instanceof A返回ture,ainstanceof B也返回ture
		//其中类B是A的父类
		
		Person p4 = new Person();
		Man m4 = (Man)p4;//异常
		//只能从父类向子类进行转型
		Object obj = new Woman();
		Person p = (Person)obj;
		
	}
}
//案例※
class Base{
	int count = 10;
	
	public void display() {
		System.out.println(this.count);
	}
}

class Sub extends Base{
	int count = 20;
	
	public void display() {
		System.out.println(this.count);
	}
}

public class FieldMethodTest {
	private void mian() {
		Sub s = new Sub();
		System.out.println(s.count);//20
		s.display();//20
		//多态性,属性都看左边,方法先看左边再看右边
		Base b = s;
		//==,在此处比较的是两个数据的地址值是否相同
		System.out.println(b == s);//true
		System.out.println(b.count);//10
		b.display();//20
		
	}
}
//案例
public class InstanceTest {
	public static void main(String[] args) {
		
		InstanceTest test = new InstanceTest();
		test.method(new Student());
		
	}
	
	public void method(Person e) {
		String info = e.getInfo();
		System.out.println(info);
		
//		if(e instanceof Graduate) {
//			System.out.println("a graduate student");
//			System.out.println("a student");
//			System.out.println("a person");
//		}else if(e instanceof Student) {
//			System.out.println("a student");
//			System.out.println("a person");
//		}else{
//			System.out.println("a person");
//		}
		
		if(e instanceof Graduate) {
			System.out.println("a graduate student");
		}
		if(e instanceof Student) {
			System.out.println("a student");
		}
		if(e instanceof Person) {
			System.out.println("a person");
		}
	}
}

class Person{
	protected String name = "person";
	protected int age = 50;
	
	public String getInfo() {
		return "Name:" + name + "\n" + "age:" + age;
	}
}

class Student extends Person{
	protected String school = "pku";
	
	public String getInfo() {
		return "Name:" + name + "\n age:" + age + "\n school:" + school;
	}
}

class Graduate extends Student{
	public String major = "IT";
	
	public String getInfo() {
		return "Name:" + name +"\nage:" + age + "\nschool:" + school + "\nmajor:" + major;
	}
}
//案例
public class Circle extends GeometricObject {
	private double radius;

	public Circle(double radius,String color,double weight) {
		super(color, radius);
		this.radius = radius;
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	public double findArea() {
		return 3.14 * radius * radius;
	}
}
//
public class MyRectangle extends GeometricObject {
	
	private double width;
	private double height;
	
	public MyRectangle(String color, double weight,double width,double height) {
		super(color, weight);
		this.width = width;
		this.height = height;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
	
	public double findArea() {
		return width * height;
	}
}
//
public class GeometricObject {
	protected String color;
	protected double weight;
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
	public GeometricObject(String color, double weight) {
		super();
		this.color = color;
		this.weight = weight;
	}
	//返回面积
	public double findArea() {
		return 0.0;
	}
}
//
public class GeometricTest {
	public static void main(String[] args) {
		
		GeometricTest test = new GeometricTest();
		
		Circle c1 = new Circle(2.3, "white", 1.0);
		test.displayGeometricObjectObject(c1);
		
		Circle c2 = new Circle(3.3, "white", 1.0);
		test.displayGeometricObjectObject(c2);
		
		boolean isEquals = test.equalsArea(c1, c2);
		System.out.println("c1和c2的面积是否相等" + isEquals);
		
		MyRectangle rect = new MyRectangle("red" , 3.4 , 2.1 , 2.0);
		test.displayGeometricObjectObject(rect);
		
	}
	
	//比较两个面积是否相等
	public boolean equalsArea(GeometricObject o1,GeometricObject o2) {//GeometricObject o1 = new Circle();
		return o1.findArea() == o2.findArea();
	}
	
	//显示对象的面积
	public void displayGeometricObjectObject(GeometricObject o) {
		System.out.println("面积为" + o.findArea());
	}
}
//案例
public class InterviewTest1 {
	public static void main(String[] args) {
		Base1 base = new Sub1();
		base.add(1,2,3);//sub_1 在add第二个方法注释掉时
		//当第二个方法不注释时,sub_1 
		
		Sub1 s = (Sub1)base;
		s.add(1,2,3);
	}
}

class Base1{
	public void add(int a,int...arr) {
		System.out.println("base1");
	}
}

class Sub1 extends Base1{
	public void add(int a,int[] arr) {
		System.out.println("sub_1");
	}
	public void add(int a,int b,int c) {
		System.out.println("sub_2");
	}
}
2.方法的重载

1.重载(overload):在同一个类中,允许存在一个以上的同名方法,只要他们的参数或者参数的类型不同即刻
判断是否重载:跟方法的使用权限修饰符,返回值类型,形参变量名,方法体都没有关系

案例//
public class OverLoadTest{
	public static void main(String[] args){
		OverLoadTest test = new OverLoadTest();
		test.getSum(1,2);
		//当第一个不存在int i,int j时,则会自动类型提升使用double i,double j
	}
	public void getSum(int i,int j){
		System.out.println(i + j);
	}
	public void getSum(double i,double j){
		System.out.println(i + j);
	}
	public void getSum(String i,int j){
		System.out.println(i + j);
	}
	public void getSum(int i,String j){
		System.out.println(i + j);
	}
}
//案例
public class OverloadExer{
	public void mOL(int i){
		System.out.println(i);
	}
	public void mOL(int i,int j){
		System.out.println(i * j);
	}
	public void mOL(String s{
		System.out.println(s);
	}
	public int max(int i;int j){
		return (i >j)?i : j;
	}
	public double max(double i;double j){
		return (i >j)?i : j;
	}
}

2.可变个数形参的方法(jdk5.0新增)
说明:①数据类型 + … + 形参
②当调用可变个数形参方法时,形参的数量不受限制
③可变个数形参的方法和方法名相同且形参不同的方法构成重载
④和方法名相同且形参为数组的方法不构成重载
⑤可变个数的形参必须写在其他形参的最后,并且只能写一个可变个数形参

//案例
public class MethodArgsTest{
	public static void main(String[] args){
		MethodArgsTest test = new MethodArgsTest();
		test.show(12);
		//如果不存在一个形参个数String类型的方法,则会使用可变个数形参方法
		test.show("hello");
		test.show("one","two");
	}
	public void show(int i){
		System.out.println(i);
	}
	public void show(String s){
		System.out.println(s);
	}
	public void show(String ... strs){
		System.out.println("show(String ... strs)");
		for(int i = 0;i < strs.length;i++){
			System.out.println(strs[i]);
		}
	}
	//④和方法名相同且形参为数组的方法不构成重载
	//public void show(String[] strs){
	//	System.out.println("show(String ... strs)");
	//}
	public void show(int i;String ... strs){
		System.out.println("show(String ... strs)");
	}
}

3.方法参数的值的传递机制
①说明:基本数据类型赋值:传递数值
引用数据类型赋值:传递地址值
②实参,形参
还实参和形参传值,注意数据类型所代表的值是数值是传递地址值

//案例
public class ValueTransferTest{
	public void main(String[] args){
		//基本数据类型赋值
		int m = 10;
		int n = m;
		System.out.println( m + " " +n);//10 10
		n = 20;
		System.out.println( m + " " +n);//10 20
		//引用数据类型赋值(没有定义Order类,这里只做演示)
		Order o1 = new Order();
		o1.orderId = 1001;
		Order o2 = o1;//赋值地址值
		System.out.println(o1 + " " + o2);//1001 1001
		o2.orderId = 1002;
		System.out.println(o1 + " " + o2);//1002 1002
		//实参,形参的使用(值都在栈中储存)
		ValueTransferTest test = new 						ValueTransferTest();
		int m = 10;
		int n = 20;
		test.swap(m,n);
		//实参是引用数据类型时
		Data data = new Data();
		data.swap(data);
	}
    	public void swap(int m,int n){
		int temp = m;
		m = n;
		n = temp;
	}
	public void swap(Data data){
		int temp = data.m;
		data.m = data.n;
		data.n = temp;
	}
}
class Data{
	int m = 10;
	int n = 20;
}

//案例的内存解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hyVdih7I-1602930317578)(/image-20201009195822143.png)]

//案例
public class Test{
	public static void main(String[] args){
		int a = 10;
		int b = 10;
		method(a,b);//要求调用方法后输出a为100,b为200
		System.out.println("a =" + a);
		System.out.println("b =" + b);
	}
	//方法一
	public static void method(int a,int b){
		a = a * 10;
		b = b * 20;
		System.out.println(a);
		System.out.println(b);
		System.exit(0);//退出程序
	}
	//方法二
	public static void method(int a,int b){
		//通过修改输出流
		PrintStream new PrintStream(System.out){
			@Override
			public void println(String x){
				if("a = 10".equals(x)){
					x = "a = 100";
				}else if("b = 10".equals(x)){
					x = "b = 200"
				}
			super.println(x);
			}
		};
		System.setOut(ps);
	}
}
//案例
{
	int[] arr = new int[]{};
	System.out.println(arr);//地址值
	char[] arr1 = new char[]{};
	System.out.println(arr1);//abc因为println()中有遍历char[]的方法
}
//案例
public class Circle{
	double radius;
	public double findArea(){
		return Math.PI * radius * radius;
	}
}
//定义一个新类
public class PassObject{
	public static void main(String[] args){
		PassObject test = new PassObject();
		Circle c = new Circle();
		test.printAreas(c,5);
		System.out.println(c.radius);
	}
	public void printAreas(Circle c,int time){
		System.out.println("Radius\t\tArea");
		int i = 0
		for(;i < time;i++){
			c.radius = i;
			System.ot.println(c.radius + "\t\t" + c.findArea());
		}
		c.radius = i;
}
3.方法的重写

1.重写override/overwrite
定义:子类继承父类以后,可以对父类同名同参数的方法进行覆盖的操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mCHlIJT9-1602930317581)(/image-20201009200015537.png)]

2.返回值类型
方法声明:权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
//方法体
}
①父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
②子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
③子类重写的方法返回值类型是基本数据类型(例.double),则子类重写的方法返回值类型必须是相同的基本数据类型(例.必须是double)
④throws异常类型:子类重写的方法抛出异常类型不大于父类被重写的方法抛出的异常类型

//案例
public class Person {
	String name;
	int age;
	
	public Person() {
		
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public void eat(){
		System.out.println("eat");
	}
	public void walk(int distance) {
		System.out.println("walk" + distance);
	}
	private void show() {
		System.out.println("i am a man");
	}
	public Object info() {
		return null;
	}
}
//
public class Student extends Person{
	String major;
	public Student() {
		
	}
	public Student(String major) {
		this.major = major;
	}
	
	public void study() {
		System.out.println("study" + major);
	}
	//重写父类方法public void eat() {
		System.out.println("eat more health food");
	}
	//父类中私有权限的方法子类中就不能称为重写,因为子类无法看到私有的方法
	public void show() {
		System.out.println("i am a man");
	}
	//子类重写的返回值应小于父类public String info() {
		return null;
	}
}
//
public class PersonTest {
	public static void main(String[] args) {
		Student s = new Student("computer");
		//子类调用的是子类重写以后的方法
		s.eat();
		s.walk(10);
		
		s.study();
		//父类调用的eat()方法还是自己原有的方法
		Person p1 = new Person();
		p1.eat();
	}
}

区分方法的重写和重载?
①二者的概念:重载,在同一个类中,允许存在一个以上的同名方法,只要他们的参数或者参数的类型不同即刻
重写,子类继承父类以后,可以对父类同名同参数的方法进行覆盖的操作。
②重写和重载的具体规则
③重载:不表现为多态性
重写:表现为多态性
④重载,是指允许存在同名方法,而这些方法的参数不同,编译器根据方法不同的参数表,对同名方法的名称做修饰,对于编译器而言,这些同名方法就成了不同的方法,他们调用地址在编译器就绑定了,Java的重载可以使包括父类和子类的,即子类可以重载父类的同名不同参数的方法,所以,对于重载而言,在调用方法之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”
而对于多态,只等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”

3.关键字

1.return关键字

表示返回一个对应的数据类型的值,如果方法没有返回值,return则表示结束方法

注意:在return表示结束方法时,后面的代码则不再执行

2.this关键字

1.可以用来修饰:属性、方法、构造器
2.this表示当前对象,在类的方法中通过"this.属性"或"this.方法"调用当前对象的属性和方法,通常省略,这里形参和属性重名所以不可省略
3.在类的构造器中可以显式的使用this(形参列表)来调用本类中其他的构造器,但不能调用自己,且必须声明在当前构造器的首行

//案例
public class PersonTest{
	public static void main(String[] args){
		Person p1 = new Person();
		p1.setName("Tom");
		System.out.println(p1.getName());
	}
}
class Person{
	private String name;
	private int age;
	public Person(){
		this.eat();
	}
	public Person(String name){
		this();//调用第一个无参构造器
		this.name = name;
	}
	public Person(int age){
		this.age = age;
	}
	public Person(int age,String name){
		this(age);//调用参数(int age)的构造器
		this.age = age;
		this.name = name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public void setAge(int age){
		this.age = age;
	}
	public String getAge(){
		return age;
	}
	public String eat(){
		System.out.println("吃饭");
	}
}
//案例
public class Boy{
	private String name;
	private int age;
	public Boy(String n,int a){
		name = n;
		age = a;
	}
	
	public void setName(String n){
		name = n;
	}
	public String getName(){
		return name;
	}
	
	public void setAge(int a){
		age = a;
	}
	public int getAge(){
		return age;
	}
	public void marry(Girl girl){
		System.out.println("我想娶" + girl.getName());
	}
	public void shout(){
		if(this.age >= 22){
			System.out.println("你可以");
		}else{
			System.out.println("你不行");
		}
	}
}
//
public class Girl{
	private String name;
	private int age;
	public Girl(String n,int a){
		name = n;
		age = a;
	}
	public String getName(){
		return name;
	}
	public void setName(String n){
		name = n;
	}
	public int getAge(){
		return age;
	}
	public void setAge(int a){
		age = a;
	}
	public void marry(Boy boy){
		System.out.println("我想嫁" + boy.getName());
		boy.marry(this);
	}
	//返回正数当前对象大,反之当前对象小,0时当前对象和形参对象相等
	public int compare(Girl girl){
		if(this.age > girl.age){
			return 1;
		}else if(this.age < girl.age){
			return -1;
		}else{
			return 0;
		}
	}
}
//
public class BoyGirlTest{
	public static void main(String[] args){
		Boy boy = new Boy("罗密欧",21);
		boy.shout();
		Girl girl = new Girl("朱丽叶",18);
		girl.marry(boy);
		Girl girl1 = new Girl("祝英台",19);
		int compare = girl.compare(girl1);
		if(compare > 0) {
			System.out.println(girl.getName() + "大");
		}else if(compare < 0) {
			System.out.println(girl1.getName() + "大");
		}else {
			System.out.println("一样大");
		}
	}
}

3.package关键字

①为了更好的实现类的管理,提出了包的概念
②使用package声明类或接口所属的包,声明在源文件的首行
③属于标识符,遵循标识符的命名规则和规范,见明知意
④每.一次代表一层文件目录
⑤同一个包下不能命名同名的接口、类,不同包下可以

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6UtwRq6-1602930317583)(/image-20201009115655036.png)]

4.import关键字

①在源文件中显式的使用import结构导入指定的包下的类、接口
②声明在包的声明和类的声明之间
③导入多个包时并列的写出导入即可
④可以使用"xxx.*“的方式,可以导入包下的所有结构
⑤如果使用的类或接口是java.lang包下定义的,则可以省略import
⑥如果调用本包下的类或接口,也可以省略import
⑦如果类名同名不同包,则不能在导入包,只能写全类名"包名.类名”
⑧使用"xxx.*"方式表明可以调用xxx包下的所有结构,如果需要使用xxx子包下的结构,则还需要重新导包
⑨import static:表示导入类或接口中的静态结构

//案例
import java.util.Arrays;
import java.util.HashMap;
//import java.util.*;
public class PackageImportTest{
	public static void main(String[] args){
		String info = Array.toString(new int[]{1,2,3});
		HashMap map = new HashMap();
	}
}

5.super关键字

①super可以理解为,父类
②super可以用来调用属性,方法,构造器
③如果子类和父类产生同名的属性,或想要调用子类已经重写的父类的方法,则可以使用super关键字调用
④可以在子类的构造器中显式的使用“super(形参列表)”的方式,调用父类中声明的指定的构造器,并且必须声明在子类构造器的首行
⑤在类的构造器中“this(形参列表)”或“super(形参列表)”只能使用一个
⑥构造器首行没有显式的声明“this(形参列表)”或“super(形参列表)”,则默认调用父类中的空参构造器

//案例
public class Person {
	String name;
	int age;
	int id = 1001;//身份证号
	
	public Person() {
		System.out.println("i am father");
	}
	
	public Person(String name) {
		this.name = name;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public void eat() {
		System.out.println("eat");
	}
	public void walk() {
		System.out.println("walk");
	}
}
//
public class Student extends Person{
	String major;
	int id = 1002;//学号
	
	public Student() {
		
	}
	public Student(String major) {
		this.major = major;
	}
	
	public void eat() {
		System.out.println("eat more");
	}
	public void study() {
		System.out.println("study more");
	}
	public void show() {
		//
		System.out.println(this.name + " " + super.age);
	}
	public void showId() {
		//
		System.out.println(this.id + " " + super.id);
	}
}
//
public class SuperTest {
	public static void main(String[] args) {
		Student s = new Student();//调用父类的空参构造器
		s.showId();//打印子类id和父类id
	}
}

6.static关键字

1.static:静态的
2.static可以用来修饰属性、方法、代码块、内部类
3.static修饰属性

3.1 static修饰的属性被称为 静态属性 ,没有被修饰的被称为 非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性,当修改其中一个 对象中 的 非静态属性时,不会导致其他对象中同样属性的修改
静态 变量,我们创建了类的多个对象,多个对象共享同一个静态变量,那就意味着当某一个对象修改静 态变量 时,会导致其他变量调用此静态变量时,是修改过的。
3.2①静态变量随着类的加载而加载
②静态变量的加载早于对象的创建
③由于类只会加载一次,则静态变量也只会加载一次
④ 类变量 实例变量
类 yes no
对象 yes yes
3.3静态属性的举例:System.out ; Math.PI

4.static修饰方法

​ ①随着类的加载而加载,可以通过“类.静态方法”的方式直接进行调用
​ ② 静态方法 非静态方法
​ 类 yes no
​ 对象 yes yes
​ ③静态方法中只能调用静态的方法或属性
​ 非静态方法中既可以调用静态的方法或属性,也可以调用非静态的方法或属性

5.static注意点

​ 5.1静态的方法内,不能使用this关键字、super关键字
​ 5.2静态属性和静态方法主要取决于静态的属性和方法的内存解析,随着类的加载而加载,存在于方法区的静态域,而非静态的属性和方法
​ 在对象实例化以后才会占用内存

6.开发中,如何确定一个属性是否需要声明为static的?
属性是可以被多个对象共享时,类中的常量也常常声明为static

开发中,如何确定一个方法是否需要声明为static的?
操作静态属性的方法工具类中的方法,习惯上声明为static的,比如Math. Arrays. Collections

public class StaticTest {
	public static void main(String[] args) {
		
		Chinese.nation = "中国";
		
		Chinese c1 = new Chinese();
		c1.name = "帅哥";
		c1.age = 30;
		
		Chinese c2 = new Chinese();
		c1.name = "美女";
		c1.age = 18;
		
		c2.nation = "CHN";
		System.out.println(c1.nation );
		
		Chinese.show();
	}
}
class Chinese{
	String name;
	int age;
	static String nation;
	
	public static void test() {
		//静态方法中只能调用静态的变量以及静态方法
		nation = "111";
		show();
	}
	
	public static void show() {
		System.out.println("静态方法");
	}
	
}

7.final关键字

final:最终的
1.final可以用来修饰的结构,类、方法、变量
2.final用来修饰一个类:此类不能被其他类继承
比如:String类、System类、StringBuffer类
3.final用来修饰方法,表明此方法不能再被重写
比如:Object类中的getClass();
4.final用来修饰变量,此时则称为 常量
4.1 final修饰属性,可以考虑赋值的位置有,显示的初始化、代码块中初始化、构造器中初始化
4.3 final修饰局部变量
尤其是用final修饰形参时,表明此形参是一个常量,当我们调用此方法时,只能赋值一次,一旦赋值以后
,就只能在方法体内使用此形参,但不能重新赋值
static final 来修饰属性被称为全局常量

public class FinalClassTest {
	int width = 10;//可以改变
	//显示的初始化
	//常量书写标识符 一致大写
	final int HEIGHT = 20;//不可以再被改变
	final int LEFT;
	final int RIGHT;
	//代码块初始化
	{
		LEFT = 1;
	}
	//构造器初始化
	public FinalClassTest() {
		RIGHT = 2;
	}
	public void test() {
		width = 20;
//		height = 30;//异常The final field FinalClassTest.height cannot be assigned
	}
	//修饰局部变量
	public void show() {
		final int num = 10;//常量
	}
	public void show(final int num) {
		System.out.println(num);
	}
	public static void main(String[] args) {
		int num = 10;
		num = num + 5;
		FinalClassTest test = new FinalClassTest() ;
		test.show(10);
	}
}
final class FinalA{
	
}
//异常:B不能继承FinalA类
//class B extends FinalA{
//	
//}
class AA{
	public final void show() {
		
	}
}
class BB extends AA{
	//异常:方法不能再被重写
//	public void show() {
//		
//	}
}

4.常用类

1.object类

1.Object类

Object类时所有类的根父类
如果在类的声明中未使用extends关键字指明父类,则默认父类为java.lang.Object类

2.Object类中的功能(属性和方法)

equals()/toString()/getClass()/hashCode()/clone()/finalize()/…
①equals():
== 和 equals()区别
==:可以使用在基本数据类型和引用数据类型变量中
基本数据类型,比较两个数值相等,不一定要类型相同
引用数据类型,比较两个地址值相等,即两个引用是否指向同一个对象实体
②equals():

1是一个方法而非运算符,只适用于引用数据类型
Object类中定义的equals()方法和==符号作用相同,比较两个地址值是否相同,是否指向同一个对象
2像String、Date、file、包装类等都重写了Object类中的equals()方法,重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的“实体内容”是否相同
3通常情况下,我们自定义的类如果使用equals(),也通常是比较两个对象的实体内容是否相同,那么我们也应该在类中重写equals()方法比较

//案例
public class Person {
	String name;
	int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	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 boolean equals(Object obj) {
//		if(this == obj) {
//			return true;
//		}
//		if(obj instanceof Person) {
//			Person cust = (Person)obj;
//			//比较两个对象的每个属性是否相同
//			return this.age == cust.age && this.name.equals(cust.name);
//		}else {
//			return false;
//		}
//	}
	//自动生成
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}
//
public class ObjectTest {
	public static void main(String[] args) {
		
		int i = 10;
		double d = 10;
		char c = 10;
		System.out.println(i == d);//ture
		System.out.println(i == c);//true
		char c1 = 'A';
		char c2 = 65;
		System.out.println(c1 == c2);//true
		
		Person p1 = new Person("Tom",21);
		Person p2 = new Person("Tom",21);
		System.out.println(p1 == p2);//false
		
		String str1 = new String();
		String str2 = new String();
		//因为String在方法区的常量池,当两个值相同时,他的地址值则相同
		String str3 = "bb";
		String str4 = "bb";
		System.out.println(str3 == str4);//ture
		System.out.println(str1 == str2);//false
		//**************************************************
		System.out.println(p1.equals(p2));//false //重新写入equals方法后变成ture
		System.out.println(str1.equals(str2));//ture
		
		Date date1 = new Date(324325L);
		Date date2 = new Date(324325L);
		System.out.println(date1.equals(date2));//ture
		
	}
}
3.toString()
public class GeometricObject {
	protected String  color;
	protected double weight;
	public GeometricObject() {
		super();
		this.color = "white";
		this.weight = 1.0;
	}
	public GeometricObject(String color, double weight) {
		super();
		this.color = color;
		this.weight = weight;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public double getWeight() {
		return weight;
	}
	public void setWeight(double weight) {
		this.weight = weight;
	}
}
//
public class Circle extends GeometricObject{
	private double radius;

	public Circle() {
		super();
		this.radius = 1.0;
//		this.color = "white";
//		this.weight = 1.0;
		//父类已经定义
	}

	public Circle(double radius) {
		super();
		this.radius = radius;
	}
	
	public Circle(double radius,String color,double weight) {
		super(color,weight);
		this.radius = radius;
	}
	
	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}
	
	//求面积
	public double findArea() {
		return 3.14 * radius * radius;
	}
	//比较两个圆的半径是否相等,相等返回ture
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj instanceof Circle) {
			Circle c = (Circle)obj;
			return this.radius == c.radius;
		}
		return false;
	}
	//默认的方法,在调用对象时默认调用使得实例化对象和String类型一样可以直接输出值
	@Override
	public String toString() {
		return "Circle [radius=" + radius + "]";
	}
}
//
public class CircleTest {
	public static void main(String[] args) {
		
		Circle circle1 = new Circle(2.3);
		Circle circle2 = new Circle(2.3,"white",2.0);
		
		System.out.println("颜色是否相等" + circle1.getColor().equals(circle2.getColor()));
		
		System.out.println("半径是否相等" + circle1.equals(circle2));
		
		System.out.println(circle1);
		System.out.println(circle2.toString());
		
	}
}

2.包装类(Wrapper)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DdhrAba0-1602930317585)(/image-20201009200817162.png)]

1.为了使基本数据类型的变量具有类的特征,引入包装类。

//案例
import org.junit.Test;

/*
 * 1.Java提供了巴中基本数据类型的包装类
 * 2.掌握的,基本数据类型、包装类、String三者之间的相互转换
 */
public class WrapperTest {
	/*
	 * JDK5.0新特性,自动装箱和自动拆箱
	 */
	@Test
	public void test3() {
		int num1 = 10;
		//基本数据类型-->包装类的对象
		method(num1);
		
		//自动装箱
		int num2 = 10;
		Integer in1 = num2;//自动装箱
		
		boolean b1 = true;
		Boolean b2 = b1;//自动装箱
		
		//自动装箱
		System.out.println(in1.toString());
		
		int num3 = in1;//自动装箱
		
	}
	public void method(Object obj) {
		System.out.println(obj);
	}
	
	//包装类转化为基本数据类型	调用包装类Xxx的xxxValue();
	@Test
	public void test2() {
		Integer in1 = new Integer(12);
		int i1 = in1.intValue();
		System.out.println(i1 + 1);
		
		Float f1 = new Float(12.3);
		float f2 = f1.floatValue();
		System.out.println(f2 + 1);
	}
	//基本数据类型--->包装类
	@SuppressWarnings("deprecation")
	@Test
	public void test1() {
		int num1 = 10;
		
		Integer in1 = new Integer(num1);
		System.out.println(in1.toString());
		
		
		Integer in2 = new Integer("123");
		
		//异常
//		Integer in3 = new Integer("123abc");
//		System.out.println(in3.toString());
		
		Float f1 = new Float(12.3f);
		Float f2 = new Float("12.3");
		System.out.println(f1);
		System.out.println(f2);
		
		boolean b1 = new Boolean(true);
		boolean b2 = new Boolean("true");
		boolean b3 = new Boolean("true123");
		System.out.println(b3);
		
		Order order = new Order();
		System.out.println(order.isMale);//false
		System.out.println(order.isFamle);//null
	}		
}
class Order{
	boolean isMale;
	Boolean isFamle;
}

2.基本数据类型包装类和String的相互转换

{
//String类型--->转化为基本数据类型、包装类
	@Test
	public void test5() {
		
		String str1 = "123";
		//可能会报NumberFormatException
		int num2 = Integer.parseInt(str1);
		System.out.println(num2 + 1);
		
		String str2 = "true";
		boolean b1 = Boolean.parseBoolean(str2);
		System.out.println(b1);
	}
	//基本数据类型、包装类--->String类型
	@Test
	public void test4() {
		int num1 = 10;
		//方式1
		String str1 = num1 + "";
		//方式2
		float f1 = 12.3f;
		String str2 = String.valueOf(f1);
		System.out.println(str2);//12.3
		
		Double d1 = new Double(12.4);
		String str3 = String.valueOf(d1);
		System.out.println(str3);//12.4
	}
}
//案例
import org.junit.Test;
/*
 * 关于包装类的案例题
 */
public class InterviewTest {
	@Test
	public void test1() {
		Object o1 = true ? new Integer(1) : new Double(2.0);
		System.out.println(o1);//1.0  三元运算符两个选项的数据类型应该相同,这里数据类型提升
	}
	@Test
	public void test2() {
		Object o2;
		if(true) {
			o2 = new Integer(1);
		}else {
			o2 = new Double(2.0);
		}
		System.out.println(o2);//1
	}
	@Test
	public void test3() {
		Integer i = new Integer(1);
		Integer j = new Integer(1);
		System.out.println(i == j);//false
		
		//Integer内部定义了一个IntegerCache结构,里面定义了一个Integer[],
		//保存了一个-128~127范围的整数,如果我们使用自动装箱的方式,给Integer赋值的范围在
		//-127~128范围内时,可以直接使用数组中的元素,不用在去new了,提高效率
		
		Integer m = 1;
		Integer n = 1;
		System.out.println(m == n);//true 
		
		//超出127时则是new的新的对象,比较的是地址值
		Integer x = 128;
		Integer y = 128;
		System.out.println(x == y);//false 
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HJlk0Yzs-1602930317587)(/image-20201009201121473.png)]

//案例


import java.util.Scanner;
import java.util.Vector;

public class ScoreTest {
	public static void main(String[] args) {
		//1.实例化Scanner,获取学生成绩
		Scanner scan = new Scanner(System.in);
		//2.实例化Vector对象,Vector v = new Vector(),相当于数组
		Vector v = new Vector();
		//3.通过for(;;)或while(ture)方式,
		
		int maxScore = 0;
		for(;;) {
			System.out.println("请输入学生成绩。输入负数时结束");
			int score = scan.nextInt();
			//3.2输入负数时跳出循环
			if(score <= 0) {
				break;
			}
			if(score > 100) {
				System.out.println("输入的数据非法,请重新输入");
			}
			
			//3.1给Vector添加数据,v.addElement(Object obj)
			//jdk5.0之前
//			Integer inScore = new Integer(score);
//			v.addElement(inScore);//多态
			//jdk5.0之后
			v.addElement(score);//自动装箱
			
			//4.获取成绩最大值
			if(maxScore < score) {
				maxScore = score;
			}
		}
		//5.遍历Vector得到每个学生的成绩,并与最大成绩比较,得到学生登记
		char level;
		for(int i = 0;i < v.size();i++) {
			Object obj = v.elementAt(i);
			//jdk5.0之前
//			Integer inScore = (Integer)obj;
//			int score = inScore.intValue();
			//jdk5.0之后
			int score = (int)obj;
			if(maxScore - score <= 10) {
				level = 'A';
			}else if(maxScore - score <= 20) {
				level = 'B';
			}else if(maxScore - score <= 30) {
				level = 'C';
			}else{
				level = 'D';
			}
			System.out.println("student" + i + ",score is" + score + ",level is" + level);
		}
	}
}

3.抽象类

abstract关键字
1.abstract:抽象的
2.abstract可以用来修饰的结构:类、方法

3.abstract修饰类:抽象类
此类不能实例化,
抽象类中仍然提供构造器,便于子类实例化时候调用(设计子类对象实例化的全过程)
开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作

4.abstract修饰方法:修饰方法
抽象方法只有方法的声明,没有方法体
包含抽象方法的类,一定是一个抽象类,反之,抽象类中可以没有抽象方法
若子类重写了父类中的所有的抽象方法后,则子类方可实例化
5.abstract使用上的注意点
1.abstract不能用来修饰:属性,构造器等结构
2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类

public class AbstractTest {
	public static void main(String[] args) {
		//Person p1 = new Person();//报错Cannot instantiate the type Person
		
	}
}

abstract class CreateTure{
	abstract public void breath();
}

abstract class Person extends CreateTure{
	String name;
	int age;
	
	public Person() {
		
	}
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public void eat() {
		System.out.println("人吃饭");
	}
	//抽象方法
	public abstract void eat1();
	
	public void walk() {
		System.out.println("人走路");
	}
	
}

class Student extends Person{

	public Student(String name,int age) {
		super(name,age);
	}
	
	@Override
	public void eat1() {
		// TODO Auto-generated method stub
		System.out.println("学生多吃实物");
	}

	//重写间接父类的抽象方法
	@Override
	public void breath() {
		// TODO Auto-generated method stub
		System.out.println("学生多呼吸新鲜空气");
	}
	
}
/*
 * 抽象类的匿名子类对象
 * 
 */
public class PersonTest {
	public static void main(String[] args) {
		
		method(new Student());
		
		Worker worker = new Worker();
		method1(worker);//非匿名的类非匿名对象
		
		method1(new Worker());//非匿名的类匿名对象
		
		System.out.println("---------------------------------------");
		//抽象类的匿名子类对象
		Person p = new Person() {

			@Override
			public void eat1() {
				// TODO Auto-generated method stub
				System.out.println("吃东西");
			}

			@Override
			public void breath() {
				// TODO Auto-generated method stub
				System.out.println("呼吸");
			}
			
		};
		
		method1(p);
		System.out.println("---------------------------------------");
		//创建匿名子类的匿名对象
		method1(new Person() {

			@Override
			public void eat1() {
				// TODO Auto-generated method stub
				System.out.println("好好吃饭");
			}

			@Override
			public void breath() {
				// TODO Auto-generated method stub
				System.out.println("好好呼吸");
			}
			
		});
	}
	
	public static void method1(Person p) {
		p.eat1();
		p.breath();
	}
	
	public static void method(Student s) {
		
	}
}

class Worker extends Person{

	@Override
	public void eat1() {
		// TODO Auto-generated method stub
		System.out.println("worker吃东西");
	}

	@Override
	public void breath() {
		// TODO Auto-generated method stub
		System.out.println("worker呼吸");
	}
}

4.代码块(类的成员)

类的成员,代码块(初始化块)

1.代码块的作用:用来初始化类、对象
2.代码块如果有修饰的话,只能使用static
3.分类:静态代码块、非静态代码块
4.静态代码块
内部可以有输出语句
随着类的加载而执行
作用,初始化属性的值
如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
静态代码块的执行要优于非静态的代码块
只能调用静态的属性和静态的方法,不能调用非静态的结构

5.非静态代码块
内部可以有输出语句
随着对象的创建而执行
每创建一个对象执行一次非静态代码块
作用:可以在创建对象时对对象的属性进行初始化
如果一个类中定义了多个非静态的代码块,则按照声明的先后顺序执行
可以调用静态的属性和静态的方法,也可以调用非静态的属性和非静态的方法

对属性赋值的位置
①默认初始化
②显示初始化
③构造器中初始化
④有了对象以后可以通过对象调用属性来赋值
⑤在代码块中赋值

public class BlockTest {
	public static void main(String[] args) {
		String desc = Person.desc;
		
		Person p1 = new Person();
		Person p2 = new Person();
		
		System.out.println(desc);
		
		Person.info();
		p1.info();
	}
}

class Person{
	
	String name;
	int age;
	static String desc = "我是一个人";
	
	public Person() {
		super();
	}
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	//静态代码块
	static{
		System.out.println("Hello,static,block11");
		desc = "我是一个爱学习的人1";
	}
	static{
		System.out.println("Hello,static,block22");
		desc = "我是一个爱学习的人2";
	}
	//非静态代码块
	{
		System.out.println("Hello,block");
		//调用非静态结构
		age = 1;
		eat();
		//调用静态结构
		desc = "调用静态结构";
		info();
	}

	public void eat() {
		System.out.println("吃饭");
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
	public static void info() {
		System.out.println("我是一个静态方法");
	}
}

5.接口

接口的使用
1.接口使用interface来定义
2.Java中,接口和类时并列的两个结构
3.如何定义接口,定义接口中的成员
3.1jdk7以前,只能定义全局常量和抽象方法
全局常量:public static final,书写时可以省略
抽象方法:public abstract

	3.2jdk:除了定义全局常量和抽象方法外,还可以定义静态方法,默认方法

4.接口中不能定义构造器,意味着接口不可以实例化

5.Java开发中,接口都通过让类去实现(implements)的方式来使用

6.java类了以实现多个接口----->弥补了Java单继承性的局限性
格式:class AA entends BB implements CC,DD,EE{
}

7.接口与接口之间是可以继承的,并且可以多继承

8.接口的具体使用,是多态性
9.接口,实际上可以看做是一种规范

面试题:抽象类和接口有哪些共同点和区别?
相同点:不能实例化,都可以被继承,都可以包含抽象方法
不同点:抽象类:有构造器 单继承
接口:不能声明构造器 多继承
类和接口:多实现

public class IntetfaceTest {
	
}

interface Flyable{
	//全局常量
	public static final int MAX_SPEED = 7900;//第一宇宙速度
	int MIN_SPEED = 1;//书写时可以省略修饰符
	
	//抽象方法
	public abstract void fly();
	
	void stop();//省略修饰符
	
}

interface Attackable{
	
	void attack();
	
}

class Plane implements Flyable{

	@Override
	public void fly() {
		System.out.println("起飞");
	}

	@Override
	//implements interfacetest.Flyable.stop
	public void stop() {
		System.out.println("降落");
	}
	
}

abstract class Kite implements Flyable{
	
	public void fly() {
		
	}
}
//先继承然后在实现接口
class Bullet extends Object implements Flyable,Attackable,CC{

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void attack() {
		// TODO Auto-generated method stub
		
	}
	
	//******************************************************
	
	@Override
	public void aa() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void bb() {
		// TODO Auto-generated method stub
		
	}
	
}
//**********************************************************

interface AA{
	void aa();
}

interface BB{
	void bb();
}

interface CC extends AA,BB{
	
}
/*
 * 接口的使用
 * 
 */
public class InterfaceTest2 {
	public static void main(String[] args) {
		Computer com = new Computer();
		//1.创建了接口的非匿名实现类的非匿名对象
		Flash flash = new Flash();
		com.transferData(flash);
		System.out.println("------------------------------------");
		//2.创建接口的非匿名实现类的匿名对象
		com.transferData(new Printer());
		System.out.println("------------------------------------");
		//3.创建了接口的匿名实现类的非匿名对象
		USB phone = new USB() {

			@Override
			public void start() {
				System.out.println("手机开始工作");
			}

			@Override
			public void stop() {
				System.out.println("手机结束工作");
			}
			
		};
		com.transferData(phone);
		System.out.println("------------------------------------");
		//4.创建了接口的匿名实现类的匿名对象
		com.transferData(new USB() {

			@Override
			public void start() {
				System.out.println("mp3开始工作");
			}

			@Override
			public void stop() {
				System.out.println("mp3停止工作");
			}
			
		});
	}
}

class Computer{
	
	public void transferData(USB usb) {
		usb.start();
		
		System.out.println("具体的传输数据的细节");
		
		usb.stop();
	}
}

interface USB{
	
	void start();
	
	void stop();
}

class Flash implements USB{

	@Override
	public void start() {
		// TODO Auto-generated method stub
		System.out.println("Flash开始");
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		System.out.println("Flash停止");
	}
	
}

class Printer implements USB{

	@Override
	public void start() {
		// TODO Auto-generated method stub
		System.out.println("Printer开始");
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		System.out.println("Printer停止");
	}
	
}
//案例 
interface A{
	int x = 0;//全局常量
}

class B{
	int x = 1;
}

class C extends B implements A {
	public void pX(){
		//System.out.println(x);报错,x不明确
		System.out.println(super.x);//1
		System.out.println(A.x);//0
	}

	public static void main(String[] args){
		new C().pX();
	}
}
//案例Java8,除了定义全局常量和抽象方法之外还可以定义静态方法,默认方法
public class Test3Test {
	public static void main(String[] args) {
		SubClass s = new SubClass();
		
		//s.method1();The method method1() is undefined for the type SubClass
		//1.接口中定义的静态方法,只能通过接口来调用
		InterfaceTest3.method1();
		//2.通过实现类的对象,可以调用接口中的默认方法
		//如果实现类重写了接口的方法,仍然调用重写以后的方法
		s.method2();
		//3.如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法
		//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法-----类优先原则
		s.method3();
		//4.在实现类没有重写此方法的情况下,报错----接口冲突
		//这就需要我们在实现类中重写此方法
		
	}
}

class SubClass extends SuperClass implements InterfaceTest3,InterfaceTest4{
	
	public void method2() {
		System.out.println("默认方法重写");
	}
	
	public void method3() {
		System.out.println("实现类重写的方法");
	}
	
	public void myMethod() {
		method3();
		super.method3();
		//调用接口中的默认方法
		InterfaceTest3.super.method3();
		InterfaceTest4.super.method3();
	}
	
}

class SuperClass{
	
	public void method3() {
		System.out.println("父类同名默认方法");
	}
}
/*
 * 
 * Java8,除了定义全局常量和抽象方法之外还可以定义静态方法,默认方法
 * 
 * Java9可以定义私有的方法
 * 
 */
public interface InterfaceTest3 {
	
	public static void method1() {
		System.out.println("静态方法");
	}
	
	public default void method2() {
		System.out.println("默认方法");
	}
	
	default void method3() {
		System.out.println("默认方法");
	}
}
public interface InterfaceTest4 {
	
	public static void method1() {
		System.out.println("静态方法");
	}
	
	public default void method2() {
		System.out.println("默认方法");
	}
	
	default void method3() {
		System.out.println("默认方法");
	}
}

6.内部类

类的内部成员,内部类
1.Java中允许将一个类A声明在另一个类B中,则A类是内部类,类B称为外部类
2.内部类的分类:成员内部类(静态、非静态)和局部内部类(方法内、代码块内、构造器内)
3.成员内部类:
一方面,作为外部类的成员
可以调用外部类的结构
可以用static修饰
可以被四种不同的权限修饰
另一方面,作为一个类
类内可以定义属性、方法、构造器等
可以用final修饰,表示此类不能被继承,言外之意,不使用final则可以被继承
可以用abstract修饰,表示类不能被实例化

4.关注3个问题
1.如何实例化成员内部类的对象
2.如何在成员内部类中区分调用外部类的结构
3.开发中局部内部类的使用

public class InnerClassTest {
	public static void main(String[] args) {
		//创建Bird实例(静态成员内部类)
		Person.Bird bird = new Person.Bird();
		bird.zhizhi();
		
		//创建Dog实例(非静态成员内部类)
		Person p = new Person();
		Person.Dog dog = p.new Dog();
		dog.shout();
		
		
	}
}

class Person{
	
	
	String name;
	
	
	public void eat() {
		System.out.println("人吃饭");
	}
	//非静态成员内部类
	class Dog{
		String name;
		
		public Dog() {
			
		}
		
		public void shout() {
			System.out.println("狗叫");
			Person.this.eat();//调用外部类的属性
		}
		
		public void display(String name) {
			System.out.println(name);//方法形参
			System.out.println(this.name);//内部类的属性
			System.out.println(Person.this.name);//外部类的属性
		}
	}
	//静态内部类
	static class Bird{
		String name;
		
		public Bird() {
			
		}
		
		public void zhizhi() {
			System.out.println("鸟在叫");
		}
	}
	
	public void method() {
		//局部内部类
		class AA{
			
		}
	}
	
	{
		class BB{
			
		}
	}
	
}
//
public class InnerClassTest1 {
	
	//开发中很少见
	public void method() {
		//局部内部类
		class AA{
			
		}
	}
	
	//返回一个实现了Comparable接口的类的对象
	public Comparable getComparable () {
		
		//创建一个实现了Comparable接口的类
		//方式1
//		class MyComparable implements Comparable{
//			
//			public int compareTo(Object o) {
//				return 0;
//			}
//		}
//		
//		return new MyComparable();
		
		//方式2
		return new Comparable() {
			
			public int compareTo(Object o) {
				return 0;
			}
		};
		
	}
	
}

7.数组

1.数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,通过编号的方式对这些数据进行统一管理。
2.数组的常见概念
数组名
下标(索引)
元素
数组的长度
3.数组的特点:
①数组是有序排列的
②数组属于引用数据类型
③数组的元素,既可以是基本数据类型,也可以是引用数据类型
④数组对象会在内存中开辟一段连续的空间
⑤数组的长度一旦确定,不可修改
4.数组的分类
按照维数:一维数组,二维数组…
按照数组元素类型:基本数据类型元素的数组,引用数据类型元素的数组
5.一维数组的使用
①一维数组的声明和初始化
②如何调用数组的指定位置的元素
③如何获取数组的长度
④如何遍历数组的元素
⑤数组元素的默认初始化值
⑥数组的内存解析

案例//
{
    //①一维数组的声明和初始化
    int num;//声明
    num = 10;//初始化

    int[] ids;
    //静态初始化:数组的初始化和数组元素的赋值操作同时进行
    ids = new int[]{1001,1002,1003,1004};
    //动态初始化:数组的初始化和数组元素的赋值操作分开进行
    String[] names = new String[5];

    //②如何调用数组的指定位置的元素:通过下标的方式调用
    //数组的脚标从0开始,到数组的长度-1
    names[0] = "张三1";
    names[1] = "张三2";
    names[2] = "张三3";
    names[3] = "张三4";
    names[4] = "张三5";

    //③如何获取数组的长度
    System.out.println(names.length);

    //④如何遍历数组的元素
    for(int i = 0;i < names.length;i++){
        System.out.println(names[i]);
    }

    //⑤数组元素的默认初始化值
    //整型:0
    //浮点型:0.0
    //char类型:字符集为0对应的字符,输出空字符" ",可以用分支语句和0判断相等
    //boolean类型:false(0)
    //数组元素类型是引用数据类型:null
    int[] arr = new int[4];
    for(int i = 0;i < arr.length;i++){
        System.out.println(arr[i]);
    }//输出0000
    char[] arr1 = new char[4];
    System.out.println(arr1[0]);//" "空字符
    if(arr1[0] == 0){
        System.out.println("可以判定,并输出");
    }
    String[] arr2 = new String[4];
    System.out.println(arr2[0]);//输出null
    if(arr2[0] == null){
        System.out.println("可以判定,并输出");
    }
}

⑥一维数组的内存解析(在JVM中体现)主要部分如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v69W2hTu-1602930317590)(/image-20201011163011879.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2yfCOcNy-1602930317591)(/image-20201011163023402.png)]

System.out.println(arr1[1]);//输出null

//案例
//输入五个同学成绩找出最高分,并判断ABCD
import java.util.Scanner;
{
    //使用Scanner,读取学生个数
    Scanner scanner = new Scanner(System.in);//ctrl + shift + o
    System.out.println("输入学生人数");
    int number = scanner.nextInt();
    //创建数组,存储成绩
    int[] scores = new int[number];
    //遍历数组并赋值
    System.out.println("请输入" + number "个成绩");
    for(int i = 0;i < scores.length;i++){
            scores[i] = scanner.nextInt();
    }
    //获取最大值
    int maxScores = 0;
    for(int i = 0;i < scores.length;i++){
            if(maxScores < scores[i]){
                maxScores = scores[i];
            }
    }
    //判断每个学生和最高分的差值,得到等级并输出
    char level;
    for(int i = 0;i < scores.length;i++){
            if(maxScore - scores[i] <= 10){
                level = 'A';
            }else if(maxScore - scores[i] <= 20){
                level = 'B';
            }else if(maxScore - scores[i] <= 30){
                level = 'C';
            }else{
                level = 'D';
            }
            System.out.println("student" + i + "scores" + scores[i] + "level" + level);
    }
}

6.多维数组的使用
多维数组可以看做是数组的嵌套使用,一个数组作为另一个数组的元素出现
①二维数组的声明和初始化
②如何调用数组的指定位置的元素
③如何获取数组的长度
④如何遍历数组的元素
⑤数组元素的默认初始化值
⑥数组的内存解析

//案例
{
    //①二维数组的声明和初始化
    //静态初始化
    int [] arr = new int[]{1,2,3};//一维数组
    int [] arrs ={1,2,3};//类型推断
    int [][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
    //动态初始化
    String[][] arr2 = new String[3][2];//外围数组中的每个元素含有具有两个元素的数组
    String[][] arr3 = new String[3][];
    String[] arr4[] = new String[3][];
    //②如何调用数组的指定位置的元素
    System.out.println(arr1[0][1]);//2
    //arr3[1] = new String[4];给外层数组第二个区域写入四个空间,下一行则正常运行
    System.out.println(arr3[1][0]);//报错空指针异常,数组arr3的内层数组没有开辟空间
    //③如何获取数组的长度
    //int [][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
    System.out.println(arr1.length);//3
    System.out.println(arr1[1].length);//2
    //④如何遍历数组的元素
    for(int i = 0;i < arr1.length;i++){
            for(int j = 0;j < arr1[i].length;j++){
                System.out.println(arr1[i][j]);
            }
    }
    //⑤数组元素的默认初始化值
    int[][] arr5 = new int[4][3];
    //外层元素初始化值:地址值
    //内层元素初始化值:与一维数组情况相同
    System.out.println(arr[0]);//输出其地址值
    System.out.println(arr[0][0]);//0
    System.out.println(arr);//输出外层数组
    double[][] arr6 = new double[4][];
    //外层元素初始化值:null
    //内层元素初始化值:不能调用,报错空指针
    System.out.println(arr6[1]);//null
    //System.out.println(arr6[1][0]);//报错空指针异常
}

⑥多维数组的内存解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lbeY6SaN-1602930317592)(/image-20201011163153250.png)]

//案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vEmKq8pO-1602930317593)(/image-20201011163211027.png)]

//获取数组中所有元素的和
{
int[][] arr = new int[][]{{3,5,8},{12,9},{7,0,6,4}};
int num = 0;
for(int i = 0;i < arr.length;i++){
		for(int j = 0;j < arr[i].length;j++){
			num += arr[i][j];
		}
}
System.out.println(num);
}
1.杨辉三角
//案例 使用二维数组打印一个10行的杨辉三角
//提示:每一行有第n行n个元素,第一个元素和最后一个元素都为1
//从第三行开始,对于非第一个元素和最后一个元素
//yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
{
    int[][] yangHui = new int[10][];

    for(int i = 0;i < yangHui.length;i++){
            yangHui[i] = new int[i + 1];
            yangHui[i][0] = yangHui[i][i] = 1;
            if(i > 1){
                for(int j = 1;j < yangHui[i].length - 1;i++){
                    yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
                }
            }
    }
    for(int i = 0;i < yangHui.length;i++){
            for(int j = 0;j < yangHui[i].length;j++){
                System.out.print(yangHui[i][j] + " ");
            }
    }
}
2.生成不相同的随机数
//案例
//创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,要求各值都不相同
{
    int[] nums = new int[6];
    int dest = 0;
    loop:for(int i = 0;i < 6;i++){
            dest = Math.floor(Math.random() * 31);
            if(i == 0){
                nums[i] = dest;
            }else{
                for(int j = 0;j < i;j++){
                    if(dest == nums[j]){
                        i = i-1;
                        continue loop;
                    }else{
                        nums[i] = dest;
                    }
                }
            }
    }
    for(int i = 0;i < 6;i++){
            System.out.print(nums[i]);
    }
}
3.回形数
//n = 4  
//1  2  3  4 
//12 13 14 5 
//11 16 15 6
//10 9  8  7 
//案例
{
	int n = 4;
	int m = 0;
	int[][] arr = new int[n][n]; 
	int maxX = n;//n - 1
	int minX = -1;
	int maxY = n - 1;
	int minY = 0;
	while(minX <= maxX){
			for(int i = 0; i < maxX; i++){
				arr[minY][++minX] = ++m;
			}
			maxX--;
			for(int i = 0; i < maxY; i++){
				arr[++minY][minX] = ++m;
			}
			maxY--;
			for(int i = 0; i < maxX; i++){
				arr[minY][--minX] = ++m;
			}
			maxX--;
			for(int i = 0; i < maxY; i++){
				arr[--minY][minX] = ++m;
			}
			maxY--;
	}
	for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
	}
}
4.求数组中元素的最大值,最小值,平均数,总和
//案例
{
	int[] arr = new int[10];
	for(int i = 0;i < arr.length;i++){
		arr[i] = (int)(Math.random()*(99-10+1)+10);
	}
	//求最大值
	int maxValue = arr[0];
	for(int i = 0;i < arr.length;i++){
		if(maxValue < arr[i]){
			maxValue = arr[i];
		}
	}
	//最小值
	int minValue = arr[0];
	for(int i = 0;i < arr.length;i++){
		if(minValue > arr[i]){
			minValue = arr[i];
		}
	}
	//总和
	int allValue = 0;
	for(int i = 0;i < arr.length;i++){
		allValue += arr[i];
	}
	//平均值
	int avgValue = allValue / arr.length;
}
5.使用简单数组
//案例
//创建一个类,声明array1和array2两个int[]数组
//用大括号吧array1初始化8个素数:2,3,5,7,11,13,17,19
//显示arra1的内容
//赋值array2等于array1,修改array2中的偶索引元素,使其等于索引值(array[0] = 0),打印array1
//array1和array2的关系:array2就像是array1的快捷方式,他们拥有相同的地址
{
	int[] = array1,array2;
	array1 = new int[]{2,3,5,7,11,13,17,19};
	for(int i = 0;i < array1.length;i++){
		System.out.print(array1[i] + " ");
	}
	array2 = array1;//不是数组的复制,是吧array1的地址赋给array2
	for(int i = 0;i < array2.length;i++){
		if(i % 2 == 0){
			//因为array1的地址赋值给array,更改array2就等于更改array1
			array2[i] = i;
		}
	}
	for(int i = 0;i < array1.length;i++){
		System.out.print(array1[i] + " ");
	}//打印出来和array2更改一样
}
6.数组的复制,反转,查找(线性查找,二分法查找)
{
	String[] arr = new String[]{"aa","bb","cc","dd"};
	//复制
	String[] arr1 = new String[arr.length];
	for(int i = 0;i < arr1.length;i++){
		arr1[i] = arr[i];
	}
	//反转
	//方法1
	for(int i = 0;i < arr.length / 2;i++){
		String temp = arr[i];
		arr[i] = arr[arr.length - i - 1];
		arr[arr.length - i - 1] = temp;
	}
	//方法2
	for(int i = 0,j = arr.length - 1;i < j; i++,j--){
		String temp = arr[i];
		arr[i] = arr[j];
		arr[j] = trmp;
	}
}
7.查找
//案例 线性查找
{
	String[] arr = new String[]{"aa","bb","cc","dd"};
	String dest = "bb";
	boolean ifFlag = true;
	for(int i = 0;i < arr.length;i++){
		if(dest.equals(arr[i])){
			System.out.println(i);
			ifFlag = false;
			break;
		}
	}
	if(isFlag){
		System.out.println("没有相同的内容");
	}
}
//案例 二分法查找
//前提:所要查找的数组必须有序
{
	int[] arr = new int[]{-99,-45,2,8,10,,24,48,54};
	int dest = 24;
	int head = 0;
	int end = arr.length - 1;
	boolean isFlag = true;
	while(head <= end ){
		int middle = (head + end) / 2;
		if(dest == arr[middle]){
			System.out.println(middle);
			isFlag = false;
			break;
		}else if(arr[middle] > dest){
			end = middle - 1;
		}else{
			end = middle + 1;
		}
	}
	if(isFlag){
		System.out.println("没有相同的内容");
	}	
}
8.排序
①选择排序:直接选择排序,堆排序√
②交换排序:冒泡排序√,快速排序√
③插入排序:直接插入排序,折半插入排序,Shell排序
④归并排序√
⑤桶式排序
⑥基数排序
//案例①冒泡排序
{
	int[] arr = new int[]{8,9,1,5,-10,48,55,4,20};
	int dest = 0; 
	for(int i = 0;i < arr.length - 1;i++){
		for(int j = 0;j < arr.length - 1 - i;j++){
			if(arr[j] > arr[j+1]){
				dest = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = dest;
			}
		}
	}
	for(int i = 0;i < arr.length;i++) {
		System.out.print(arr[i] + " ");
	}
}
{
	boolean isFlag = true;
	int[] arr = new int[]{8,9,1,5,-10,48,55,4,20};
	int dest = 0; 
	for(int i = 0;i < arr.length - 1 && isFlag == true;i++){
		isFlag = false;
		for(int j = 0;j < arr.length - 1 - i;j++){
			if(arr[j] > arr[j+1]){
				dest = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = dest;
				isFlag = true;
			}
		}
	}
	for(int i = 0;i < arr.length;i++) {
		System.out.print(arr[i] + " ");
	}
}
9.arrays工具类
①boolean eauals(int[] a,int[] b); 比较数组是否相等
//案例
{
	//①boolean eauals(int[] a,int[] b); 比较数组是否相等
	int[] arr1 = new int[]{1,2,3,4};
	int[] arr2 = new int[]{1,4,2,3};
	boolean isEquals = Arrays.equals(arr1,arr2);
	System.out.println(isEquals);
	//②String toString(int[] a);输出数组信息
	System.out.println(Arrays.toString(arr1));
	//③void fill(int[] a,int val);将指定值填充到数组之中
	Arrays.fill(arr1,10);
	System.out.println(Arrays.toString(arr1));
	//④void sort(int[] a);对数组进行排序
	Arrays.sort(arr2);
	System.out.println(Arrays.toString(arr2));
	//⑤int binarySearch(int[] a,int key)二分查找
	int[] arr3 = new int[]{8,9,1,5,-10,48,55,4,20};
	int index = Arrays.binarySearch(arr3, 4);
	System.out.println(index);//没找到时返回一个负数
}
10.说明
①如何判断算法的优劣:时间复杂度、空间复杂度、稳定性
②排序的分类:内部排序,外部排序(借助磁盘)
<1.理解
①定义在java.util.Arrays包下
②Arrays提供了很多操作数组的方法
<2.数组的常见异常
①数组的角标越界异常:ArrayIndexOutOfBoundsExcetion
②空指针异常:NullPointerException
情况一:给数组赋值null,覆盖地址
情况二:未赋值,未开辟内存空间输出则报错空指针

设计模式

1.Javabean的使用

1.JavaBean是一种Java语言写成的可重用组件
2.符合标准:①类是公共的 ②有一个无参的公共构造器 ③有属性,且有对应的get、set方法

//案例
public class Customer{
	private int id;
	private String name;
	//空参构造器,可通过反射制造对象
	public Customer(){

	}
	public void setId(int i){
		id = i;
	}
	public int getId(){
		return id;
	}
	public void setName(String n){
		id = n;
	}
	public int getName(){
		return name;
	}
}

2.MVC设计模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nCU86ehz-1602930317594)(/image-20201009115518572.png)]

3.单例(Singleton)设计模式

单例设计模式
1.所谓类的单例设计模式,就是采用一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例
2.如何实现?
3.区分饿汉式和懒汉式
饿汉式:坏处,对象加载时间过长
好处,线程安全的
懒汉式:好处,延迟对象的创建
坏处,线程不安全—>可以通过修改提升安全性
4.单例模式的优点
由于单例模式只生成一个实例,减少了系统性能的开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时产生一个单例对象,然后永久驻留内存的方法来解决

public class SingletonTest1 {
	public static void main(String[] args) {
		
		Bank bank1 = Bank.getInstance();
		Bank bank2 = Bank.getInstance();
		//单例的饿汉式实现
		System.out.println(bank1 == bank2);
	}
}

class Bank{
	
	//1.私有化类的构造器
	private Bank() {
		
	}
	
	//2.内部创建类的对象
	private static Bank instance = new Bank();
	
	//3.提供公共的方法,返回类的对象
	public static Bank getInstance() {
		return instance;
	}
	
	
}
//
public class SingletonTest2 {
	public static void main(String[] args) {
		
		Order order1 = Order.getInstance();
		Order order2 = Order.getInstance();
		//单例的懒汉式实现
		System.out.println(order1 == order2);
	}
}

class Order{
	
	//1.私有化类的构造器
	private Order(){
		
	}
	
	//2.声明当前类对象
	private static Order instance = null;
	
	//3.声明public、static的返当前类对象的方法
	public static Order getInstance() {
		
		if(instance == null) {
			instance = new Order();
			return instance;
		}
		return instance;
	}
}
//单例案例
class Bank{

	private Bank(){

	}
	
	public static final Bank instance = new Bank();//单例模式的第三种写法

}

4.模板方法设计模式

模板方法设计模式(TemplateMethod)多态的使用

/*
 * 抽象了你的应用,模板方法的设计模式
 * 
 */
public class TemplateTest {
	public static void main(String[] args) {
		
		Template t = new SubTemplate();
		
		t.spendTime();
	}
}

abstract class Template{
	
	public void spendTime() {
		
		long start = System.currentTimeMillis();
		
		this.code();//不确定的部分,就是易变的部分  code();
		
		long end = System.currentTimeMillis();
		
		System.out.println("花费的时间为:" + (end - start));
		
	}

	public abstract void code() ;
	
}

class SubTemplate extends Template{

	@Override
	public void code() {
		// TODO Auto-generated method stub
		for(int i = 2;i <= 1000;i++) {
			boolean isFlag = true;
			for(int j = 2;j <= Math.sqrt(i);j++) {
				if(i % j == 0) {
					isFlag = false;
				}
			}
			if(isFlag) {
				System.out.println(i);
			}
		}
	}
	
}

5.代理模式

接口的应用:代理模式(Proxy)

public class NetWorkTest {
	public static void main(String[] args) {
		Server server = new Server();
		ProxyServer pro = new ProxyServer(server);
		
		pro.browse();
	}
}

interface NetWork{
	
	public void browse();
	
}

//被代理类
class Server implements NetWork{

	@Override
	public void browse() {
		System.out.println("真实的服务器访问网络");
	}
	
}

//代理类
class ProxyServer implements NetWork{

	private NetWork work;
	
	public ProxyServer(NetWork work) {
		this.work = work;
	}
	
	public void check() {
		System.out.println("联网之前的检查工作");
	}
	
	@Override
	public void browse() {
		check();
		work.browse();
	}
	
	
}

6.工厂模式

简单工厂模式
工厂方法模式:实现了创建者和调用者的分离
抽象工厂模式

作业

1.案例-日历

//案例 日历方法调用现有的Calendar类中的方法
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;

import javax.imageio.ImageIO;

public class Calendar3 {
	
	private int month;
	private int year;
	private int dayOfWeek;//制表符的个数,判断月份的第一天是星期几
	private int monthOfDay;//输入对应的月份的天数
	
	public Calendar3() {
		
	}

	public int getMonth() {
		return month;
	}

	public boolean setMonth(int month) {
		if(month < 1 || month >12) {
			System.out.println("输入的数字不合法,请重新输入!1~12");
			return true;
		}else {
			this.month = month;
			return false;
		}
	}

	public int getYear() {
		return year;
	}

	public boolean setYear(int year) {
		if(year < 2000) {
			System.out.println("输入的数字不合法,请重新输入!请输入2000年以后的年份");
			return true;
		}else {
			this.year = year;
			return false;
		}
	}
	//输入日历
	public void addCalendar() {
		addTt();
		System.out.println("日\t" + "一\t" + "二\t" + "三\t" + "四\t" + "五\t" + "六\t" );
		int days = 1;
		int line = 0;//代表换行的变量
		for(int i = 0 - dayOfWeek;i < monthOfDay + dayOfWeek;i++ ) {
			if(i < 0) {
				System.out.print("\t");
			}else {
				System.out.print(days++ + "\t");
			}
			line++;
			if(line % 7 == 0) {
				System.out.println();
			}
		}
		System.out.println(dayOfWeek + "  " + monthOfDay);
	}
	//输入制表符的个数 判断输入的月份是星期几
	private void addTt() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, 1);
		//判断输入的天数是周几
		dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		//获取当前月的天数
		monthOfDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}
	//在图片上打印一个月的日期
	public void imageAdd(int monthAdd) throws IOException {
		//在一个图片上打印年份和月份
		//创建类的对象
		BufferedImage image = new BufferedImage(550,550,BufferedImage.TYPE_INT_RGB);
		//获取画笔
		Graphics graphics = image.getGraphics();
		graphics.setColor(Color.black);
		graphics.fillRect(0, 0, 550, 550);
		//修改字体
		Font f = new Font("华文彩云",Font.BOLD,30);
		graphics.setFont(f);
		graphics.setColor(Color.GREEN);
		//写星期几
		int x = 100;
		int y = 100;
		graphics.drawString("一", x, y);
		x += 50;
		graphics.drawString("二", x, y);
		x += 50;
		graphics.drawString("三", x, y);
		x += 50;
		graphics.drawString("四", x, y);
		x += 50;
		graphics.drawString("五", x, y);
		x += 50;
		graphics.drawString("六", x, y);
		x += 50;
		graphics.drawString("七", x, y);
		x += 50;
		
		x = 100;
		y += 50;
		int tt = dayOfWeek;
		for(int i = 0;i < tt;i++) {
			graphics.drawString(" ", x, y);
			x += 50;
		}
		for(int j = 1;j < monthOfDay;j++) {
			graphics.drawString(String.valueOf(j) , x, y);
			x += 50;
			if((tt + j) % 7 == 0) {
				System.out.println();
				x = 100;
				y += 50;
			}
		}
		ImageIO.write(image, "jpg", new File("image.jpg"));
	}
}
//
import java.io.IOException;
import java.util.Scanner;

public class CalendarTest {
	public static void main(String[] args) throws IOException {
		
		Calendar3 cal = new Calendar3();
		
		@SuppressWarnings("resource")
		Scanner input = new Scanner(System.in);
		int months;//输入的月
		int years = 0;//输入的年
		boolean isFlag = true;
		
		while(isFlag) {
			System.out.println("请输入年份");
			years = input.nextInt();
			isFlag =  cal.setYear(years);
		}
		
		//打印年份和月份
		for(months = 1;months <= 12;months++) {
			//写入年份和月份
			cal.setMonth(months);
			System.out.println(years + " 年  " + months + " 月  ");
			cal.addCalendar();
			System.out.println();
			System.out.println("**************************************************");
		}
		
		System.out.println("你要在图片上打印今年的几月?1~12");
		System.out.println("请输入月份");
		int monthAdd = input.nextInt();
		cal.imageAdd(monthAdd);
		
	}
}
//案例日历方法自己编写
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Calendar2 {
	
	private int month;
	private int year;
	private int tt;//制表符的个数,判断月份的第一天是星期几
	private int addMonth;//输入对应的月份的天数
	
	public Calendar2() {
		
	}

	public int getMonth() {
		return month;
	}

	public boolean setMonth(int month) {
		if(month < 1 || month >12) {
			System.out.println("输入的数字不合法,请重新输入!1~12");
			return true;
		}else {
			this.month = month;
			return false;
		}
	}

	public int getYear() {
		return year;
	}

	public boolean setYear(int year) {
		if(year < 2000) {
			System.out.println("输入的数字不合法,请重新输入!请输入2000年以后的年份");
			return true;
		}else {
			this.year = year;
			return false;
		}
	}
	//输入日历
	public void addCalendar() {
		addMonth = monthDay(month);
		tt = addTt();
		System.out.println("一\t" + "二\t" + "三\t" + "四\t" + "五\t" + "六\t" + "七\t");
		int days = 1;
		int line = 0;//代表换行的变量
		for(int i = 0 - tt;i < addMonth;i++ ) {
			if(i < 0) {
				System.out.print("\t");
			}else {
				System.out.print(days++ + "\t");
			}
			line++;
			if(line % 7 == 0) {
				System.out.println();
			}
		}
	}
	//输入制表符的个数 判断输入的月份是星期几
	private int addTt() {
		int monthNumber = 0;//保存当年月的天数
		int yearNumber = 0;//保存当年距离2000年的天数
		//计算输入的日期到2000年1月1日有多少天
		for(int i = 2000;i < year;i++) {
			if(leapYear(i)) {
				yearNumber += 366;
			}else {
				yearNumber += 365;
			}
		}
		
		for(int i = 1;i < month;i++) {
			monthNumber += monthDay(i);
		}
		if((monthNumber + yearNumber) % 7 < 2) {
			return (monthNumber + yearNumber) % 7 + 5;
		}else {
			return (monthNumber + yearNumber) % 7 - 2;
		}
	}
	//判断月份的天数
	private int monthDay(int month) {
		if(month == 1 || month ==3 || month ==5 || month ==7 || month ==8 || month ==10 || month ==12) {
			return 31;
		}else if(month == 2) {
			if(leapYear(year)) {
				return 29;
			}else {
				return 28;
			}
		}else {
			return 30;
		}
	}
	//判断闰年
	private boolean leapYear(int year) {
		if( !(year % 100 == 0) && year % 4 == 0 || year % 400 == 0 ) {
			return true;
		}else {
			return false;
		}
	}
	//在图片上打印一个月的日期
	public void imageAdd(int monthAdd) throws IOException {
		//在一个图片上打印年份和月份
		//创建类的对象
		BufferedImage image = new BufferedImage(550,550,BufferedImage.TYPE_INT_RGB);
		//获取画笔
		Graphics graphics = image.getGraphics();
		//写星期几
		int x = 100;
		int y = 100;
		graphics.drawString("一", x, y);
		x += 50;
		graphics.drawString("二", x, y);
		x += 50;
		graphics.drawString("三", x, y);
		x += 50;
		graphics.drawString("四", x, y);
		x += 50;
		graphics.drawString("五", x, y);
		x += 50;
		graphics.drawString("六", x, y);
		x += 50;
		graphics.drawString("七", x, y);
		x += 50;
		
		x = 100;
		y += 50;
		int tt = addTt();
		for(int i = 0;i < tt;i++) {
			graphics.drawString(" ", x, y);
			x += 50;
		}
		for(int j = 1;j < monthDay(monthAdd);j++) {
			graphics.drawString(String.valueOf(j) , x, y);
			x += 50;
			if((tt + j) % 7 == 0) {
				System.out.println();
				x = 100;
				y += 50;
			}
		}
		ImageIO.write(image, "jpg", new File("image.jpg"));
	}
}

2.案例-定时器打印数字

//案例用定时器隔两秒打印七个不相同的数
import java.util.*;//导入工具类包

public class TimeTest {
	public static void main(String[] args) {
		TimeTest test = new TimeTest();//实例化TimeTest类的对象来调用nums_7()方法
		Scanner input = new Scanner(System.in);
		boolean isFlag = true;//控制循环的结束
		Timer time = new Timer();//建立Timer工具类对象,调用定时器方法
		TimerTask timer = new TimerTask() {//实例化一个TimerTask对象并给里面加入方法,可供Timer对象调用
			@Override
			public void run() {
				test.nums_7();
			}
		};
		//控制开始
		while(isFlag) {
			System.out.println("是否获取七个不一样的数字?1开始0结束");
			int num = input.nextInt();//获取键盘值,控制开始结束
			if(num == 1) {
				//time.schedule(new MyTask(),0,2000);
				time.scheduleAtFixedRate(timer,0,2000);//不延迟,每2秒调用一次timer的方法
			}else if(num == 0){
				isFlag = false;
				time.cancel();//停止定时器
			}else {
				System.out.println("输入错误!请输入0或1");
			}
		}
		
/*
 * String s1 = new String("Tom"); String s2 = new String("Tom");
 * System.out.println(s1 == s2);
 */
	}
	public void nums_7() {
		//建立数组将7个随机数保存入数组里
		int[] arr = new int[7];
		int nums = 0;
		int i ;
		int j ;
		//控制7个数不相同,并写入数组
		for(i = 0;i < 7;i++) {
			nums = (int) (Math.random() * 33);
			if(i == 0) {
				  arr[i] = nums;
			}
			for(j = 0;j < i;j++) {
				if(arr[j] == nums) {
					i = i - 1;
					break;
				}else {
					arr[i] = nums;
				}
			}
		}
		//打印七个数
		for(int x = 0;x < 7;x++) {
			System.out.print(arr[x] + "\t");
		}
		//每打印七个数换行
		System.out.println();
	}
}
//class MyTask extends TimerTask{//打印七个不同数字的类继承TimerTask类,使其可以被定时器调用
//	  int[] arr = new int[7];
//	  int nums = 0;
//	  int i ;
//	  int j ;
//	  @Override
//	  public void run() {
//			  for(i = 0;i < 7;i++) {
//				  nums = (int) (Math.random() * 33);
//				  if(i == 0) {
//					  arr[i] = nums;
//				  }
//				  for(j = 0;j < i;j++) {
//					  if(arr[j] == nums) {
//						  i = i - 1;
//						  break;
//					  }else {
//						  arr[i] = nums;
//					  }
//				  }
//			  }
//			  for(int j = 0;j < 7;j++) {
//				  System.out.print(arr[j] + "\t");
//			  }
//			  System.out.println();
//	  }
//}

3.案例-存钱取钱

//案例 取钱存钱
public class Account {
	private int id;
	private double balance;
	private double annualInterestRate;
	//构造器
	public Account(int id,double balance,double annualInterestRate) {
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}
	//方法
	public int getId() {
		return id;
	}

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

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}

	public double getAnnualInterestRate() {
		return annualInterestRate;
	}

	public void setAnnualInterestRate(double annualInterestRate) {
		this.annualInterestRate = annualInterestRate;
	}
	//取钱
	public void withdraw(double amount) {
		if(balance < amount) {
			System.out.println("余额不足");
			return;
		}
		balance -= amount;
		System.out.println("余额" + balance + "取出" + amount);
	}
	//存钱
	public void deposit(double amount) {
		if(amount > 0) {
			balance += amount;
			System.out.println("成功存入" + balance);
		}
	}
}
//
public class Customer {
	private String firstName;
	private String lastName;
	private Account account;
	public Customer(String f,String l) {
		this.firstName = f;
		this.lastName = l;
		
	}
	public Account getAccount() {
		return account;
	}
	public void setAccount(Account account) {
		this.account = account;
	}
	public String getFirstName() {
		return firstName;
	}
	public String getLastName() {
		return lastName;
	}
	
}
//
public class CustomerTest {
	public static void main(String[] args) {
		//建立对象
		Customer cust = new Customer("Jane","Smith");
		
		Account acct = new Account(1000,2000,0.0123);
		
		cust.setAccount(acct);
		cust.getAccount().deposit(100);
		cust.getAccount().withdraw(1000);
		
		cust.getAccount().withdraw(2000);
		
		System.out.println("Customer[" + cust.getLastName() + "," +
		cust.getFirstName() + "] " + "id" + cust.getAccount().getId() + "余额" + cust.getAccount().getBalance());
		
	}
}
//案例
public class Account {
	private double balance;
	public Account(double init_balance) {
		this.balance = init_balance;
	}
	public double getBalance() {
		return balance;
	}
	//存钱操作
	public void deposit(double amt) {
		if(amt > 0) {
			balance += amt;
			System.out.println("存钱成功");
		}
	}
	//取钱操作
	public void withdraw(double amt) {
		if(balance >= amt) {
			balance -= amt;
			System.out.println("存钱成功");
		}else {
			System.out.println("余额不足");
		}
	}
}
//
public class Bank {
	private Customer[] customers;//存放多个客户的数组
	private int numberOfCustomer;//记录客户的个数
	
	public Bank() {
		customers = new Customer[10];
	}
	//添加客户
	public void addCustomer(String f,String l) {
		Customer cust = new Customer(f,l);
		customers[numberOfCustomer++] = cust;
		//numberOfCustomer++;
	}
	//获取客户的个数
	public int getNumOfCustomers() {
		return numberOfCustomer;
	}
	//获取指定位置的客户
	public Customer getCustomer(int index) {
		if(index >= 0 && index < customers.length) {
			return customers[index];
		}else {
			return null;
		}
	}
}
//
public class Customer {
	private String firstName;
	private String lastName;
	private Account account;
	
	public Customer(String f,String l) {
		this.firstName = f;
		this.lastName = l;
	}

	public Account getAccount() {
		return account;
	}

	public void setAccount(Account account) {
		this.account = account;
	}

	public String getFirstName() {
		return firstName;
	}

	public String getLastName() {
		return lastName;
	}
}
//
public class BankTesst {
	public static void main(String[] args) {
		Bank bank = new Bank();
		
		bank.addCustomer("June", "Aime");
		bank.getCustomer(0).setAccount(new Account(2000));
		
		bank.getCustomer(0).getAccount().withdraw(500);
		double balance = bank.getCustomer(0).getAccount().getBalance();
		System.out.println("客户"+ bank.getCustomer(0).getFirstName() + "余额" + balance);
	}
}

4.案例-超市购物系统

package entity;

//管理员账号实体类
public class Admin {
	private String id;//管理员帐号
	private String passWord;//管理员密码
	
	public Admin() {
		super();
	}
	
	public Admin(String id, String passWord) {
		super();
		this.id = id;
		this.passWord = passWord;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassWord() {
		return passWord;
	}
	public void setPassWord(String passWord) {
		this.passWord = passWord;
	}
	
}
package entity;

//商品实体类
public class Product {
	private int id;//商品序号
	private String name;//商品名称
	private float price;//商品价格
	private int nums;//商品数量
	
	public static Product[] goodList = new Product[200];//存储商品的数组
	
	public Product() {
		super();
	}
	public Product(int num, String name, float price,int nums) {
		super();
		this.id = num;
		this.name = name;
		this.price = price;
		this.nums = nums;
	}
	public int getNums() {
		return nums;
	}
	public void setNums(int nums) {
		this.nums = nums;
	}
	public int getId() {
		return id;
	}
	public void setId(int num) {
		this.id = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
}
package entity;

//购物车实体类
public class ShopCar {
	
	public static Product[] shopCars = new Product[200];//存储商品的数组
	
	public ShopCar() {
		super();
	}

}
package service;

import ui.ShoppingUI;

public class ShopTest {
	
	public static void main(String[] args) {
		ShoppingUI shoppingUI = new ShoppingUI();
		shoppingUI.showShopping();
	}
}
package ui;

import java.util.Scanner;

import util.AdminUtil;
import util.GoodsUtil;

public class AdminUI {
	private static Scanner adminInput = new Scanner(System.in);
	
	//管理员操作界面
	public static void adminUI() {
		int inputNums = 0;
		//管理员账号登陆
		while(true) {
			System.out.println("请输入管理员账号");
			String adminId = adminInput.next();
			System.out.println("请输入管理员密码");
			String passWord = adminInput.next();
			if(adminId.equals( AdminUtil.getAdmin().getId()) && passWord.equals(AdminUtil.getAdmin().getPassWord())){
				break;
			}else {
				if(inputNums == 2) {
					System.out.println("输入次数已上线,退出管理员登陆!");
					return;
				}else {
					System.out.println("账号密码错误");
				}
			}
			inputNums++;
		}
		
		//管理员操作
		while(true) {
			System.out.println("1.管理员添加商品2.管理员删除商品3.显示商品列表4.退出管理员操作");
			int choice = adminInput.nextInt();
			if(choice == 1) {
				System.out.println("请输入商品的编号");
				int id = adminInput.nextInt();
				System.out.println("请输入商品的名字");
				String name = adminInput.next();
				System.out.println("请输入商品的价格");
				float price = adminInput.nextFloat();
				System.out.println("请输入商品的数量");
				int nums = adminInput.nextInt();
				GoodsUtil.addGoods(id, name, price, nums);
			}else if(choice == 2) {
				System.out.println("请输入你要删除的商品的序号");
				int deletenum = adminInput.nextInt();
				GoodsUtil.deleteGoods(deletenum);
			}else if(choice == 3) {
				GoodsUtil.showGoods();
			}else if(choice == 4) {
				break;
			}else {
				System.out.println("请输入正确的数字!");
			}
		}
	}
}
package ui;

import java.util.Scanner;

import entity.ShopCar;
import util.ShopCarUtil;

public class ShoppingCarUI {
	private static Scanner input = new Scanner(System.in);
	//购物车界面
	public static void shoppingCarUI(){
		
		while(true) {
			ShopCarUtil.showShopCar();
			if(ShopCar.shopCars[0] == null) {
				return;
			}
			System.out.println("1.删除商品2.清空购物车3.返回上一层");
			int choice = input.nextInt();
			if(choice == 1) {
				System.out.println("请输入你要删除商品的序号");
				int deleteNum = input.nextInt();
				ShopCarUtil.deleteAccounts(deleteNum);
			}else if(choice == 2) {
				ShopCarUtil.clearShopCar();
			}else if(choice ==3) {
				break;
			}else {
				System.out.println("输入错误,请输入正确的数字!");
			}
			
		}
	}
}
package ui;

import java.util.Scanner;

import entity.Product;
import util.ShopCarUtil;
import util.GoodsUtil;

//购物车界面
public class ShoppingUI {
	
	Scanner input = new Scanner(System.in);
	public void showShopping() {
		
		/*
		 * 超市的界面方法
		 */
		while(true) {
			System.out.println("--------------欢迎来到Java超市--------------");
			
			System.out.println("1.显示商品列表2.购买商品3.查看购物车列表4.结算5.管理员登陆6.退出");
			
			int choice = input.nextInt();
			if(choice == 1) {
				GoodsUtil.showGoods();
			}else if(choice == 2){
				int list;
				int nums;
				while(true) {
					System.out.println("请输入你要添加商品的序号");
					list = input.nextInt();
					if(list < GoodsUtil.addProduct) {
						break;
					}else {
						System.out.println("请输入正确的商品序号!");
					}
				}
				while(true) {
					System.out.println("请输入你要添加商品的数量");
					nums = input.nextInt();
					if(nums < Product.goodList[list - 1].getNums()) {
						break;
					}else {
						System.out.println("商品库存不足,请重新输入!");
					}
				}
				ShopCarUtil.addGoodsCar(list,nums);
				
			}else if(choice ==3) {
				ShoppingCarUI.shoppingCarUI();
			}else if(choice ==4) {
				int allPrice = ShopCarUtil.settleAccounts();
				if(allPrice == 0) {
					System.out.println("请先购买商品!");
					return;
				}
				System.out.println("总价为:" + allPrice);
			}else if(choice ==5) {
				AdminUI.adminUI();
			}else if(choice ==6) {
				System.out.println("期待您的下次光临!");
				break;
			}else {
				System.out.println("请输入正确的数字");
			}
		}
		
	}
}
package util;

import entity.Admin;

public class AdminUtil {
	
	//创建管理员帐号
	static Admin admin = new Admin("admin","123456");
	
	public static Admin getAdmin() {
		return admin;
	}
	public static void setAdmin(Admin admin) {
		AdminUtil.admin = admin;
	}
	
}
package util;

import entity.Product;

//商品工具类
public class GoodsUtil {
	
	private static int numsProduct = 0;//打印商品列表商品的序号
	public static int addProduct = 0;//添加商品的数组角标
	
	//初始化商品
	static {
		Product p1 = new Product(1001,"茄子",1.5f,100);
		Product p2 = new Product(1002,"萝卜",1.7f,100);
		Product p3 = new Product(1003,"黄瓜",2.3f,100);
		Product.goodList[addProduct++] = p1;
		Product.goodList[addProduct++] = p2;
		Product.goodList[addProduct++] = p3;//addProduct = 3
		
		
	}
	
	//显示商品列表
	public static void showGoods() {
		numsProduct = 1;
		System.out.println("序号\t" + "商品编号\t" + "商品名称\t" + "商品价格\t" + "商品数量\t");
		for(Product p :Product.goodList) {
			if(p != null) {
				System.out.print(numsProduct++ + "\t" + p.getId() + "\t" + p.getName() + "\t"  + p.getPrice() + "\t"  + p.getNums() + "\t" );
				System.out.println();
			}else {
				break;
			}
		}
	}
	
	//管理员添加商品
	public static void addGoods(int id,String name,float price,int nums) {
		Product newProduct = new Product(id,name,price,nums);
		Product.goodList[addProduct++] = newProduct;
	}
	
	//管理员删除商品
	public static void deleteGoods(int deletenum) {
		//将商品的后一个商品覆盖前一个商品,来删除商品
		for(int i = deletenum - 1;i < Product.goodList.length;i++ ) {
			if(Product.goodList[i + 1] == null) {
				Product.goodList[i] = Product.goodList[i + 1];
				break;
			}else {
				Product.goodList[i] = Product.goodList[i + 1];
			}
		}
		addProduct--;
	}
	
	
}
package util;

import entity.Product;
import entity.ShopCar;

//购物车工具类
public class ShopCarUtil {
	
	private static int nums = 0;
	public static int numsShopCarProduct = 0;
	//添加商品,将商品写入购物车
	public static void addGoodsCar(int id,int goodsNum) {
		Product addGoods = Product.goodList[id - 1];
		Product shopCar = new Product();
		shopCar.setId(addGoods.getId());
		shopCar.setName(addGoods.getName());
		shopCar.setPrice(addGoods.getPrice());
		shopCar.setNums(goodsNum);
		int goodsnums = addGoods.getNums();
		if((goodsnums - goodsNum) >= 0) {
			addGoods.setNums(goodsnums - goodsNum);
		}else {
			System.out.println("库存不足,请重新选择!");
			return;
		}
		ShopCar.shopCars[nums++] = shopCar;
	}
	
	//显示购物车列表
	public static void showShopCar() {
		
		if(ShopCar.shopCars[0] == null) {
			System.out.println("您的购物车是空的,请先购买商品在查看!");
			return;
		}
		
		numsShopCarProduct = 1;
		System.out.println("------------------你的购物车-------------------");
		System.out.println("序号\t" + "商品编号\t" + "商品名称\t" + "商品价格\t" + "商品数量\t");
		for(Product p :ShopCar.shopCars) {
			if(p != null) {
				System.out.print(numsShopCarProduct++ + "\t" + p.getId() + "\t" + p.getName() + "\t"  + p.getPrice() + "\t"  + p.getNums() + "\t" );
				System.out.println();
			}else {
				break;
			}
		}
	}
	
	//结算
	public static int settleAccounts() {
		int allPrice = 0;
		for(Product p :ShopCar.shopCars) {
			if(p != null) {
				allPrice += p.getPrice()*p.getNums();
			}else {
				break;
			}
		}
		return allPrice;
	}
	
	//删除购物车商品
	public static void deleteAccounts(int deletenum) {
		ShopCarUtil.returnNums(deletenum - 1);
		//将商品的后一个商品覆盖前一个商品,来删除商品
		for(int i = deletenum - 1;i < ShopCar.shopCars.length;i++ ) {
			if(ShopCar.shopCars[i + 1] == null) {
				ShopCar.shopCars[i] = ShopCar.shopCars[i + 1];
				break;
			}else {
				ShopCar.shopCars[i] = ShopCar.shopCars[i + 1];
			}
		}
		ShopCarUtil.nums--;
	}
	
	//清空购物车
	public static void clearShopCar() {
		for(int i = 0;i < ShopCar.shopCars.length;i++) {
			if(ShopCar.shopCars[i] != null) {
				ShopCarUtil.returnNums(i);
			}else {
				break;
			}
		}
		
		for(int i = 0;i < ShopCar.shopCars.length;i++) {
			if(ShopCar.shopCars[i] != null) {
				ShopCar.shopCars[i] = null;
			}else {
				break;
			}
		}
	}
	
	//将删除商品的数量返回至商品列表
	public static void returnNums(int deletenum) {
		
		Product delAccount = ShopCar.shopCars[deletenum];
		for(Product p :Product.goodList) {
			if(p.getId() == delAccount.getId()) {
				int nums = p.getNums() + delAccount.getNums();
				p.setNums(nums);
				break;
			}
		}
	}
}

5.案例-检索并播放指定盘符中的音乐

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Timer;
import java.util.TimerTask;

import javazoom.jl.player.Player;

public class Mp3Player {
	public static void main(String[] args) {
		Mp3Player mp3 = new Mp3Player();
		File d = new File("f:/");
		mp3.showMenu();
		String[] file = mp3.readFiles(d);
		while(true) {
			mp3.playerMp3(file);
			if(playNums == 20) {
				break;
			}
		}
		//每五秒调用一次检索硬盘是否插入新的盘符
		Timer time = new Timer();
		TimerTask timer = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				mp3.monitorDisk();
			}
			
		};
		time.scheduleAtFixedRate(timer,0,5000);
	}
	
	private Player player;
	private int nums = 0;//将音乐文件添加进数组的脚标
	String[] mp3File = new String[100];//将音乐的绝对路径写入数组
	private static int playNums = 0;//播放20首歌时,停止播放
	private String mp3Name;//播放音乐地址值的脚标检索值
	static File[] file = File.listRoots();//先获取盘符的默认长度,如果长度增加说明有新的设备输入,则读取新的设备
	static int numsHardDisk = file.length;
	//展示程序菜单
	public void showMenu() {
		System.out.println("搜索对应盘符中的mp3文件如下:");
		
	}
	//持续监听硬盘盘符是否改变
	public void  monitorDisk() {
		File[] fileDisk = File.listRoots();
		if(fileDisk.length > numsHardDisk) {
			String p = String.valueOf(fileDisk[fileDisk.length - 1]);
			File d = new File(p);
			Mp3Player mp3USB = new Mp3Player();
			mp3USB.showMenu();
			String[] file = mp3USB.readFiles(d);
			mp3USB.monitorDisk();
			while(true) {
				mp3USB.playerMp3(file);
				if(playNums == 20) {
					break;
				}
			}
		}
		
	}
	//读取磁盘中mp3文件
	public String[] readFiles(File rootFile) {
		//打印文件夹名字
		String fileName = rootFile.getName();
		//列出文件夹中所有的文件
		File files[] = rootFile.listFiles();
		if(rootFile.isFile()) {
			String sub = fileName.substring(fileName.length()-3);
			if(sub.equals("mp3")) {
				String path = rootFile.getAbsolutePath();
				mp3File[nums++] = path;
			}
		}
		if(files != null) {
			for(File file2 : files) {
				readFiles(file2);
			}
		}
		return mp3File;
	}
	//播放mp3
	public void playerMp3(String[] files) {
		mp3Name = files[playNums++];
		try {
            BufferedInputStream buffer = new BufferedInputStream(new FileInputStream(mp3Name));
            player = new Player(buffer);
            player.play();
        } catch (Exception e) {
            System.out.println(e);
        }
	}
}

6.案例-复制文件

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class CopyHomework {
	
	Scanner input = new Scanner(System.in);
	public static void main(String[] args) {
		CopyHomework ch = new CopyHomework();
		Scanner input = new Scanner(System.in);
		try {
			while(true) {
				System.out.println("是否要复制文件?1.是2.退出");
				int choice = input.nextInt();
				if(choice == 1) {
					ch.copyUI();
				}else if(choice == 2) {
					break;
				}else {
					System.out.println("请输入正确的数字!");
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			input.close();
		}
	}
	
	//界面方法
	public void copyUI() throws IOException {
		try {
			System.out.println("请输入你要复制的源文件路径");
			String path = input.next();
			System.out.println("请输入你要赋值文件指定保存路径");
			String copyPath = input.next();
			System.out.println("请输入新文件的名字和文件格式");
			String copyName = input.next();
			copy(path,copyPath,copyName);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//将需要拷贝文件的内容读出来并写入
	public void copy(String path,String copyPath,String copyname) throws IOException {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			FileInputStream fis = new FileInputStream(new File(path));
			FileOutputStream fos = new FileOutputStream(new File(copyPath + "\\" + copyname));
			
			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);
			
			byte[] buffer = new byte[20];
			int len;
			while((len = bis.read(buffer)) != -1) {
				bos.write(buffer,0,len);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				if(bis != null)
				bis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				if(bos != null)
				bos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}

7.案例-可储存的注册和登录

//此案例的异常应该使用try-catch-finally解决
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Scanner;

public class LoginTest {
	
	public static void main(String[] args) throws IOException {
		
		LoginTest l = new LoginTest();
		Scanner input = new Scanner(System.in);
		while(true) {
			System.out.println("请问你是要注册还是登录?1.注册2.登录3.退出");
			int choice = input.nextInt();
			if(choice == 1) {
				l.registrationUI();
			}else if(choice == 2) {
				l.loginUI();
			}else if(choice == 3){
				System.out.println("退出成功!");
				break;
			}else {
				System.out.println("请输入正确的数字");
			}
		}
		input.close();
	}
	
	
	Scanner input = new Scanner(System.in);
	String savePath = "F:\\eclipse-workpeace\\ObjectParctice\\src\\logintest\\saveFile.txt";
	File file = new File(savePath);
	byte[] arrayb = new byte[20];
	//注册界面
	public void registrationUI() throws IOException {
		System.out.println("----------注册界面---------");
		System.out.println("请输入你的账号");
		String name = input.next();
		System.out.println("请输入你的密码");
		String pwg = input.next();
		System.out.println("请再次输入你的密码");
		String spwg = input.next();
		if(pwg.equals(spwg)){
			saveAcount(name,pwg);
			System.out.println("注册成功!");
		}else {
			System.out.println("两次输入的密码不一致,请重新输入");
		}
	}
	
	//将注册的账号密码写入到电脑里方便下次登录
	public void saveAcount(String name,String pwg) throws IOException {
		String lastAccount = lastTxt();
		FileOutputStream out = new FileOutputStream(file);
		String account = name + pwg;
		String allAccount;
		allAccount = lastAccount +"\r\n" + account ;
		System.out.println(allAccount);
		byte b[] = allAccount.getBytes();
		out.write(b);
		out.close();
	}
	
	//登录界面
	public void loginUI() throws IOException {
		int nums = 1;
		while(true) {
			System.out.println("----------登录界面---------");
			System.out.println("请输入你的账号");
			String name = input.next();
			System.out.println("请输入你的密码");
			String pwg = input.next();
			boolean right = equalsAcount(name,pwg);
			if(right) {
				System.out.println("登录成功");
				break;
			}else {
				System.out.println("登陆失败,请重新输入!");
				if(nums == 3) {
					break;
				}
			}
			nums++;
		}
	}
	
	//判断登陆账号密码是否已经注册
	public boolean equalsAcount(String name,String pwg) throws IOException {
		InputStream input = new FileInputStream(file);
		Reader bReader = new InputStreamReader(input);
		BufferedReader bs = new BufferedReader(bReader);
		String outname;
		String inputname = name + pwg;
		while((outname = bs.readLine()) != null) {
			if(outname.equals(inputname)) {
				input.close();
				bs.close();
				return true;
			}
		}
		input.close();
		return false;
	}
	
	//获取原来文本文档中的内容
	public String lastTxt() throws IOException {
		InputStream input = new FileInputStream(file);
		Reader bReader = new InputStreamReader(input);
		BufferedReader bs = new BufferedReader(bReader);
		String name ;
		String allName = "" ;
		while((name = bs.readLine()) != null) {
			allName = allName + "\r\n" + name ;
		}
		bs.close();
		return allName;
	}
	
}
			}else if(choice == 2) {
				break;
			}else {
				System.out.println("请输入正确的数字!");
			}
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally {
		input.close();
	}
}

//界面方法
public void copyUI() throws IOException {
	try {
		System.out.println("请输入你要复制的源文件路径");
		String path = input.next();
		System.out.println("请输入你要赋值文件指定保存路径");
		String copyPath = input.next();
		System.out.println("请输入新文件的名字和文件格式");
		String copyName = input.next();
		copy(path,copyPath,copyName);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

//将需要拷贝文件的内容读出来并写入
public void copy(String path,String copyPath,String copyname) throws IOException {
	BufferedInputStream bis = null;
	BufferedOutputStream bos = null;
	try {
		FileInputStream fis = new FileInputStream(new File(path));
		FileOutputStream fos = new FileOutputStream(new File(copyPath + "\\" + copyname));
		
		bis = new BufferedInputStream(fis);
		bos = new BufferedOutputStream(fos);
		
		byte[] buffer = new byte[20];
		int len;
		while((len = bis.read(buffer)) != -1) {
			bos.write(buffer,0,len);
		}
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}finally {
		try {
			if(bis != null)
			bis.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			if(bos != null)
			bos.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

}


#### 7.案例-可储存的注册和登录

~~~java
//此案例的异常应该使用try-catch-finally解决
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Scanner;

public class LoginTest {
	
	public static void main(String[] args) throws IOException {
		
		LoginTest l = new LoginTest();
		Scanner input = new Scanner(System.in);
		while(true) {
			System.out.println("请问你是要注册还是登录?1.注册2.登录3.退出");
			int choice = input.nextInt();
			if(choice == 1) {
				l.registrationUI();
			}else if(choice == 2) {
				l.loginUI();
			}else if(choice == 3){
				System.out.println("退出成功!");
				break;
			}else {
				System.out.println("请输入正确的数字");
			}
		}
		input.close();
	}
	
	
	Scanner input = new Scanner(System.in);
	String savePath = "F:\\eclipse-workpeace\\ObjectParctice\\src\\logintest\\saveFile.txt";
	File file = new File(savePath);
	byte[] arrayb = new byte[20];
	//注册界面
	public void registrationUI() throws IOException {
		System.out.println("----------注册界面---------");
		System.out.println("请输入你的账号");
		String name = input.next();
		System.out.println("请输入你的密码");
		String pwg = input.next();
		System.out.println("请再次输入你的密码");
		String spwg = input.next();
		if(pwg.equals(spwg)){
			saveAcount(name,pwg);
			System.out.println("注册成功!");
		}else {
			System.out.println("两次输入的密码不一致,请重新输入");
		}
	}
	
	//将注册的账号密码写入到电脑里方便下次登录
	public void saveAcount(String name,String pwg) throws IOException {
		String lastAccount = lastTxt();
		FileOutputStream out = new FileOutputStream(file);
		String account = name + pwg;
		String allAccount;
		allAccount = lastAccount +"\r\n" + account ;
		System.out.println(allAccount);
		byte b[] = allAccount.getBytes();
		out.write(b);
		out.close();
	}
	
	//登录界面
	public void loginUI() throws IOException {
		int nums = 1;
		while(true) {
			System.out.println("----------登录界面---------");
			System.out.println("请输入你的账号");
			String name = input.next();
			System.out.println("请输入你的密码");
			String pwg = input.next();
			boolean right = equalsAcount(name,pwg);
			if(right) {
				System.out.println("登录成功");
				break;
			}else {
				System.out.println("登陆失败,请重新输入!");
				if(nums == 3) {
					break;
				}
			}
			nums++;
		}
	}
	
	//判断登陆账号密码是否已经注册
	public boolean equalsAcount(String name,String pwg) throws IOException {
		InputStream input = new FileInputStream(file);
		Reader bReader = new InputStreamReader(input);
		BufferedReader bs = new BufferedReader(bReader);
		String outname;
		String inputname = name + pwg;
		while((outname = bs.readLine()) != null) {
			if(outname.equals(inputname)) {
				input.close();
				bs.close();
				return true;
			}
		}
		input.close();
		return false;
	}
	
	//获取原来文本文档中的内容
	public String lastTxt() throws IOException {
		InputStream input = new FileInputStream(file);
		Reader bReader = new InputStreamReader(input);
		BufferedReader bs = new BufferedReader(bReader);
		String name ;
		String allName = "" ;
		while((name = bs.readLine()) != null) {
			allName = allName + "\r\n" + name ;
		}
		bs.close();
		return allName;
	}
	
}

你可能感兴趣的:(Java,java)