【java程序设计期末复习】chapter7 内部类和异常类

内部类和异常类

内部类

ava支持在一个类中声明另一个类,这样的类称作内部类,而包含内部类的类成为内部类的外嵌类

注意

(1)内部类的类体中不可以声明类变量和类方法。
(2)外嵌类的类体中可以用内部类声明对象,作为外嵌类的成员。

内部类的使用规则:

声明内部类如同在类中声明方法或变量一样,一个类把内部类看作是自己的成员。
外嵌类的类体中可以用内部类声明的对象,作为外嵌类的成员。
外嵌类的成员变量在内部类中仍然有效,内部类中的方法也可以调用外嵌类中的方法。
内部类的类体中不可以声明类变量和方法。
外嵌类和内部类在编译时,生成两个.class文件。

在Java中,内部类可以被以下几种关键字修饰:

(1)private: 内部类可以被private修饰,这样只有外部类的成员方法可以访问内部类。
(2)protected: 内部类也可以被protected修饰,这样它可以被外部类的子类访问。
(3)public: 如果内部类被public修饰,那么它对于任何类都是可见的,可以在外部类以及外部类所在的包中使用。
(4)static: 静态内部类可以被static修饰,这样它就成为了外部类的静态成员,可以直接通过外部类名访问。

static静态内部类无法操作外嵌类的实例成员变量

(5)abstract: 内部类也可以是抽象的,这样就不能直接实例化该内部类,而是需要通过继承该内部类并实现其抽象方法来创建实例。
(6)内部类可以是final类,也可以不是。换句话而言,非匿名内部类可以存在它自己的(内部)子类

public class Example7_1 {
   public static void main(String args[]) {
      RedCowForm form = new RedCowForm("红牛农场");
      form.showCowMess();
      form.cow.speak();
      //RedCowForm.RedCow redCow = new RedCowForm.RedCow(180,119,6000);
      //redCow.speak();
   }   
}
class RedCowForm {
   static String formName;
   RedCow cow;  //内部类声明对象
   RedCowForm() {
   }
   RedCowForm(String s) //构造方法
   {
      cow = new RedCow(150,112,5000);
      formName = s;
   }
   public void showCowMess() {
      cow.speak();
   }
   class RedCow {  //内部类的声明
      String cowName = "红牛";
      int height,weight,price;
      RedCow(int h,int w,int p)
      {
          height = h;
          weight = w;
          price = p;
      }
      void speak() {
         System.out.println("偶是"+cowName+",身高:"+height+"cm 体重:"+weight+"kg,生活在"+formName);
      }
   }    //内部类结束
} 

匿名类

Java允许我们直接使用一个类的子类的类体创建一个子类对象。

1.和子类有关的匿名类
创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明后的类体,称作匿名类。
假设Bank是类,那么下列代码就是用Bank的一个子类(匿名类)创建对象:

new Bank () 
{          
        匿名类的类体
};

2.和接口有关的匿名类
假设Computable是一个接口,那么,Java允许直接用接口名和一个类体创建一个匿名对象,此类体被认为是实现了Computable接口的类去掉类声明后的类体,称作匿名类。
下列代码就是用实现了Computable接口的类(匿名类)创建对象:

new Computable() 
{
    实现接口的匿名类的类体
} ;

3.匿名类的规则
(1)编译器会给每一个匿名类一个名字

在Java中,虽然我们可以创建匿名类,但实际上编译器会为每个匿名类自动分配一个名称,这个名称通常是一些形如"OuterClass$1"、"OuterClass$2"等的字符串,其中"OuterClass"是包含匿名类的外部类的名称。

编译器为匿名类分配名称的原因主要有两个:

调试和诊断: 当程序出现错误时,编译器会生成一个带有堆栈跟踪信息的异常。这个跟踪信息通常包括类名和方法名等信息,用于指示在哪里发生了异常。如果编译器不为匿名类分配名称,那么在错误跟踪信息中将无法准确显示匿名类的信息,这会给调试和错误诊断带来困难。

字节码文件结构: Java字节码文件需要包含类名等元数据信息,而编译器需要为每个类分配一个唯一的名称。即使在源代码中没有为匿名类指定名称,编译器也需要为其生成一个唯一的名称,以便生成对应的字节码文件。因此,为了保证编译后的字节码文件的正确性和完整性,编译器会为匿名类分配一个名称。

尽管编译器为匿名类分配了名称,但这些名称对于程序员来说通常是不可见的,因为它们是编译器自动生成的,并且在源代码中并不直接暴露。

(2)匿名类不能声明自己的static成员变量和static方法
静态成员变量和静态方法属于类本身,而不是类的实例。因此,为了使用静态成员变量和静态方法,需要通过类名来访问,而不是通过类的实例。然而,由于匿名类没有名称,无法通过类名来访问它们,因此在匿名类中声明静态成员变量和静态方法是没有意义的。
(3)匿名类一定是final类
匿名类只存在其实例,因此不能被继承或者重写。

异常类

所谓异常就是程序运行时可能出现一些错误,比如试图打开一个根本不存在的文件等,异常处理将会改变程序的控制流程,让程序有机会对错误作出处理。程序运行出现异常时,Java运行环境就用异常类Exception的相应子类创建一个异常对象,并等待处理。

try…catch语句

Java使用trycatch语句来处理异常,将可能出现的异常操作放在trycatch语句的try部分,将发生异常后的处理放在catch部分。
try~catch语句的格式如下:

try 
{
      包含可能发生异常的语句
}
catch(ExceptionSubClass1  e)
{}
catch(ExceptionSubClass2  e)
{}

例子:

class DangerException extends Exception {
    final String message = "超重";
    public String warnMess() {
        return message;
    }
}
 
class CargoBoat {
    int realContent;  //装载的重量
    int maxContent;   //最大装载量
    public void setMaxContent(int c) {
        maxContent = c;
    }
    public void loading(int m) throws DangerException {
      realContent += m;
      if(realContent>maxContent) {
          throw new DangerException(); 
      }
   }
}

public class Example7_8 {
   public static void main(String args[]) {
      CargoBoat ship = new CargoBoat();
      ship.setMaxContent(1000);
      int m = 0;
      try{ 
           m =600; 
           ship.loading(m);
           m = 400;
           ship.loading(m);
           m = 367;
           ship.loading(m);
           m = 555;
           ship.loading(m);
      }
      catch(DangerException e) {
           System.out.println(e.warnMess()); 
           System.out.println("无法再装载重量是"+m+"吨的集装箱"); 
           try {
               ship.loading(-m); //卸载货物
           }  
           catch(DangerException exp) { 
               System.exit(0);  //程序退出,不再给机会
           }  
      }
      finally {
          System.out.printf("货船将正点启航\n");
          System.out.println("目前装载了"+ship.realContent+"吨货物");
      }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值