一、内部类
在一个类中定义另一个类,这样的类成为内部类,包含内部类的类称为 内部类的 外嵌类。
内部类与外嵌类的关系:
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语句)。