Java之内部类与异常类

一、内部类

在一个类中定义另一个类,这样的类成为内部类,包含内部类的类称为 内部类的 外嵌类。

内部类与外嵌类的关系:

1.内部类可以调用其外嵌类的方法和成员变量

2.内部类中不可以声明类变量和类方法

3.外嵌类可以 用内部类声明的对象作为外嵌类的成员

4.内部类仅供其对应的外嵌类使用,其他类不可以声明别的类的内部类对象。

public class RCF{
    static String from;
    //内部类的声明
    class RedCow{
        String cown = "red";
        int h , w;
        RedCow(int H,int W){
            h = H;    w = W;
        }
        void speak(){
            System.out.println("Name:" + cown +"; Height:" + h 
                    + "; Weight:" + w + "; Family:" + from);
        }
    }
    RedCow cow;//内部类声明对象
    RCF(String s){
        cow = new RedCow(152,100);
        from = s;
    }
    public void show(){
        cow.speak();
    }
}

 

public class neibulei {
    public static void main(String[] args) {
        RCF rcf = new RCF("andy");
        rcf.show();
        rcf.cow.speak();
//        RCF.RedCow rc = new RCF.RedCow(180, 150);
//        rc.speak();
    }

}

还记得static吗?类成员和类变量,在这里,内部类也可以被修饰为static内部类,即外嵌类中的一种静态数据类型,用static修饰后,就可以在其他类中使用static内部类来创建对象了。but,static内部类就不能操作外嵌类中的实例变量了,但可以操作类变量。即把上述中内部类RedCow改成static内部类后,main方法中的注释部分就可以去掉了。

二、匿名类

匿名类,什么是匿名类?没有名字的类啊,那没有名字的类怎么来用呢?没有名字肯定就不能声明对象呀,但是却可以直接创建对象的。那不能声明对象,怎么用这个匿名类呢? 那就作为参数来用呀!

匿名类有两种,一种是与子类有关,一种是与接口有关

其实匿名类就是直接创建对象的啊,无论是与子类有关还是与接口有关,他都是没有类名直接创建的。你看现在若有一个A类,那么我们是如何创建他的对象的? A  a = new A();  这样,就创建了一个A类的对象a,那现在我们是如何创建匿名类呢?  直接写 new  A{  匿名类类体   };   这不就是直接创建了一个类吗,这也就可以理解了匿名类是一个子类吧。也因为匿名类没有名字可以用来声明,所以常常直接创建一个匿名类对象  参数。

1.和子类有关的匿名类

匿名类的特点:

1.匿名类可以继承和重写父类的方法(匿名类就是一个子类)。

2.匿名类一定是内部类,因为他一定是在某个类中直接用匿名来创建对象的。

3.匿名类可以访问外嵌类中的成员变量和方法,但是匿名类中不可以声明static成员变量和static方法

 //抽象类对象

abstract class OutputAlphabet {
    public abstract void output();
}

//OutputAlphabet类的一个子类

public class OutputEnglish extends OutputAlphabet{
    public void output() {
        for(char c = 'a';c <= 'h';c++){
            System.out.printf("%3c",c);
        }
    }
}

public class ShowBoard {
    void showMess(OutputAlphabet show){  //参数是OutputAlphabet类型的对象
        show.output();
    }
}

public class nimig {
    public static void main(String[] args) {
        ShowBoard board = new ShowBoard();

//参数是一个OutputEnglish类型的对象,对于一个参数直接是一个对象我是有点不太理解的,他是怎么用的呢?看下面,应该会容易理解一点
        board.showMess(new OutputEnglish());

//参数直接为对象不好理解,那我们先创建一个对象,然后再调用,是不是就明白了呢,其实道理也就是这样的,不过是换了一种形式
        OutputEnglish english = new OutputEnglish();
        board.showMess(english);

        english.output(); // 这个,因为创建的对象里有这个方法,所以直接调用也可以

// 这个,红括号里面的就是他的参数,前面可以声明一个对象再来引用,但对于匿名类是不能声明的,所以就直接作为参数,在这里面进行创建、写类体。注意一下匿名类是如何创建的:new 父类名(){      类体    }
        board.showMess ( new OutputAlphabet() {
            public void output() {   
//重写父类方法
                for(char c = '1';c <= '5';c++){
                    System.out.printf("\n" + "%3c",c);
                }
            }
        }
)  ;   //注意分号不要忘了
    }
}

2.和接口有关的匿名类

与接口有关就是用接口名和类体来创建一个匿名类咯。  new  接口名 () {    类体    };

接口和类体组成的匿名类要求类体必须要重写接口中的所有方法。

//接口定义

interface Speak{
    void sp();
}
class Hello{
    public void turn(Speak hello){  // 接口参数 
        hello.sp();
    }
}
public class niming {
    public static void main(String[] args) {
        Hello HD = new Hello();
        HD.turn ( new Speak(){ 
            public void sp(){
                System.out.println("Hello,you are welcom!");
            }
        }
) ;
    }
}

三、异常类

Java中本身也是包含有很多类的,具体的作用方法我一个菜鸟还是记不住的,就遇到了再记吧。那现在关于异常类中的方法,我还是查一下吧,简单的...

异常类的祖先是Throwable,throwable的直接子类是 Exception 和 Error。

异常对象可以调用下列方法得到或输出有关异常的信息:

public String  getMessage();     //只显示原因,不显示类名

public void printStackTrace();   //跟踪异常发生时堆栈的内容

public String toString();              //显示类名和原因


Java允许方法调用过程中抛出异常对象,终止当前方法的继续执行。

1.try-catch语句

Java使用try-catch语句来处理异常,将可能出现的异常操作放在try-catch语句try部分,一旦try部分抛出异常对象,或调用某个可能抛出异常对象的方法,并且该方法抛出了异常对象,(反正就是try语句里有异常)那么try部分立刻结束执行,转向执行相应的catch部分。  故程序可以将发生异常后的处理放在catch部分,try-catch语句可以由几个catch组成,分别处理发生的相应异常。

其try-catch语句格式为:

try{

        包含可能发生异常的语句

}

catch(ExceptionSubClass1 e){     ......     }

catch(ExceptionSubClass2 e){     ......     }

各个catch参数中的异常类都是Exception的某个子类,表明try部分可能发生的异常,这些子类间不能有父子关系,否则保留一个含有父类参数的catch即可。

public class yichang {
	public static void main(String[] args) {
		int n =0 ,m = 0, t = 1000;
		try{
			m = Integer.parseInt("8888");
			n = Integer.parseInt("ab12");
			t = 999;
		}
		catch(NumberFormatException e){
			System.out.println("发生异常:" + e.getMessage());
		}
		System.out.println("n=" + n + ",m=" + m + ",t=" + t);
		try{
			System.out.println("故意抛出I/O异常!");
			throw new java.io.IOException("我是故意的");
//			System.out.println("这个输出语句是没有机会被执行的");
		}
		catch(java.io.IOException e){
			System.out.println("发生异常:" + e.getMessage());
		}
	}
}

java.lang包中的 Integer 类调用其类方法public static int parseInt(String s)可以将 “数字”格式 的字符串, 如“6789”, 转化为 int型数据 ,但是当试图将字符串“ab89”转换成数字时,例如:int number=Integer.parseInt(“ab89”);方法parseInt()在执行过程中就会抛出 NumberFormatException 对象,即程序运行出现NumberFormatException异常(字符串转换成数字异常)。 

2.自定义异常类

可以自己编写Exception的子类作为自己的异常类。使用 throws 关键字声明要产生的异常(即在要判断方法的方法名后面加throws  编写的异常类类名),使用 throw 关键字抛出该异常的对象,使该方法结束执行。

程序必须在try-catch块语句中调用可能发生异常的方法,其中catch的作用就是捕获throw关键字抛出异常对象

//自定义的异常类,其实和普通的类一样

public class BankException extends Exception{
    String message;
    public BankException(int m,int n) {
        message = "若入账资金"+m+"是负数,或者支出"+n+"为正数,则错误"; 
    }
    public String warn(){
        return message;
    }
}

public class Bank {
    private int money;

//判断方法中是否有异常
    public void income(int in,int out) throws BankException{  //声明可能产生异常的类
        if(in<0||out>0||in+out<0){
            throw new BankException(in, out);   //若发生了异常对其进行抛出
        }
        int netIncom = in +out;
        System.out.printf("本次纯收入为:%d元\n",netIncom);
        money = money + netIncom;
    }
    public int getMoney(){
        return money;
    }
}

public class yichang {
    public static void main(String[] args) {
        Bank bank = new Bank();
        try{
            bank.income(200, -50);
            bank.income(300, -80);
            bank.income(500, -100);
            System.out.printf("银行存款:%d元\n",bank.getMoney());
            bank.income(100, 50);  //  在这里出现了异常,则立即结束执行
            bank.income(6000, -20);  //  不会被执行
        }
        catch(BankException e){
            System.out.println("发生问题为:");
            System.out.println(e.warn());
        }
        System.out.printf("银行存款:%d元\n",bank.getMoney());
    }
}

3.finally语句

finally语句使用在try-catch语句后面的

try{.....}

catch(ExceptionSubClass e){.....}

finally{.....}

在执行了try-catch语句后,执行finally语句,也就是说,无论try部分是否发生异常,finally语句都会被执行。

But,若try-catch语句中执行了程序退出代码( 即执行System.exit(0);  ),则不会执行后面的所有语句(包括finally语句)。

 

 

猜你喜欢

转载自blog.csdn.net/weixin_42227243/article/details/82950581