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地址值给p3Person 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){//创建的每一个对象的年龄默认值都是18Person 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);//4Order1 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类的m1Man 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);//20s.display();//20//多态性,属性都看左边,方法先看左边再看右边Base b = s;//==,在此处比较的是两个数据的地址值是否相同System.out.println(b == s);//trueSystem.out.println(b.count);//10b.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 10n = 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 1001o2.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为200System.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){@Overridepublic 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 = 0for(;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;
//      }
//  }//自动生成@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic 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);//tureSystem.out.println(i == c);//truechar c1 = 'A';char c2 = 65;System.out.println(c1 == c2);//truePerson p1 = new Person("Tom",21);Person p2 = new Person("Tom",21);System.out.println(p1 == p2);//falseString str1 = new String();String str2 = new String();//因为String在方法区的常量池,当两个值相同时,他的地址值则相同String str3 = "bb";String str4 = "bb";System.out.println(str3 == str4);//tureSystem.out.println(str1 == str2);//false//**************************************************System.out.println(p1.equals(p2));//false //重新写入equals方法后变成tureSystem.out.println(str1.equals(str2));//tureDate 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;}//比较两个圆的半径是否相等,相等返回turepublic 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类型一样可以直接输出值@Overridepublic 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新特性,自动装箱和自动拆箱*/@Testpublic 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();@Testpublic 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")@Testpublic 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);//falseSystem.out.println(order.isFamle);//null}
}
class Order{boolean isMale;Boolean isFamle;
}

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

{//String类型--->转化为基本数据类型、包装类@Testpublic void test5() {String str1 = "123";//可能会报NumberFormatExceptionint num2 = Integer.parseInt(str1);System.out.println(num2 + 1);String str2 = "true";boolean b1 = Boolean.parseBoolean(str2);System.out.println(b1);}//基本数据类型、包装类--->String类型@Testpublic void test4() {int num1 = 10;//方式1String str1 = num1 + "";//方式2float f1 = 12.3f;String str2 = String.valueOf(f1);System.out.println(str2);//12.3Double d1 = new Double(12.4);String str3 = String.valueOf(d1);System.out.println(str3);//12.4}
}
//案例
import org.junit.Test;
/** 关于包装类的案例题*/
public class InterviewTest {@Testpublic void test1() {Object o1 = true ? new Integer(1) : new Double(2.0);System.out.println(o1);//1.0  三元运算符两个选项的数据类型应该相同,这里数据类型提升}@Testpublic void test2() {Object o2;if(true) {o2 = new Integer(1);}else {o2 = new Double(2.0);}System.out.println(o2);//1}@Testpublic 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);}@Overridepublic void eat1() {// TODO Auto-generated method stubSystem.out.println("学生多吃实物");}//重写间接父类的抽象方法@Overridepublic void breath() {// TODO Auto-generated method stubSystem.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() {@Overridepublic void eat1() {// TODO Auto-generated method stubSystem.out.println("吃东西");}@Overridepublic void breath() {// TODO Auto-generated method stubSystem.out.println("呼吸");}};method1(p);System.out.println("---------------------------------------");//创建匿名子类的匿名对象method1(new Person() {@Overridepublic void eat1() {// TODO Auto-generated method stubSystem.out.println("好好吃饭");}@Overridepublic void breath() {// TODO Auto-generated method stubSystem.out.println("好好呼吸");}});}public static void method1(Person p) {p.eat1();p.breath();}public static void method(Student s) {}
}class Worker extends Person{@Overridepublic void eat1() {// TODO Auto-generated method stubSystem.out.println("worker吃东西");}@Overridepublic void breath() {// TODO Auto-generated method stubSystem.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("吃饭");}@Overridepublic 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{@Overridepublic void fly() {System.out.println("起飞");}@Override//implements interfacetest.Flyable.stoppublic void stop() {System.out.println("降落");}}abstract class Kite implements Flyable{public void fly() {}
}
//先继承然后在实现接口
class Bullet extends Object implements Flyable,Attackable,CC{@Overridepublic void fly() {// TODO Auto-generated method stub}@Overridepublic void stop() {// TODO Auto-generated method stub}@Overridepublic void attack() {// TODO Auto-generated method stub}//******************************************************@Overridepublic void aa() {// TODO Auto-generated method stub}@Overridepublic 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() {@Overridepublic void start() {System.out.println("手机开始工作");}@Overridepublic void stop() {System.out.println("手机结束工作");}};com.transferData(phone);System.out.println("------------------------------------");//4.创建了接口的匿名实现类的匿名对象com.transferData(new USB() {@Overridepublic void start() {System.out.println("mp3开始工作");}@Overridepublic 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{@Overridepublic void start() {// TODO Auto-generated method stubSystem.out.println("Flash开始");}@Overridepublic void stop() {// TODO Auto-generated method stubSystem.out.println("Flash停止");}}class Printer implements USB{@Overridepublic void start() {// TODO Auto-generated method stubSystem.out.println("Printer开始");}@Overridepublic void stop() {// TODO Auto-generated method stubSystem.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);//1System.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();//方式2return 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开始,到数组的长度-1names[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)//数组元素类型是引用数据类型:nullint[] arr = new int[4];for(int i = 0;i < arr.length;i++){System.out.println(arr[i]);}//输出0000char[] 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]);//输出nullif(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 + oSystem.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);//3System.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]);//0System.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 - 1int 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的地址赋给array2for(int i = 0;i < array2.length;i++){if(i % 2 == 0){//因为array1的地址赋值给array,更改array2就等于更改array1array2[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];}//反转//方法1for(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;}//方法2for(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{@Overridepublic void code() {// TODO Auto-generated method stubfor(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{@Overridepublic 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("联网之前的检查工作");}@Overridepublic 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对象调用@Overridepublic 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() {@Overridepublic void run() {// TODO Auto-generated method stubmp3.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;}//播放mp3public 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 blocke.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 blocke.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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {try {if(bis != null)bis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {if(bos != null)bos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.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 blocke.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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {try {if(bis != null)bis.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {if(bos != null)bos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.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基础SE.03.Java面向对象相关推荐

  1. 菜鸟学习笔记:Java基础篇4(面向对象三大特征)

    菜鸟学习笔记:Java面向对象篇中 继承 概念 方法重写(override) Object类 Super关键字 组合 final关键字补充 封装 访问控制符 多态 继承 概念 继续上一篇的例子: #m ...

  2. 菜鸟学习笔记:Java基础篇3(面向对象思想、程序执行过程内存分析、面向对象重要概念)

    菜鸟学习笔记:Java面向对象篇上 Java面向对象的思想 Java程序执行过程内存分析 Java垃圾回收机制 构造方法 方法重载(overload) static关键字 this关键字 Java面向 ...

  3. Java基础【之】面向对象编程(封装、继承(extends、方法重写、super)、多态(动态绑定、重载/重写)、代码实现)

    Java基础[之]面向对象编程(封装.继承.多态.代码实现) 1.封装 2.继承 2.1.extends 2.2.方法重写 2.3.super 3.多态 3.1.对象的多态.方法的多态 3.2.动态绑 ...

  4. 打怪升级之小白的大数据之旅(一)<Java基础语法之Java的身世之谜>

    打怪升级之小白的大数据之旅(一) Java基础语法之Java的身世之谜 打怪升级之小白的大数据之旅(一) 前言 一.学习大数据之前 二.Java基础 what? why? how? 总结 前言 做了几 ...

  5. 视频教程-Java基础与实践-Java

    Java基础与实践 CSDN高校俱乐部指导老师,程序爱好者,教师,国家认证的软件架构设计师.系统分析师.信息系统项目管理师.软件设计师.网络工程师.本人热衷于计算机软件相关的研发.技术探讨.学习分享和 ...

  6. Java基础2019最新Java面试经典题解析

    Java基础2019最新Java面试经典题解析 1简述JVM.JRE.JDK的区别 JVM:java虚拟机 ,加载.class并运行.class JRE:java运行环境除了包含JVM以外还包含了运行 ...

  7. java里面value_「Java基础知识」Java中包含哪些运算符

    原标题:「Java基础知识」Java中包含哪些运算符 在Java中包含的运算符有:算数运算符,逻辑运算符,关系运算符等. 算数运算符也就是我们平时的加减乘除余等操作:在Java中都是将右边的值赋值给左 ...

  8. java里面string什么意思_「Java基础知识」Java中的字符串是什么

    原标题:「Java基础知识」Java中的字符串是什么 字符串顾名思义就是一些字符组合在一起组成的一串数据,称作字符串,在Java中字符串用双引号包围起来,格式为String string = &quo ...

  9. 《Java基础知识》Java变量的声明、初始化和作用域

    <Java基础知识>Java变量的声明.初始化和作用域 一.Java变量的声明 在 Java 程序设计中,每个声明的变量都必须分配一个类型.声明一个变量时,应该先声明变量的类型,随后再声明 ...

  10. Java基础篇(03):流程控制语句,和算法应用

    本文源码:GitHub·点这里 || GitEE·点这里 一.分支语句 流程控制语句对任何一门编程语言都是非常重要的,Java中基于流程控制程序执行的不同步骤和代码块. 1.IF条件 IF条件语句会根 ...

最新文章

  1. 用Tableau制作3D旋转地球
  2. 解决layui数据表格table固定列行高不一致的情况
  3. SAP Customer Data Cloud的administrator设置
  4. zabbix触发器表达式
  5. 【BZOJ - 3450】Tyvj1952 Easy(数学期望,期望的线性性)
  6. 停止追赶最新的 RPA 趋势
  7. 什么相片可以两张弄成一张_怎么将两张图片合成一张?
  8. kindle资源网址
  9. Android录音声音大小判断,Android录音使用 byte 类型获取分贝或声音振幅
  10. js 负数转换正_如何使用JavaScript将负数转换为正数?
  11. js 实现打以及样式问题
  12. Octane 2022 预览版来了 -设计师们的福音
  13. java文件后缀_java源文件名的后缀是什么?
  14. Python 解析爬取的车次数据(12306)
  15. 深入了解 Animation Scripting 动画脚本
  16. TM1638驱动数码管的一点建议,附程序
  17. Java-Stream流,异常捕获
  18. 软件工程第1次作业:阅读教材,提五个问题
  19. SpringBean生命周期详解 | 有图有真相
  20. 武汉,一座被低估的城市!(2)

热门文章

  1. slickedit使用
  2. python pycharm anaconda需要都下载吗_Anaconda下载与安装、PyCharm下载与安装
  3. 微星主板Ubuntu16.04安装教程
  4. 计算机考研408高分复习规划-如何复习408才能得高分
  5. 湖南师范大学地图学与地理信息系统专业考研上岸经验分享
  6. Qt中QImage用于16位图像的显示,QImage数据对齐
  7. 一对一语音视频直播双端原生+php后台源码 社交交友APP匹配语音视频聊天即时通信源码
  8. VS code 快捷键常用
  9. 【python】10行代码下载B站弹幕
  10. Android 编程经典200例 (pdf)资源