面向过程 : 以函数为最小单位(方法),数据独立于函数之外,以过程步骤为主(怎么做)—执行者
面向对象 : 以类对象为最小单位,类包括数据+方法,是以对象为主(谁来做)—指挥者
类
举例:小猫
属性:名字,颜色,体重
行为:走,跑,叫
对象 :
举例:小猫
属性:tom,yellow,5KG
行为:贴墙走,喵喵叫
类与对象的关系
创建类
类的定义
package com.kgc01;
public class Demo01Person {//成员变量String name; //姓名int age; //年龄String gender; //性别//成员方法public void walk(){System.out.println("走路");}public String display(){return "名字是:"+name+",年龄是:"+age+",性别是:"+gender;}
}
对象的创建
package com.kgc01;
public class PersonTest {public static void main(String[] args) {//创建一个对象Demo01Person p1=new Demo01Person();p1.name="小红";p1.age=18;p1.gender="女";p1.walk();p1.display();System.out.println(p1.display());}
}
//在一个java文件里创建
package com.kgc01;
class Student{String name;public void study(){System.out.println("好好学习,天天向上");}
}
public class TestStudent {public static void main(String[] args) {Student s1 = new Student();s1.name="张三";System.out.println(s1.name);s1.study();}
}
成员变量
分类
声明一个实例变量
使用实例变量
package com.kgc01;
public class circle {
double r;public double getArea(){return 3.14*r*r;}
}
package com.kgc01;
public class TestCircle {public static void main(String[] args) {circle c = new circle();c.r=5;System.out.println("面积是:"+c.getArea());}
}
实例变量的特点
实例变量的赋值
实例变量和局部变量的区别
在类中的位置不一样
作用范围不一样
初始化的值不同
在内存中的位置不同
生命周期不同
package com.kgc01;
//需求: 声明员工类, 包含姓名 ,性别,薪资,三个实例变量, 并创建员工对象,打印员工信息
class Staff{ //声明员工类String name; //姓名String gender; //性别double price; //薪资
}
public class Demo03 {public static void main(String[] args) {Staff staff = new Staff(); //创建员工对象staff.name="张三";staff.gender="男";staff.price=10000;System.out.println("姓名:"+staff.name);System.out.println("性别:"+staff.gender);System.out.println("薪资:"+staff.price);} }
成员方法
方法也叫函数,是一个独立功能的定义,是一个类中最基本的功能单元,把一个功能封装成一个方法,可以实现代码的重用,减少代码量
方法的使用原则
成员方法的分类
语法格式
修饰符 返回值类型 方法名([参数列表:参数类型1 参数名1,参数类型2 参数名2...]){方法体;- [return 返回值;]- }
package com.kgc02;//定义计算两个整数和的方法,返回值类型,计算的结果是int,参数,两个都是int类型public class Demo01Add {public static void main(String[] args) {Add a = new Add();int sum = a.getAdd(1,2);//第一种System.out.println("sum = "+sum);//第二种System.out.println(a.getAdd(2,3));}}//加法类class Add{//方法public int getAdd(int a,int b){return a+b;}}```- 形参 : 在定义方法时,方法名后面括号中的变量名称为形式参数(简称形参),即形参出现在方法定义中- 实参 : 调用者方法中调用另一个方法时,方法名后边括号中的参数称为实际参数(简称实参),即实参出现在调用者方法中- 总结 : 调用时,需要通过方法名来识别调用哪个方法- 调用时,需要传"实参",实参的个数,类型顺序,需要与形参列表一一对应,如果方法没有形参,就不需要也不能传实参- 调用时,如果方法有返回值,可以接受或处理返回值的结果,如果方法返回值的类型是void,不需要也不能接收和处理返回值结果```java
package com.kgc02;
//比较两个整数是否相等: 需要定义一个方法,两个参数, 有返回值
class Equals{public boolean getEqual(int a,int b){return a==b;}
}
public class Demo02Equal {public static void main(String[] args) {Equals equals = new Equals();System.out.println(equals.getEqual(1,1));}
}
可变参数
package com.kgc02;public class Demo03 {public static void main(String[] args) {//实例化对象Sum s = new Sum();int array[] = {1,2,3,4,5,6,7,8};System.out.println(s.mySum(array));System.out.println(s.mySum2(array));}
}
class Sum{public int mySum(int[] a){int sum=0;for (int i=0;isum+=a[i];}return sum;}public int mySum2(int...arr){int sum=0;for (int i=0;isum+=arr[i];}return sum;}
}
//定义求1-n个整数中的最大值
package com.kgc02;
import java.util.Arrays;
public class Demo04Max {public static void main(String[] args) {int[] arr = new int[]{3,4,56,67,81,34,70};Max max = new Max();System.out.println(max.myMax(arr));System.out.println(max.myMax(1,3,454567,768,4356,678,435,4563));}
}
class Max{public int myMax(int...a){Arrays.sort(a);return a[a.length-1];}
}
在同一个类中,允许存在一个以上的同名方法,只要让他们的参数列表不同即可,与修饰符和返回值类型无关
参数列表 : 数据类型个数不同,数据类型不同,数据类型顺序不同
重载方法的调用 : JVM是通过方法的参数列表调用不同的方法
//比较两个数据是否相等,分别为两个byte类型,两个short类型,两个long类型
package com.kgc02;public class Demo05Equals {public static void main(String[] args) {MyEqual myEqual = new MyEqual();byte a1=10;byte a2=20;System.out.println(myEqual.equals(a1,a2));short b1=10;short b2=10;System.out.println(myEqual.equals(b1,b2));int c1=10;int c2=20;System.out.println(myEqual.equals(c1,c2));long d1=10;long d2=10;System.out.println(myEqual.equals(d1,d2));}
}
class MyEqual{public String equals(byte a,byte b){return a==b?"相等":"不相等";}public String equals(short a,short b){return a==b?"相等":"不相等";}public String equals(int a,int b){return a==b?"相等":"不相等";}public String equals(long a,long b){return a==b?"相等":"不相等";}
}
封装
属性的封装
属性封装的目的
实现步骤
权限修饰符
修饰符 | 在同一个类中 | 在同一个包中 | 子类中 | 任何地方 |
---|---|---|---|---|
private | 可以 | 不可以 | 不可以 | 不可以 |
默认修饰符 | 可以 | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
public | 可以 | 可以 | 可以 | 可以 |
package com.kgc01;
//定义一个学生类Student,声明 姓名和成绩,实例变量,私有化,提供get/set方法,getinfo方法用于返回学生的对象信息
public class Student {private String name;private int score;public void setName(String n){name=n;}public String getName(){return name;}//----------------------------------------------------------public void setScore(int s){score=s;}public int getScore() {return score;}//----------------------------------------------------------public String getInfo(){return "姓名:"+name+"\t"+"成绩:"+score;}
}
package com.kgc01;
import java.util.Scanner;//定义一个测试类TestStudent,main中创建一个可以装3个学生的对象的数组,并且按照学生成绩排序,显示学生信息
public class Test {public static void main(String[] args) {Scanner sc = new Scanner(System.in);//创建一个可以装3个学生的对象的数组Student[] s = new Student[3];//赋值s[0]=new Student();s[0].setName("张三");s[0].setScore(89);s[1]=new Student();s[1].setName("李四");s[1].setScore(98);s[2]=new Student();s[2].setName("王五");s[2].setScore(69);//先打印目前的顺序for (int i = 0; i < s.length; i++) {System.out.println(s[i].getInfo());}System.out.println("--------------------");//冒泡排序for (int i = 0; i < s.length; i++) {for (int j = 0; j < s.length-i-1; j++) {if (s[j].getScore()>s[j+1].getScore()){Student temp = s[j];s[j]=s[j+1];s[j+1]=temp;}}}for (int i = 0; i < s.length; i++) {System.out.println(s[i].getInfo());}}
}
构造器
public class Test01Student {private String name;private int age;//无参构造public Test01Student(){System.out.println("无参构造");}//有参构造public Test01Student(String n,int a){name=n;age=a;}
练习:
package com.kgc01;
/*1. 声明一个员工类:1. 属性: 编号,姓名,薪资,性别, 要求属性私有化,提供get / set方法2. 提供无参构造和有参构造3. 提供 getInfo()
2. 测试类中main中,分别用无参构造和有参构造 创建员工对象, 调用getInfo方法
*/
public class Test02Emp {private int id;private String name;private double price;private String gender;//无参public Test02Emp(){}//有参public Test02Emp(int a,String b,double c,String d){id=a;name=b;price=c;gender=d;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getInfo(){return "编号:"+getId()+"\t"+"姓名:"+getName()+"\t"+"薪资:"+getPrice()+"\t"+"性别:"+getGender()+"\t";}
}package com.kgc01;
//2. 测试类中main中,分别用无参构造和有参构造 创建员工对象, 调用getInfo方法
// private int id;
// private String name;
// private double price;
// private String gender;
public class Test02Demo {public static void main(String[] args) {Test02Emp emp = new Test02Emp();emp.setId(1);emp.setName("李四");emp.setPrice(2000);emp.setGender("女");System.out.println(emp.getInfo());Test02Emp emp1 = new Test02Emp(2,"张三",1000,"男");System.out.println(emp1.getInfo());}
}
this
public Test02Emp(int id, String name, double price, String gender) {this.id = id;this.name = name;this.price = price;this.gender = gender;}
java语言编写类的标准规范
public class ClassName{
//成员变量
//构造方法//无参构造 必须有//有参构造 建议有
//setXXX()
//getXXX()
//其他成员方法
}
包
继承的由来
继承 : 就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性,相同的行为
好处 :
格式 :
package com.kgc02;
/*
定义动物类,作为父类*/
public class Animal {//定义name属性public String name;//定义age属性public int age;//定义动物吃东西的方法public void eat(){System.out.println(age+"岁的"+name+"在吃东西--animal");}
}
-----------------------------------------------------------------------------package com.kgc02;
//定义猫类,继承动物
public class Cat extends Animal{//定义一个猫抓老鼠的方法public void catchMouse(){System.out.println("抓老鼠--cat");}
}
-----------------------------------------------------------------------------package com.kgc02;public class Test01 {public static void main(String[] args) {//创建一个猫类对象Cat cat = new Cat();//为猫类对象name属性进行赋值cat.name = "Tom";//为猫类对象age属性进行赋值cat.age = 1;//调用猫类方法cat.catchMouse();//调用毛类继承来的eat方法cat.eat();}
}
继承的特点 :
//声明父类:Person类 包含属性:姓名,年龄,性别 属性私有化,get/set 包含getinfo方法
package com.kgc03;
public class Person {private String name;private int age;private String gender;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getInfo(){return "姓名:"+name+"\t"+"年龄:"+age+"\t"+"性别:"+gender+"\t";}
}
//声明子类:Student类 继承Person类,新增属性score,属性私有化get/set 包含getinfo方法
package com.kgc03;
public class Student extends Person {private int score;public int getScore() {return score;}public void setScore(int score) {this.score = score;}@Overridepublic String getInfo() {return super.getInfo()+"成绩:"+getScore()+"\t";}
}
//声明子类:Teacher类 继承Person类,新增属性salary,属性私有化get/set 包含getinfo方法
package com.kgc03;
public class Teacher extends Person{private int salary;public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}@Overridepublic String getInfo() {return super.getInfo()+"薪资:"+salary+"\t";}
}
//测试类
package com.kgc03;public class Test03 {public static void main(String[] args) {Student st = new Student();st.setName("张三");st.setAge(18);st.setGender("男");st.setScore(100);System.out.println(st.getInfo());Teacher t = new Teacher();t.setName("李四");t.setAge(28);t.setGender("女");t.setSalary(10000);System.out.println(t.getInfo());}
}
static
是一个成员修饰符,可以修饰类的成员,成员变量,成员方法
被修饰的成员是属于类的,而不是单单属于某个对象,可以不用靠创建对象来使用
静态方法
[其他修饰符] static 返回值类型 方法名([参数列表]){//方法体
}
package com.kgc01;public class Demo01 {public static void main(String[] args) {Son s = new Son();s.fun(); //有警告,没错误也可以运行 Son.fun(); //建议使用 类名.方法名//Son.method(); 非静态不能使用s.method();}
}
class Son{private int a;private static int b;public static void fun(){
// 静态方法只能访问静态变量----否则报错
// System.out.println(a);
// System.out.println(this.a);
// method();System.out.println(b);System.out.println("Son:fun()");}public void method(){System.out.println("Son:method()");}
}
静态变量
package com.kgc01;
public class Demo02 {public static void main(String[] args) {//无需创建对象//静态变量是成员变量的一种,静态变量存储在方法区中,则它在类加载时就会进行初始化Chinese c1 = new Chinese("小红");Chinese c2 = new Chinese("小明");System.out.println("国家:"+c1.getCountry()+",姓名:"+c1.getName());System.out.println("国家:"+c2.getCountry()+",姓名:"+c2.getName());c1.setCountry("中国"); //两个对象共享,一个对象修改,会影响另一个对象System.out.println("国家:"+c1.getCountry()+",姓名:"+c1.getName());System.out.println("国家:"+c2.getCountry()+",姓名:"+c2.getName());// 所以静态变量访问的时候不需要创建实例(对象),直接可以通过类名来访问Chinese.setCountry("China"); //通过类名. 访问可读性更好System.out.println("国家:"+Chinese.getCountry()+",姓名:"+c1.getName());System.out.println("国家:"+Chinese.getCountry()+",姓名:"+c2.getName());}
}
class Chinese{//静态成员属于整个类所有,类的所有对象所共享private static String country="中华人民共和国";//非静态不会被共享private String name;public Chinese(String name) {this.name = name;}public static String getCountry() {return country;}public static void setCountry(String country) {Chinese.country = country;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
抽象类
抽象 : 即不具体,或无法具体
抽象方法 : 没有方法体的方法
抽象类 : 被abstract修饰的抽象类
[权限修饰符] abstract class 类名{}//父类
[权限修饰符] abstract class 类名 extends 父类{}
[其他修饰符] abstract 返回值类型 方法名 ([形参列表]); //注意:抽象方法没有方法体
继承抽象类的子类,必须重写父类的抽象方法,否则该子类也必须声明为抽象类,最终必须有子类实现该父类的抽象方法,否则,从最初的的父类到最终的子类都不能创建对象,失去意义
package com.kgc01;
abstract class Animal{public abstract void run();
}
class Cat extends Animal{@Override//重写----实现父类没有实现的方法public void run() {System.out.println("小猫在墙上走");}
}
public class Demo03 {public static void main(String[] args) {//创建子类对象Cat cat = new Cat();//调用run方法cat.run();}
}
注意事项
package com.kgc01;
abstract class Graphic{private String name;public Graphic(String name) {this.name = name;}public abstract double getArea();public abstract double getPerimeter();public String getInfo(){return "名称:"+name+"\t"+"面积:"+getArea()+"\t"+"周长:"+getPerimeter()+"\t";}
}class Circle extends Graphic{private double radius;public Circle(String name, double radius) {super(name);this.radius = radius;}@Overridepublic double getArea() {return radius*radius*3.14;}@Overridepublic double getPerimeter() {return radius*6.28*100/100;}public String getInfo() {return super.getInfo()+"半径:"+radius+"\t";}
}class Rectange extends Graphic{public double length;public double width;public Rectange(String name, double length, double width) {super(name);this.length = length;this.width = width;}@Overridepublic double getArea() {return length*width;}@Overridepublic double getPerimeter() {return 2*(length+width);}public String getInfo() {return super.getInfo()+"长:"+length+"\t"+"宽:"+width+"\t";}
}public class Demo04 {public static void main(String[] args) {Rectange rec = new Rectange("长方形",10,20);System.out.println(rec.getInfo());Circle cir = new Circle("圆",10);System.out.println(cir.getInfo());}
}
package com.kgc01;
/*
练习:
1. 声明抽象父类: Person,包含抽象方法:1. public abstract void walk();2. public abstract void ea();
2. 声明子类 Man, 继承 Person1. 重写walk(): 大步流星的走2. 重写eat(): 狼吞虎咽的吃饭3. 新增方法: public void smoke() 吞云吐雾
3. 声明子类 Woman, 继承Person1. 重写walk(): 婀娜多姿的走2. 重写eat(): 细嚼慢咽的吃饭3. 新增方法: public void buy() 买买买
4. 测试类中创建子类对象,调用 方法测试*/
abstract class Person{public abstract void walk();public abstract void eat();
}class Man extends Person{@Overridepublic void walk() {System.out.println("大步流星的走");}@Overridepublic void eat() {System.out.println("狼吞虎咽的吃饭");}public void smoke(){System.out.println("吞云吐雾");}
}class Woman extends Person{@Overridepublic void walk() {System.out.println("婀娜多姿的走");}@Overridepublic void eat() {System.out.println("细嚼慢咽的吃饭");}public void buy(){System.out.println("买买买");}
}public class Demo05 {public static void main(String[] args) {Man man = new Man();man.walk();man.eat();man.smoke();System.out.println("-----------------------");Woman woman = new Woman();woman.walk();woman.eat();woman.buy();}
}
多态
多态是指同一行为,具有多个不同的表现形式
前提
父类类型 变量名 = new 子类对象;
变量名.方法名(); //这个方法是父类中声明的,子类中重写的方法
多态的体现
package com.kgc02;
abstract class Animal2{public abstract void eat();
}class Cat extends Animal2{@Overridepublic void eat() {System.out.println("吃鱼");}public void catchMouse(){System.out.println("捉老鼠");}
}class Dog extends Animal2{@Overridepublic void eat() {System.out.println("吃骨头");}
}public class Demo01 {public static void main(String[] args) {//多态的形式创建对象Animal2 a1 = new Cat();//调用Cat中的eata1.eat();//a1.catchMouse();是子类的扩展的方法,父类中没有Animal2 a2 = new Dog();a2.eat();showAnimal2Eat(a1);showAnimal2Eat(a2);}// public static void showCatEat(Cat a){
// a.eat();
// }public static void showAnimal2Eat(Animal2 b){b.eat();}
}
多态的好处
package com.kgc02;public class Demo02 {public static void main(String[] args) {Animal2[] all = new Animal2[4]; //可以存储各种Animal子类对象all[0]=new Cat();all[1]=new Cat();all[2]=new Dog();all[3]=new Dog();for (int i = 0; i < all.length; i++) {all[i].eat();}}
}
//练习
//声明一个抽象父类Traffic,包含抽象方法 public abstract void driver()
//声明子类Car,Bicycle,并重写dirver方法
//在测试类main中,创建一个数组,有各种交通工具,遍历调用driver方法,模拟马路上跑的各种交通工具
package com.kgc02;abstract class Traffic{public abstract void driver();
}
class Bicycle extends Traffic{@Overridepublic void driver() {System.out.println("自行车");}
}
class Car extends Traffic{@Overridepublic void driver() {System.out.println("汽车");}
}
public class Demo03 {public static void main(String[] args) {Traffic[] traffic = new Traffic[]{new Car(),new Car(),new Bicycle(),new Bicycle()};for (int i = 0; i < traffic.length; i++) {traffic[i].driver();}}
}
父子类之间的类型转换
向上转型
向下转型
子类类型 变量名 = (子类类型) 父类变量名;//向上转型
Animal a = new Cat();
//向下转型
Cat c = (Cat) a;
instanceof
为避免ClassCastException的发生,给引用变量做类型的校验,只要用instanceof判断返回为true,那么强制转换类型就是安全的,不会报错
变量名/对象名 instanceof 数据类型;
//如果属于就返回true,如果不属于就返回falseAniamls a = new Dog();
if(a instanceof Cat){Cat cc = (Cat) a;cc.catchMouse();
}else if(a instanceof Dog){Dog dd = (Dog) a;dd.watchHouse();
}
它是所有类的根类,即所有类的父类
toString() 默认情况返回的是对象进行时的类型,重写返回对象的详细信息来代替之前的getInfo
equals() 判断两个对象是否为同一个对象 和==类似
package com.kgc03;public class Person {private String name;private int age;public Person(String name, int age) {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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object obj) {Person p = (Person) obj;if (this.name==p.name){return true;}else {return false;}}
}
//测试类
public class Test01 {public static void main(String[] args) {Person p1 = new Person("小明",18);System.out.println(p1);System.out.println(p1.toString());Person p2 = new Person("小红",20);System.out.println(p1==p2);System.out.println(p1.equals(p2));Person p3 = p1;System.out.println(p1==p3);System.out.println(p1.equals(p3));}
}
接口 : java语言中一种引用类型,是方法的集合,主要是封装方法,它与定义类的方式相似 interface关键字,他也会被编译成class文件,但一定要明确它不是类,是另外一种数据类型(数组,类,接口)
Java里的接口, 就是抽象方法和常量值的集合(简单理解为接口就是一种特殊的抽象类)
[修饰符] interface 接口名 {//静态常量//抽象方法//默认方法//静态方法//私有方法
}
实现接口
[修饰符] class 实现类 implements 接口 {//重写接口中的抽象方法[必须],如果实现类是抽象类,name可以不重写//重写接口中默认方法[可选]
}[修饰符] class 实现类 extends 父类 implements 接口 {//重写接口中的抽象方法[必须],如果实现类是抽象类,name可以不重写//重写接口中默认方法[可选]
}
非抽象类实现接口
//练习
//声明一个接口LiveAble//包含两个抽象方法 void eat();void breathe();//包含一个默认方法default void sleep(); 睡觉//包含静态方法 static void drink(); 喝水
package com.kgc04;
public interface LiveAble {public abstract void eat();public abstract void breathe();public default void sleep(){System.out.println("不动");}public static void drink(){System.out.println("喝水");}
}package com.kgc04;
public class Animal implements LiveAble{@Overridepublic void eat() {System.out.println("吃东西");}@Overridepublic void breathe() {System.out.println("吸入氧气,呼出二氧化碳");}@Overridepublic void sleep() {System.out.println("闭上眼睡觉");}
}package com.kgc04;
public class Plant implements LiveAble{@Overridepublic void eat() {System.out.println("吸收营养");}@Overridepublic void breathe() {System.out.println("吸入二氧化碳,呼出氧气");}
}package com.kgc04;
public class Test {public static void main(String[] args) {//创建实现类(子类) 对象Animal a = new Animal();a.eat();a.sleep();a.breathe();System.out.println("------------------------");//创建实现类 对象Plant p = new Plant();p.eat();p.sleep();p.breathe();System.out.println("------------------------");//通过接口名,调用静态方法LiveAble.drink();}
}
异常 : 指的是程序在执行过程中,出现的非正常的情况,如果不处理最终会导致JVM的非正常停止
对于异常有两种解决方法,一种是遇到错误就终止程序的运行,另一种是由程序员在编写程序时就考虑到错误的检测,错误消息的提示,以及错误的处理
异常的根类 : java.lang.Throwable,其子下有两个子类,java.lang.Error与java.lang.Exception,平时所说的异常指的是java.lang.Exception
Throwable 中常用的方法
Exception 异常的分类
java异常处理的5个关键字 : try catch finally , throw throws
try…catch 捕获异常
try{//可能出现异常的代码
}catch(异常类型 e){//处理异常的代码//记录日志/打印异常信息/继续抛出异常
}
//例1
package com.kgc01;
import java.io.File;
import java.io.FileNotFoundException;public class TestException {public static void main(String[] args) {File f = new File("d:\\a.txt");try{if (!f.exists()){throw new FileNotFoundException("d:\\a.txt"+"不存在");}}catch (FileNotFoundException e){System.out.println(e.getMessage());}}
}
//例2
package com.kgc01;
public class Test01 {public static void main(String[] args) {int[] arr = new int[2];//下标越界try{for (int i = 0; i <=arr.length ; i++) {System.out.println(arr[i]);}}catch (ArrayIndexOutOfBoundsException e){System.out.println(e);//出现错误的下标System.out.println(e.getStackTrace());//错误地址}}
}
//例3
package com.kgc01;
import java.util.Scanner;public class Test02 {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.print("请输入一个整数:");//将可能出现错误的地方try起来(输入字符串)try{int a = sc.nextInt();System.out.println(a);}catch(Exception e){//捕获输出错误类型System.out.println(e);}//不影响程序的运行System.out.println("正常运行");}
}
//注:Exception是所有错误的父类,不知道错误类型可以使用Exception
throws 抛出异常,交给上级处理,如果都不处理,最终会交给JVM
package com.kgc01;import java.util.InputMismatchException;
import java.util.Scanner;public class Test03 {public static void main(String[] args) {try{getInt();}catch (ArrayIndexOutOfBoundsException e){System.out.println("请输入一个整数");}}public static void getInt() throws InputMismatchException{Scanner sc = new Scanner(System.in);System.out.print("请输入一个整数:");int a = sc.nextInt();System.out.println(a);System.out.println("正常运行");}
}
finally
有一些特定的代码,不论是否出现异常,都要执行的代码
try{//代码
}catch(){//代码
}finally{//代码
}
package com.kgc01;import java.util.InputMismatchException;
import java.util.Scanner;public class Test03 {public static void main(String[] args) {try{getInt();}catch (InputMismatchException e){System.out.println("请输入一个整数");}finally {System.out.println("欢迎下次光临");}}public static void getInt() throws InputMismatchException{Scanner sc = new Scanner(System.in);System.out.print("请输入一个整数:");int a = sc.nextInt();System.out.println(a);System.out.println("正常运行");}
}
异常处理
需求概述:
根据输入速率和正确率将玩家分为不同级别
级别越高,一次显示的字符数越多,玩家正确输入一次的得分也越高
规定时间内完成规定次数的输入,正确率达到规定要求,则升级
玩家最高级别为6级、初始级别一律为1级
用户错误输入一次,游戏结束
核心代码
package com.kgc;
//生成随机的字符串
import java.util.Random;
import java.util.Scanner;public class QuickHit {public static void main(String[] args) {//创建random随机对象Random random = new Random();//可改变长度的字符串StringBuffer buffer = new StringBuffer();for (int i = 0; i < 1; i++) { //控制字符串的长度//产生一个随机数int rand = random.nextInt(4);//控制字符串的难易程度//根据随机数拼接字符串switch (rand){case 0:buffer.append(">");break;case 1:buffer.append("<");break;case 2:buffer.append("*");break;case 3:buffer.append("&");break;}System.out.println("buffer="+buffer);Scanner sc = new Scanner(System.in);System.out.print("请输入:");//输入前开始计时(从19700101 00:00:00开始)long l1 = System.currentTimeMillis();String in = sc.next();//输入后结束计时long l2 = System.currentTimeMillis();//打印时间差long l = (l2-l1)/1000;System.out.println("所用时长"+l+"秒");if (in.equals(buffer.toString())){System.out.println("相同");}else {System.out.println("不相同");}}}
}
游戏项目
public class Test {public static void main(String[] args) {//创建一个玩家Player player = new Player();player.play();}
}
public class Leavel {private int leavelNo;//级别号private int strLength;//各级别一次输出字符串的长度private int strTimes;//各级别输入字符串的次数private int timeLimit;//各级别闯关的时间限制private int perScore;//各级别成功输入一次的字符串后增加的分值public Leavel(int leavelNo, int strLength, int strTimes, int timeLimit, int perScore) {this.leavelNo = leavelNo;this.strLength = strLength;this.strTimes = strTimes;this.timeLimit = timeLimit;this.perScore = perScore;}public int getLeavelNo() {return leavelNo;}public void setLeavelNo(int leavelNo) {this.leavelNo = leavelNo;}public int getStrLength() {return strLength;}public void setStrLength(int strLength) {this.strLength = strLength;}public int getStrTimes() {return strTimes;}public void setStrTimes(int strTimes) {this.strTimes = strTimes;}public int getTimeLimit() {return timeLimit;}public void setTimeLimit(int timeLimit) {this.timeLimit = timeLimit;}public int getPerScore() {return perScore;}public void setPerScore(int perScore) {this.perScore = perScore;}
}
public class LevelParam {public final static Level[] levels = new Level[6]; //对应6个级别,不可修改的,加载类时同时加载static {levels[0] = new Level(1,1,6,30,1);levels[1] = new Level(2,2,5,25,2);levels[2] = new Level(3,3,4,20,3);levels[3] = new Level(4,4,3,15,5);levels[4] = new Level(5,5,2,10,8);levels[5] = new Level(6,6,1,5,20);}
}
import java.util.Scanner;
public class Player {private int levelNo;//级别private int curScore;//当前积分private long startTime=0;//各级别开始时间private int usedTime;//各级别已经用的时间public int getLevelNo() {return levelNo;}public long getStartTime() {return startTime;}public void setStartTime(long startTime) {this.startTime = startTime;}public void setLevelNo(int levelNo) {this.levelNo = levelNo;}public int getCurScore() {return curScore;}public void setCurScore(int curScore) {this.curScore = curScore;}public int getUsedTime() {return usedTime;}public void setUsedTime(int usedTime) {this.usedTime = usedTime;}public void play(){Game game = new Game(this);Scanner sc = new Scanner(System.in);//外层 循环控制级别for (int i = 0; i < LevelParam.levels.length; i++) {//1.晋级levelNo+=1;//2.晋级后计时清零,积分清零startTime = System.currentTimeMillis();curScore=0;//内层 循环控制循环次数//3.控制一个级别玩的次数for (int j = 0; j < LevelParam.levels[levelNo-1].getStrTimes(); j++) {//3.1 游戏输出字符串String outStr = game.printStr();//3.2 接收用户输入String inStr = sc.next();//3.3 游戏中判断玩家输入的是否正确并输出相应的结果信息game.printResult(outStr,inStr);}}}}
import java.util.Random;//游戏类
public class Game {public Player player;//构造方法,传入玩家public Game(Player player) {this.player = player;}//输出指定级别,规定长度的字符串public String printStr(){int strLength = LevelParam.levels[player.getLevelNo()-1].getStrLength(); //取到对应玩家的长度StringBuffer buffer = new StringBuffer();Random random = new Random();//通过循环生成 要输出的字符串//外循环控制字符串的长度for (int i = 0; i < strLength; i++) {//产生随机数int rand = random.nextInt(strLength);//根据随机数拼接字符串switch(rand){case 0:buffer.append(">");break;case 1:buffer.append("<");break;case 2:buffer.append("*");break;case 3:buffer.append("&");break;case 4:buffer.append("%");break;case 5:buffer.append("#");break;}}//输出字符串System.out.println(buffer);//返回字符串return buffer.toString();}//判断玩家输入是否正确,并输出相应的结果信息public void printResult(String out,String in){//判断是否输入正确boolean flag;if(out.equals(in)){flag=true;}else {flag=false;}//如果输入正确if (flag){long currenttime=System.currentTimeMillis(); //获取当前时间的毫秒// 判断是否超时// 已用时long yys=(currenttime-player.getStartTime())/1000;//System.out.println(yys);// 级别时间long jbsj=LevelParam.levels[player.getLevelNo()-1].getTimeLimit();if (yys>jbsj) {System.out.println("太慢了");System.exit(1); // 系统退出}else{//如果没有超时//取出之前的积分+过一次给的分数int jf = player.getCurScore()+LevelParam.levels[player.getLevelNo()-1].getPerScore();//计算积分player.setCurScore(jf);//计算已用时player.setUsedTime((int)yys);System.out.println("输入正确,您的级别是:"+player.getLevelNo()+"\t"+"您的积分是:"+player.getCurScore()+"\t"+"已用时间:"+player.getUsedTime());//判断用户是否已经闯关到最后一关if(player.getLevelNo()==6){//取出当前积分和,最后一关玩的次数*每次的分数,如果相等就通关了int dqjf= player.getCurScore();int tgf = LevelParam.levels[player.getLevelNo()-1].getStrTimes()*LevelParam.levels[player.getLevelNo()-1].getPerScore();if (dqjf==tgf){System.out.println("恭喜通关!");System.exit(0);}}}}else {System.out.println("错误,退出");System.exit(1);}}
}