三、接口与异常
- 下面程序抛出一个异常并捕捉它。请替换【代码】为java代码。
public class Main {
static void proc() throws IllegalAccessException{
System.out.println("inside proc");
throw new IllegalAccessException("demo");
}
public static void main(String[] args) {
try {
proc();
}catch(IllegalAccessException e){
System.out.println("捕获"+e);
}
}
}
- 按模板要求,将 【代码】部分替换为Java代码
class NoLowerLeter extends Exception//类声明,声明一个Exception的子类NoLowerLetter
{
public void print() {
System.out.printf("%c",'#');
}
}
class NoDigit extends Exception//类声明,声明一个Exception的子类NoDigit
{
public void print() {
System.out.printf("%c", '*');
}
}
class People{
void printLetter(char c) throws NoLowerLetter{
if(c<'a'||c>'z') {
NoLowerLetter noLowerLetter=new NoLowerLetter();//创建NoLowerLetter类型对象
throw noLowerLetter;//抛出noLowerLetter
}
else {
System.out.print(c);
}
}
void printDigit(char c)throws NoDigit{
if(c<'1'||c>'9') {
NoDigit noDigit=new NoDigit();//创建NoDigit类型对象
throw noDigit;//抛出noDigit
}
else {
System.out.print(c);
}
}
}
public class Main{
public static void main(String[] args) {
People people=new People();
for(int i=0;i<128;i++) {
try {
people.printLetter((char)i);
}
catch(NoLowerLetter e) {
e.print();
}
}
for(int i=0;i<128;i++) {
try {
people.printDigit((char)i);
}
catch(NoDigit e) {
e.print();
}
}
}
}
- 计算成绩
体操比赛计算选手成绩的办法是去掉一个最高分和最低分后再计算平均分,而学校考察一个班级的某科目的考试情况时,是计算全班同学的平均成绩。体操Gymnastics类和学校School类都实现了ComputerAverage接口,但是实现的方式不同。
裁判测试程序样例:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
double a[] ;
double b[];
Scanner sc=new Scanner(System.in);
String str1=sc.nextLine();
String[] str_a=str1.split(" ");
a=new double[str_a.length];
for(int i=0;i<str_a.length;i++)
a[i]=Double.parseDouble(str_a[i]);
String str2=sc.nextLine();
String[] str_b=str2.split(" ");
b=new double[str_b.length];
for(int i=0;i<str_b.length;i++)
b[i]=Double.parseDouble(str_b[i]);
CompurerAverage computer;
computer=new Gymnastics();
double result=computer.average(a); //computer调用average(double x[])方法,将数组a传递给参数x
//System.out.printf("%n");
System.out.printf("体操选手最后得分:%5.3f\n",result);
computer=new School();
result=computer.average(b); //computer调用average(double x[])方法,将数组b传递给参数x
System.out.printf("班级考试平均分数:%-5.2f",result);
}
}
/* 请在这里填写答案 */
//定义接口
//定义Gymnastics 类实现接口
//定义School类实现接口
//定义接口
interface ComputerAverage{
public double average(double x[]);
}
//定义Gymnastics 类实现接口
class Gymnastics implements ComputerAverage{
@Override
public double average(double[] x) {
double max = x[0];
double min = x[0];
double sum = 0;
int maxIndex = 0,minIndex = 0;
for (int i = 0; i < x.length; i++) {
sum += x[i];
if(x[i] > max) {
max = x[i];
maxIndex = i;
}
if(x[i] < min) {
min = x[i];
minIndex = i;
}
}
sum -= x[maxIndex];
sum -= x[minIndex];
return sum / (x.length-2);
}
}
//定义School类实现接口
class School implements ComputerAverage{
@Override
public double average(double[] x) {
double sum = 0;
for (int i = 0; i < x.length; i++) {
sum += x[i];
}
return sum / x.length;
}
}
- 货车的装载量 (15分)
卡车要装载一批货物,货物由三种商品组成:电视、计算机、洗衣机。卡车需要计算出整批货物的重量。
要求有一个ComputerWeight接口,该接口中有一个方法:
public double computeWeight()
######有三个实现该接口的类:Television、Computer和WashMachine. 这三个类通过实现接口给出自重。这3个类都有属性weight,并通过构造方法初始化,其中Television类的computeWeight()方法,返回weight值;Computer的computeWeight()方法,返回2倍weight值;WashMachine的computeWeight()方法,返回3倍weight值
有一个卡车Truck类,该类用ComputeWeight接口类型的数组作为成员(Truck类面向接口),那么该数组的元素就可以存放Television对象的引用、Computer对象的引用或WashMachine
对象的引用。程序能输出Truck对象所装载的货物的总重量。
裁判测试程序样例:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
ComputerWeight[] goods=new ComputerWeight[650]; //650件货物
double[] a=new double[3];//存储Television,Computer,WashMachine对象weight属性初值
Scanner sc=new Scanner(System.in);
String str1=sc.nextLine();
String[] str_a=str1.split(" ");
for(int i=0;i<3;i++)
a[i]=Double.parseDouble(str_a[i]);
for(int i=0;i<goods.length;i++) { //简单分成三类
if(i%3==0)
goods[i]=new Television(a[0]);
else if(i%3==1)
goods[i]=new Computer(a[1]);
else if(i%3==2)
goods[i]=new WashMachine(a[2]);
}
Truck truck=new Truck(goods);
System.out.printf("货车装载的货物重量:%-8.5f kg\n",truck.getTotalWeights());
goods=new ComputerWeight[68]; //68件货物
for(int i=0;i<goods.length;i++) { //简单分成两类
if(i%2==0)
goods[i]=new Television(a[0]);
else
goods[i]=new WashMachine(a[2]);
}
truck.setGoods(goods);
System.out.printf("货车装载的货物重量:%-8.5f kg\n",truck.getTotalWeights());
}
}
/* 请在这里填写答案 */
//定义 接口ComputerWeight 代码写在下面
//定义类 Television 实现接口ComputerWeight 代码写在下面
//定义类Computer实现接口ComputerWeight 代码写在下面
//定义类WashMachine 实现接口ComputerWeight 代码写在下面
//类Truck ,实现相关成员方法 代码写在下面
//定义 接口ComputerWeight 代码写在下面
interface ComputerWeight{
public double computeWeight();
}
//定义类 Television 实现接口ComputerWeight 代码写在下面
class Television implements ComputerWeight{
double weight;
public Television(double weight) {
this.weight = weight;
}
@Override
public double computeWeight() {
return weight;
}
}
//定义类Computer实现接口ComputerWeight 代码写在下面
class Computer implements ComputerWeight{
double weight;
public Computer(double weight) {
this.weight = weight;
}
@Override
public double computeWeight() {
return 2 * weight;
}
}
//定义类WashMachine 实现接口ComputerWeight 代码写在下面
class WashMachine implements ComputerWeight{
double weight;
public WashMachine(double weight) {
super();
this.weight = weight;
}
@Override
public double computeWeight() {
return 3 * weight;
}
}
//类Truck ,实现相关成员方法 代码写在下面
class Truck{
ComputerWeight[] computerWeights;
public Truck(ComputerWeight[] computerWeights) {
this.computerWeights = computerWeights;
}
public void setGoods(ComputerWeight[] computerWeights) {
this.computerWeights = computerWeights;
}
public double getTotalWeights() {
double sum = 0;
for (int i = 0; i < computerWeights.length; i++) {
sum += computerWeights[i].computeWeight();
}
return sum;
}
}
- 锥体体积计算 (10分)
定义一个接口IgetArea,有方法double getArea(); 用于计算形状面积,定义另外一个接口IgetPerimeter,有方法 double getPerimeter();用于计算形状周长。接口IShape 有常量 PI=3.14,继承 接口IgetArea和IgetPerimeter
定义一个直角三角形类(regular triangle)RTriangle类,实现接口IShape。两条直角边作为Triangle类的私有成员,类中包含参数为2条直角边的构造方法。
定义一个圆形类Circle,实现接口IShape。半径r作为Circle类的私有成员,类中包含参数为r的构造方法。
定义一个锥体类Cone ,类中有一个IShape类型的成员IS,和锥体高h的成员,包含一个构造方法给IS和h赋初值,另外还有一个 public double getVolume() 方法,用于计算锥体的体积
裁判测试程序样例:
import java.lang.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double a = input.nextDouble();
double b = input.nextDouble();
double r=input.nextDouble();
double h=input.nextDouble();
IShape[] is=new IShape[2];
is[0]=new RTriangle(a,b);
is[1]=new Circle(r);
Cone cn1;
for(int i=0;i<2;i++) {
cn1=new Cone(is[i],h);
String vol=String.format("%.2f", cn1.getVolume());
String p=String.format("%.2f",is[i].getPerimeter());
System.out.println("Volume"+i+"="+vol+" Perimeter="+p);
}
}
}
/* 将其他代码填写在下面 */
interface IgetArea{
double getArea();
}
interface IgetPerimeter{
double getPerimeter();
}
interface IShape extends IgetArea,IgetPerimeter {
final double PI = 3.14;
public double getPerimeter();
public double getArea();
}
class RTriangle implements IShape{
private double side1,side2;
public double getSide1() {
return side1;
}
public double getSide2() {
return side2;
}
public void setSide1(double side1) {
this.side1 = side1;
}
public void setSide2(double side2) {
this.side2 = side2;
}
public RTriangle(double side1, double side2) {
this.side1 = side1;
this.side2 = side2;
}
@Override
public double getPerimeter() {
double side3 = Math.sqrt(side1*side1+side2*side2);
return side1 + side2 + side3;
}
@Override
public double getArea() {
return side1 * side2 * 1/2;
}
}
class Circle implements IShape{
private double r;
public final double PI = 3.14;
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
public Circle(double r) {
this.r = r;
}
@Override
public double getPerimeter() {
return 2 * PI *r;
}
@Override
public double getArea() {
return PI * r * r;
}
}
class Cone{
double h;
IShape IS;
public Cone(IShape IS,double h) {
this.IS = IS;
this.h = h;
}
public double getVolume() {
return IS.getArea() * h * 1.0/3;
}
}
- 系统常用标准异常类 (10分)
常用异常类NumberFormatException,IndexOutOfBoundsException、ArithmeticException等,本程序,建立一个Test_Exception类,里面有一个test方法,用于检测以上异常对象的发生并输出相应信息。 比如发生NumberFormatException异常,输出"数据格式异常";发生IndexOutOfBoundsException异常,输出"越界异常";发生ArithmeticException异常,输出"算术运算异常"。 ##。# Test_Exception类定义:
class Test_Exception{
void test() {
int n = 0,m = 0,t = 1000;
int[] a=new int[4];
int[] b=null;
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
try {
m = Integer.parseInt(str);
t=t/m;
a[m]=m;
b[0]=m;
}
//catch部分需要你们自己填写
catch(...){...}
catch(...){...}
catch(...){...}
catch(Exception e) {
System.out.println("Exception:"+e.getMessage());
} //先catch子类Exception,后catch父类
}
}
裁判测试程序样例:
在这里给出函数被调用进行测试的例子。例如:
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Test_Exception te=new Test_Exception();
te.test();
}
}
/* 请在这里编写完整 Test_Exception类 */
class Test_Exception{
void test() {
int n = 0,m = 0,t = 1000;
int[] a=new int[4];
int[] b=null;
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
try {
m = Integer.parseInt(str);
t=t/m;
a[m]=m;
b[0]=m;
}
//catch部分需要你们自己填写
catch(NumberFormatException e){
System.out.println("数据格式异常");
}
catch(IndexOutOfBoundsException e){
System.out.println("越界异常");
}
catch(ArithmeticException e){
System.out.println("算术运算异常");
}
catch(Exception e) {
System.out.println("Exception:"+e.getMessage());
} //先catch子类Exception,后catch父类
}
}
- 检查物品是否为次品 (10分)
工厂检查产品次品的设备,如果发现是次品就发出警告。编程模拟设备发现次品过程。
编写一个产品类Product,有成员变量name和isDefect(是否次品),有get和set方法。
编写一个Exception的子类DefectException,该子类message属性,有构造方法DefectException() 将"次品"赋值给message成员,有toShow()方法输出message的值
编写一个Machine类,该类的方法checkProduct(Product product)当发现参数product为次品时(product的 isDefect属性为true),将抛出DefectException异常对象。
程序在主类的main方法中的try…catch语句的try部分让Machine类的实例调用checkProduct方法,如果发现次品就在try…catch语句的catch部分处理次品。
设计的类定义:
class Product { //完整编写
boolean isDefect;
String name;
//补充代码
}
class DefectException extends Exception { //完整编写
String message;
//补充代码
}
class Machine {
public void checkProduct(Product product) throws DefectException {
if(product.isDefect()) {
DefectException defect=new DefectException();
//【代码1】 //抛出defect
}
else {
System.out.print(product.getName()+"不是次品! ");
}
}
}
裁判测试程序样例:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Machine machine = new Machine();
String name[] ;
Scanner sc=new Scanner(System.in);
name=sc.nextLine().split(" ");
Product [] products = new Product[name.length]; //检查6件货物
for(int i= 0;i<name.length;i++) {
products[i] = new Product();
if(i%2==0) {
products[i].setIsDefect(false);
products[i].setName(name[i]);
}
else {
products[i].setIsDefect(true);
products[i].setName(name[i]);
}
}
for(int i= 0;i<products.length;i++) {
try {
machine.checkProduct(products[i]);
System.out.println(products[i].getName()+"检查通过");
}
catch(DefectException e) {
e.toShow();//【代码2】 //e调用toShow()方法
System.out.println(products[i].getName()+"被禁止!");
}
}
}
}
/* 将完整的Product类, DefectException类 和Machine类写在下面*/
class Product { //完整编写
boolean isDefect;
String name;
public boolean isDefect() {
return isDefect;
}
public String getName() {
return name;
}
public void setIsDefect(boolean isDefect) {
this.isDefect = isDefect;
}
public void setName(String name) {
this.name = name;
}
}
class DefectException extends Exception { //完整编写
String message;
public DefectException() {
}
public DefectException(String message) {
this.message = message;
}
public void toShow() {
System.out.print("次品!");
}
}
class Machine {
public void checkProduct(Product product) throws DefectException {
if(product.isDefect()) {
DefectException defect=new DefectException();
throw defect;
}
else {
System.out.print(product.getName()+"不是次品! ");
}
}
}
- jmu-Java-06异常-多种类型异常的捕获 (10分)
如果try块中的代码有可能抛出多种异常,且这些异常之间可能存在继承关系,那么在捕获异常的时候需要注意捕获顺序。
补全下列代码,使得程序正常运行。
裁判测试程序:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String choice = sc.next();
try {
if (choice.equals("number"))
throw new NumberFormatException();
else if (choice.equals("illegal")) {
throw new IllegalArgumentException();
} else if (choice.equals("except")) {
throw new Exception();
} else
break;
}
/*这里放置你的答案*/
}//end while
sc.close();
}
catch (NumberFormatException e) {
System.out.println("number format exception");
System.out.println(e);
}catch(IllegalArgumentException e) {
System.out.println("illegal argument exception");
System.out.println(e);
}catch(Exception e) {
System.out.println("other exception");
System.out.println(e);
}
四、面向对象高级程序设计
- 本题要求主线程退出时,在main方法中所启动的线程t1也要自动结束。
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new PrintTask());
t1.setDaemon(true);
t1.start();
System.out.println(Thread.currentThread().getName() + " end");
}
}
- 本题目要求t1线程打印完后,才执行主线程main方法的最后一句System.out.println(Thread.currentThread().getName()+" end");
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new PrintTask());
t1.start();
t1.join();
System.out.println(Thread.currentThread().getName()+" end");
}
}
- 下列程序使用泛型机制创建一个数组列表对象,并向其添加三个元素,利用迭代器遍历该数组列表,请把程序补充完整。
import java.util.*;
public class Main{
public static void main(String[] args) {
List<String> al=new ArrayList<String>();
al.add("red");
al.add("yellow");
al.add("blue");
ListIterator< String > listIter=al.listIterator();
while(listIter.hasNext())
System.out.print(listIter.next()+" ");
}
}
- jmu-Java-07多线程-互斥访问
裁判测试程序:
import java.util.Scanner;
/*你的代码,即Account类的代码*/
/*系统已有代码,无需关注*/
class Account{
private int balance;
public int getBalance() {
return balance;
}
Account(int balance){
this.balance = balance;
}
public synchronized void deposit(int money) {
balance += money;
}
public synchronized void withdraw(int money) {
balance -= money;
}
}
- jmu-Java-07多线程-同步访问
裁判测试程序:
import java.util.Scanner;
//这里是已有的Account类前半部分的代码
/*这里是deposit代码*/
/*这里是withdraw代码的前半部分*/
if(balance<0) //这里是withdraw代码的后半部分。
throw new IllegalStateException(balance+"");
}
/*系统已有代码,无需关注*/
public void deposit(int money) {
synchronized (this) {
balance += money;
}
}
public void withdraw(int money) {
synchronized (this) {
balance -= money;
}
- jmu-Java-05集合-List中指定元素的删除
编写以下两个函数
/*以空格(单个或多个)为分隔符,将line中的元素抽取出来,放入一个List*/
public static List<String> convertStringToList(String line)
/*在list中移除掉与str内容相同的元素*/
public static void remove(List<String> list, String str)
裁判测试程序:
public class Main {
/*covnertStringToList函数代码*/
/*remove函数代码*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
List<String> list = convertStringToList(sc.nextLine());
System.out.println(list);
String word = sc.nextLine();
remove(list,word);
System.out.println(list);
}
sc.close();
}
}
/*以空格(单个或多个)为分隔符,将line中的元素抽取出来,放入一个List*/
public static List<String> convertStringToList(String line) {
List<String> list = new ArrayList<String>();
String[] str = line.split("\\s+");
for (int i = 0; i < str.length; i++) {
list.add(str[i]);
}
return list;
}
/*在list中移除掉与str内容相同的元素*/
public static void remove(List<String> list, String str) {
for (int i = 0; i < list.size(); i++) {
if(list.get(i).equals(str)) {
list.remove(i);
i--;
}
}
}
- 试试多线程 (20分)
编写4个线程,第一个线程从1加到25,第二个线程从26加到50,第三个线程从51加到75,第四个线程从76加到100,最后再把四个线程计算的结果相加。
class Count extends Thread{
int start;
Count(int start) {
this.start = start;
}
@Override
public synchronized void run() {
for (int i = start; i < start + 25; i++) {
Main.sum += i;
}
}
}
public class Main{
public static int sum = 0;
public static void main(String[] args) throws Exception {
Count count1 = new Count(1);
Count count2 = new Count(26);
Count count3 = new Count(51);
Count count4 = new Count(76);
count1.start();
count1.join();
count2.start();
count2.join();
count3.start();
count3.join();
count4.start();
count4.join();
System.out.println(sum);
}
}
- List的使用 (15分)
本题练习列表的使用。
定义Person类
定义私有属性String name,int age,使用Eclipse生成每个属性setter 、getter,有参Person(String name,int age) 、无参 构造方法,toString方法。
定义Main类,在main方法中
定义List list = new ArrayList();
用键盘给变量n赋值
生成n个Person对象并添加到列表中,该Person的name和age通过键盘给出
循环列表,输出列表所有Person对象信息(调用toString方法)
import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + getName() + ", age=" + getAge() + "]";
}
}
public class Main{
public static void main(String[] args) {
List list = new ArrayList<>();
Scanner input = new Scanner(System.in);
int n = input.nextInt();
for (int i = 0; i < n; i++) {
Person person = new Person(input.next(),input.nextInt());
list.add(person);
}
for (int i = 0; i < n; i++) {
System.out.println(list.get(i).toString());
}
}
}