Java 实验4 包与异常处理

实验4 包与异常处理

一、实验目的

理解Java包机制的作用,掌握Java中的四种访问控制级别;理解异常处理机制,掌握Java异常处理的基本方法。

二、实验内容

1.程序理解:

1)包的定义和引入

在包Com.tsinghua.p1中定义了一个ClassA类,里面定义的四个不同修饰符的变量和方法,在方法中分别打印出对应修饰符变量的值。在该类的main()方法中尝试通过该类的实例对象调用了四个变量和四个方法。说明了四个修饰符号在同一个类中是可调用的。

package com.tsinghua.p1;

public class ClassA{

    private   String s_pri = "classA private   str";
              String s_fri = "classA friendly  str";    
    protected String s_pro = "classA protected str";
    public    String s_pub = "classA public    str";

    private void printPriStr(){      
        System.out.println(" ClassA  s_pri :"+this.s_pri);
    }

    void printFriStr(){      
        System.out.println(" ClassA  s_fri :"+this.s_fri);
    }

    protected void printProStr(){      
        System.out.println(" ClassA  s_pro :"+this.s_pro);
    }    

    public  void printPubStr(){      
        System.out.println(" ClassA  s_pub :"+this.s_pub);
    } 
    public static void main(String[] args){         

         ClassA a  = new ClassA();
         a.printPriStr();
         a.printFriStr();         
         a.printProStr();         
         a.printPubStr();                           

         System.out.println(a.s_pri);
         System.out.println(a.s_fri);         
         System.out.println(a.s_pro);
         System.out.println(a.s_pub);         
    }       
}

在同一个包中继承ClassA类创建子类ClassBA,然后实例了该类的一个对象,然后调用了父类中的方法和变量。私有变量和私有方法都不能在继承类中使用,不论是同类中的还是非同类中的。

package com.tsinghua.p1;

public class ClassBA extends ClassA{

     public static void main(String[] args){
          ClassBA ba = new ClassBA();
          ba.printFriStr();          
          ba.printProStr();
          ba.printPubStr();
          //私有变量不能访问
         // System.out.println(ba.s_pri);
          System.out.println(ba.s_fri);
          System.out.println(ba.s_pro);          
          System.out.println(ba.s_pub);


         ClassA a  = new ClassA();
     //私有方法不能调用    
    //     a.printPriStr();
         a.printFriStr();
         a.printProStr();         
         a.printPubStr();   

      //私有变量不能访问   
     //    System.out.println(a.s_pri);
         System.out.println(a.s_fri);
         System.out.println(a.s_pro);         
         System.out.println(a.s_pub);   

     }
}

在同一个包中创建一个新的类,然后在新类中实例化一个ClassA的对象,然后尝试调用ClassA中定义的变量和方法。
注意:除了私有变量和私有方法外,其他的在同一个包中的不同类中都可以调用。

package com.tsinghua.p1;
public class ClassB {
     public static void main(String[] args){                  
         ClassA a  = new ClassA();        
        // a.printPriStr();  私有变量不可调用
         a.printProStr();
         a.printFriStr();
         a.printPubStr();                           

        // System.out.println(a.s_pri); 私有方法不可调用
         System.out.println(a.s_pro);
         System.out.println(a.s_fri);
         System.out.println(a.s_pub);  
     }
}

在另一个包Com.tsinghua.p2中创建一个新的类ClassCA并继承ClassA,然后在该类中实例化该类的一个对象,然后调用父类中的变量和方法。
注意:
不同包中的子类,只能调用父类中protected和public定义的方法或变量。

package com.tsinghua.p2;

import com.tsinghua.p1.ClassA; //引入com.tsinghua.p1包中的ClassA类。

public class ClassCA extends ClassA{

     public static void main(String[] args){
        ClassCA ca = new ClassCA();

        // ca.printPriStr();
        // ca.printFriStr();        
        ca.printProStr();
        ca.printPubStr();
        // System.out.println(ca.s_pri);
        // System.out.println(ca.s_fri);        
        System.out.println(ca.s_pro);
        System.out.println(ca.s_pub);
        ClassA a  = new ClassA();

        // a.printPriStr();   
        // a.printProStr();
        // a.printFriStr();
        a.printPubStr();                           
        // System.out.println(a.s_pri);     
        // System.out.println(a.s_pro);
        // System.out.println(a.s_fri);
        System.out.println(a.s_pub);   

     }
}

2)程序无法预见的异常必须进行异常处理(try-catch)

系统已定义异常类的处理:NumberFormatException

package com.tsinghua.p2;

import java.io.*;//通过数据流、序列化和文件系统提供系统输入和输出。

public class IntTransfer {
    public static void main(String[] args) {
        // 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
        BufferedReader re = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        System.out.println("请输入整数字符串:");
        while (true) {
            try {
                str = re.readLine();// 读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车
                                    // ('\r') 或回车后直接跟着换行
                int i = Integer.parseInt(str);// 将字符串参数作为有符号的十进制整数进行解析。
                System.out.println("输入的整数为:" + i);
                break;
            } catch (NumberFormatException e) {// 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
                System.out.println("输入的整数格式不对,请重新输入:");

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2.编程题

(1)1) 设计一个类,类成员和方法分别用public、private、protected以及“default”访问权限。在本类的main方法中创建属于这个类的一个对象,并观察在试图访问所有类成员时会获得哪种类型的编译器错误提示。(为什么?)设计一个新类,并在新类的main方法中创建属于这个类的一个对象,并观察在试图访问所有类成员时会获得哪种类型的编译器错误提示。(注意同一个目录内的类属于“默认”包的一部分)(为什么?)


2) 用protected数据成员创建一个类,在相同的文件里创建第二个类,用一个方法操纵第一个类里的protected权限的数据成员,观察能否操纵?
(2)写一个类MikeOne,包括一个方法:methodA()打印出类名,放入包mypack.one中,写一个类MikeTwo,包括一个方法:methodB()打印出类名,放入包mypack.two中。定义一个类Cmain,要求在其中可以访问到前面的两个类中的方法。(提示,导入所需包中的类后再访问,获取对象的类名,可以通过对象.getClass().getName()来实现)


(3)在实验3的复数类中增加一个构造方法,该构造方法有两个字符串类型的参数,分别为复数的实部和虚部赋值。在构造方法里先将字符串参数转换为浮点数再赋值给实部或虚部。当字符串的内容不能转化为浮点数时,抛出数值格式异常NumberFormatException。在main函数中处理该异常,并进行测试。
(提示:请参照程序理解的第2题来完成本程序;字符串转换为浮点数调用Double类提供的静态方法parseDouble,转换失败时会抛出数值格式异常NumberFormatException,在main函数中处理此异常)。


(4)自定义非法年龄类IllegalAgeException,定义一个Person类,包含年龄,姓名,性别等属性,编写属性设置和读取函数,在设置年龄函数中,判断参数是否符合要求(1~150),如果不符合则抛出异常,编写main函数进行测试。

三、实验结果和分析

(1)程序1运行结果
1)
Java 实验4 包与异常处理_第1张图片

分析:设计一个类,类成员和方法分别用public、private、protected以及“default”访问权限。在本类的main方法中创建属于这个类的一个对象,从结果可以看出,private,default,protected,public这四种权限都可以在本类中访问。

Java 实验4 包与异常处理_第2张图片

分析:设计一个新类,并在新类的main方法中创建属于这个类的一个对象,并观察在试图访问所有类成员时,从结果可以看出:private权限的成员变量和成员函数都不能被访问,说明如果类的成员被private访问控制符来修饰,则这个成员只能被该类的其他成员访问,其他类无法直接访问。

2)
这里写图片描述

分析:用protected数据成员创建一个类,在同一个包里创建第二个类,在第二个类里创建第一个类的对象,访问protected权限的数据成员,从结果可以看出,如果一个类的成员被protected访问控制符修饰,那么这个成员既能被同一包下的其他类访问,也能被不同包下该类的子类访问。

(2)程序2运行结果

这里写图片描述

分析:写一个类MikeOne,包括一个方法:methodA()打印出类名,放入包mypack.one中,写一个类MikeTwo,包括一个方法:methodB()打印出类名,放入包mypack.two中。在mypack.two包下定义一个类Cmain,导入所需mypack.one,创建对象,访问前两个类中的方法,(可通过getClass().getName()获取对象的类名,可以通过对象.来实现)

(3)程序3运行结果

Java 实验4 包与异常处理_第3张图片

Java 实验4 包与异常处理_第4张图片

分析:自定义一个异常类NumberFormatException继承自Exception,在实验3的复数Complex类中增加一个构造方法,该构造方法有两个字符串类型的参数,分别为复数的实部和虚部赋值,在构造方法里先用 Double.parseDouble(),将字符串参数转换为浮点数,再赋值给实部或虚部。当字符串的内容不能转化为浮点数时,抛出数值格式异常NumberFormatException。在main函数中用try….catch…处理该异常.

(4)程序4运行结果

Java 实验4 包与异常处理_第5张图片

分析:自定义非法年龄类IllegalAgeException,定义一个Person类,包含年龄,姓名,性别等属性,编写属性设置和读取函数,在设置年龄函数中,判断参数是否符合要求(1~150),如果不符合则抛出异常,编写main函数进行测试。在main()方法中,定义了一个try….catch语句用于捕获setAge()方法跑出的异常,在调用setAge()方法时由于传入的年龄在1-150之间,否则就会抛出一个自定义异常IllegalAgeException,该异常被扑火后最终被catch代码块处理,并打印出异常信息。

四、实验源代码

(1)程序1源代码
1)

 package example1;

//定义访问权限测试PermissionTest类
public class PermissionTest1 {
    // 定义各种权限的成员变量
    private String apri = "私有成员变量被访问鸟~";
    String adef = "缺省成员变量被访问鸟~";
    protected String apro = "保护成员变量被访问鸟~";
    public String apub = "公有成员变量被访问鸟~";

    // 定义各种权限的成员函数
    private void bpri() {
        System.out.println("私有成员函数被访问鸟~");
    }

    void bdef() {
        System.out.println("缺省成员函数被访问鸟~");
    }

    protected void bpro() {
        System.out.println("保护成员函数被访问鸟~");
    }

    public void bpub() {
        System.out.println("公有成员函数被访问鸟~");
    }

    public static void main(String[] args) {
        // 创建类对象
        PermissionTest1 p1 = new PermissionTest1();
        // 访问所有类成员
        System.out.println("在本类的main方法中访问所有类成员的结果为:\n");
        System.out.println(p1.apri);
        System.out.println(p1.adef);
        System.out.println(p1.apro);
        System.out.println(p1.apub + "\n");
        p1.bpri();
        p1.bdef();
        p1.bpro();
        p1.bpub();
    }

}
package example1;

public class PermissionTest2 {

    public static void main(String[] args) {
        // 创建类对象
        PermissionTest1 p2 = new PermissionTest1();
        // 访问所有类成员
        System.out.println("在新类的main方法中访问所有类成员的结果为:\n");
        // System.out.println(p2.apri);
        System.out.println("私有成员变量无法访问!");
        System.out.println(p2.adef);
        System.out.println(p2.apro);
        System.out.println(p2.apub + "\n");
        // p2.bpri();
        System.out.println("私有成员函数无法访问!");
        p2.bdef();
        p2.bpro();
        p2.bpub();
    }

}

2)

package example1;

public class PermissionTest3 {

    // 定义一个protected成员变量
    protected String cpro = "保护成员变量被访问了鸟~";
}

package example1;

public class PermissionTest4 {

    public static void main(String[] args) {
        PermissionTest3 p4 = new PermissionTest3();

        System.out.println(p4.cpro);
    }

}

(2)程序2源代码

package mypack.one;

//定义一个类 MikeOne
public class MikeOne {
    // 定义一个方法,打印出类名
    public void methodA() {
        System.out.println(getClass().getName());

    }

}

package mypack.two;

//定义一个类 MikeOne
public class MikeTwo {
    // 定义一个方法,打印出类名
    public void methodB() {
        System.out.println(getClass().getName());

    }

}

package mypack.two;

//导入mypack.one.MikeOne包
import mypack.one.MikeOne;

public class Cmain {

    public static void main(String[] args) {
        // 创建对象
        MikeOne m1 = new MikeOne();
        MikeTwo m2 = new MikeTwo();
        // 调用方法
        m1.methodA();
        m2.methodB();
    }

}

(3)程序3源代码

package com.tsinghua.p2;


package com.tsinghua.p2;

import java.io.*;//通过数据流、序列化和文件系统提供系统输入和输出。

//定义一个复数Complex类
public class Complex {
    double real;
    double im;

    // 定义实部和虚部构造方法
    public Complex(String real, String im) {

        this.real = Double.parseDouble(real);
        this.im = Double.parseDouble(im);
    }

    // 字符串描述(重写Object的toString方法,输出a+bi的形式)
    public String toString() {
        if (im < 0)
            return real + "" + im + "i";
        else
            return real + "+" + im + "i";

    }

    public static void main(String[] args) {
        // 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
        BufferedReader re = new BufferedReader(new InputStreamReader(System.in));
        // 初始化
        String str1 = "";
        String str2 = "";
        System.out.println("请输入复数的实部和虚部:");
        while (true) {
            try {
                str1 = re.readLine();// 读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车
                str2 = re.readLine(); // ('\r') 或回车后直接跟着换行
                Complex c1 = new Complex(str1, str2);// 创建Complex对象
                System.out.println("输入的复数为" + c1.toString());
                break;
            } catch (NumberFormatException e) {// 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
                System.out.println("输入的浮点数格式不对,请重新输入:");

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

}

(4)程序4源代码

//下面的代码是自定义一个异常类继承自Exception
public class IllegalAgeException extends Exception {
    public IllegalAgeException() {
        super(); // 调用Exception无参的构造方法
    }

    public IllegalAgeException(String message) {
        super(message); // 调用Exception有参的构造方法
    }
}
package com.tsinghua.p2;

import java.util.Scanner;

//定义一个Person类
public class Person {
    // 定义年龄,姓名,性别成员变量
    private int age;
    private String name;
    private String sax;

    // 编写属性设置和读取函数
    void SetAge(int age) throws IllegalAgeException {
        if (age >= 150 || age < 0) {
            throw new IllegalAgeException("年龄不合法");// 使用throw关键字声明异常对象
        }
        this.age = age;
    }

    void SetName(String name) {
        this.name = name;
    }

    void SetSax(String sax) {
        this.sax = sax;
    }

    int GetAge() {
        return age;
    }

    String GetName() {
        return name;
    }

    String GetSax() {
        return sax;
    }

    public static void main(String[] args) {
        while (true) {
            try {
                // 创建对象
                Person p = new Person();

                Scanner sc = new Scanner(System.in);
                System.out.println("请输入姓名,年龄,性别:");

                String str1 = sc.next();
                int a = sc.nextInt();
                String str2 = sc.next();
                // 调用属性设置和读取函数的方法

                p.SetName(str1);
                p.SetAge(a);
                p.SetSax(str2);
                System.out.println("姓名:" + p.GetName());
                System.out.println("年龄:" + p.GetAge());
                System.out.println("性别:" + p.GetSax());
                break;
            } catch (IllegalAgeException e) { // 对捕获到的异常进行处理
                System.out.println(e.getMessage()); // 打印捕获的异常信息
            }

        }
    }
}

你可能感兴趣的:(Java)