zoukankan      html  css  js  c++  java
  • Java 笔记04

    内部类:

    (注:所有使用内部类的地方都可以不用内部类,使用内部类可以使程序更加的简洁,便于命名规范和划分层次结构)。

    内部类是指在一个外部类的内部再定义一个类。

    内部类作为外部类的一个成员,并且依附于外部类而存在的。

    内部类可为静态,可用PROTECTED和PRIVATE修饰。(而外部类不可以:外部类只能使用PUBLIC和DEFAULT)。

     

    内部类的分类:

    成员内部类、

    局部内部类、

    静态内部类、

    匿名内部类(图形是要用到,必须掌握)。

     

    ①  成员内部类:作为外部类的一个成员存在,与外部类的属性、方法并列。

    内部类和外部类的实例变量可以共存。

    在内部类中访问实例变量:this.属性

    在内部类访问外部类的实例变量:外部类名.this.属性。

     

    成员内部类的优点:

    ⑴内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)

    ⑵用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。

    注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。

    对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。

     

    (编写一个程序检验:在一个TestOuter.java程序中验证内部类在编译完成之后,会出现几个class.

     

    成员内部类不可以有静态属性。(为什么?)

     

    如果在外部类的外部访问内部类,使用out.inner.

     

    建立内部类对象时应注意:

    在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)

    而在外部类的外部,要生成(new)一个内部类对象,需要首先建立一个外部类对象(外部类可用),然后在生成一个内部类对象。

    Outer.Innerin=Outer.new.Inner()。

    错误的定义方式:

    Outer.Innerin=new Outer.Inner()。

    注意:当Outer是一个private类时,外部类对于其外部访问是私有的,所以就无法建立外部类对象,进而也无法建立内部类对象。

     

    ②  局部内部类:在方法中定义的内部类称为局部内部类。

    与局部变量类似,在局部内部类前不加修饰符public和private,其范围为定义它的代码块。

     

    注意:局部内部类不仅可以访问外部类实例变量,还可以访问外部类的局部变量(但此时要求外部类的局部变量必须为final)??

    在类外不可直接生成局部内部类(保证局部内部类对外是不可见的)。

    要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部类。

     

    ③  静态内部类:(注意:前三种内部类与变量类似,所以可以对照参考变量)

    静态内部类定义在类中,任何方法外,用static定义。

    静态内部类只能访问外部类的静态成员。

    生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:

    Outer.Innerin=new Outer.Inner();

    而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。

    静态内部类不可用private来进行定义。例子:

    对于两个类,拥有相同的方法:

    People

    {

      run();

    }

    Machine{

       run();

    }

    此时有一个robot类:

    class Robotextends People implement Machine.

    此时run()不可直接实现。

    注意:当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用内部类来实现。

    用接口不能完全地实现多继承,用接口配合内部类才能实现真正的多继承。

     

    ④  匿名内部类(必须掌握):

    匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口。

    IA被定义为接口。

    IA I=newIA(){};

    注:一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名。

    因其为局部内部类,那么局部内部类的所有限制都对其生效。

    匿名内部类是唯一一种无构造方法类。

    匿名内部类在编译的时候由系统自动起名Out$1.class。

     

    如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。

    因匿名内部类无构造方法,所以其使用范围非常的有限。

    (下午:)Exception(例外/异常)(教程上的MODEL7)

    对于程序可能出现的错误应该做出预案。

    例外是程序中所有出乎意料的结果。(关系到系统的健壮性)

     

    JAVA会将所有的错误封装成为一个对象,其根本父类为Throwable。

    Throwable有两个子类:Error和Exception。

    一个Error对象表示一个程序错误,指的是底层的、低级的、不可恢复的严重错误。此时程序一定会退出,因为已经失去了运行所必须的物理环境。

    对于Error错误我们无法进行处理,因为我们是通过程序来应对错误,可是程序已经退出了。

    我们可以处理的Throwable对象中只有Exception对象(例外/异常)。

    Exception有两个子类:Runtime exception(未检查异常)

    非Runtimeexception(已检查异常)

    (注意:无论是未检查异常还是已检查异常在编译的时候都不会被发现,在编译的过程中检查的是程序的语法错误,而异常是一个运行时程序出错的概念。)

    在Exception中,所有的非未检查异常都是已检查异常,没有另外的异常!!

     

    未检查异常是因为程序员没有进行必要的检查,因为他的疏忽和错误而引起的异常。一定是属于虚拟机内部的异常(比如空指针)。

     

    应对未检查异常就是养成良好的检查习惯。

    已检查异常是不可避免的,对于已检查异常必须实现定义好应对的方法。

    已检查异常肯定跨越出了虚拟机的范围。(比如“未找到文件”)

     

    如何处理已检查异常(对于所有的已检查异常都要进行处理):

    首先了解异常形成的机制:

    当一个方法中有一条语句出现了异常,它就会throw(抛出)一个例外对象,然后后面的语句不会执行返回上一级方法,其上一级方法接受到了例外对象之后,有可能对这个异常进行处理,也可能将这个异常转到它的上一级。

    对于接收到的已检查异常有两种处理方式:throws和try方法。

     

    注意:出错的方法有可能是JDK,也可能是程序员写的程序,无论谁写的,抛出一定用throw。

     

    例:public void print() throws Exception.

     

    对于方法a,如果它定义了throwsException。那么当它调用的方法b返回异常对象时,方法a并不处理,而将这个异常对象向上一级返回,如果所有的方法均不进行处理,返回到主方法,程序中止。(要避免所有的方法都返回的使用方法,因为这样出现一个很小的异常就会令程序中止)。

     

    如果在方法的程序中有一行throw new Exception(),返回错误,那么其后的程序不执行。因为错误返回后,后面的程序肯定没有机会执行,那么JAVA认为以后的程序没有存在的必要。

     

    对于try……catch格式:

    try  {可能出现错误的代码块}   catch(exception e){进行处理的代码} ;

                                    对象变量的声明

     

    用这种方法,如果代码正确,那么程序不经过catch语句直接向下运行;

    如果代码不正确,则将返回的异常对象和e进行匹配,如果匹配成功,则处理其后面的异常处理代码。(如果用exception来声明e的话,因为exception为所有exception对象的父类,所有肯定匹配成功)。处理完代码后这个例外就完全处理完毕,程序会接着从出现异常的地方向下执行(是从出现异常的地方还是在catch后面呢?利用程序进行验证)。最后程序正常退出。

     

    Try中如果发现错误,即跳出try去匹配catch,那么try后面的语句就不会被执行。

    一个try可以跟进多个catch语句,用于处理不同情况。当一个try只能匹配一个catch。

    我们可以写多个catch语句,但是不能将父类型的exception的位置写在子类型的excepiton之前,因为这样父类型肯定先于子类型被匹配,所有子类型就成为废话。JAVA编译出错。

     

    在try,catch后还可以再跟一子句finally。其中的代码语句无论如何都会被执行(因为finally子句的这个特性,所以一般将释放资源,关闭连接的语句写在里面)。

     

    如果在程序中书写了检查(抛出)exception但是没有对这个可能出现的检查结果进行处理,那么程序就会报错。

    而如果只有处理情况(try)而没有相应的catch子句,则编译还是通不过。

    如何知道在编写的程序中会出现例外呢

    1.  调用方法,查看API中查看方法中是否有已检查错误。

    2.  在编译的过程中看提示信息,然后加上相应的处理。

     

    Exception有一个message属性。在使用catch的时候可以调用:

    Catch(IOExceptione){System.out.println(e.message())};

    Catch(IOExceptione){e.printStackTrace()};

    上面这条语句回告诉我们出错类型所历经的过程,在调试的中非常有用。

     

    开发中的两个道理:

    ①如何控制try的范围:根据操作的连动性和相关性,如果前面的程序代码块抛出的错误影响了后面程序代码的运行,那么这个我们就说这两个程序代码存在关联,应该放在同一个try中。

    ①  对已经查出来的例外,有throw(积极)和try catch(消极)两种处理方法。

    对于try catch放在能够很好地处理例外的位置(即放在具备对例外进行处理的能力的位置)。如果没有处理能力就继续上抛。

     

    当我们自己定义一个例外类的时候必须使其继承excepiton或者RuntimeException。

    Throw是一个语句,用来做抛出例外的功能。

    而throws是表示如果下级方法中如果有例外抛出,那么本方法不做处理,继续向上抛出。

    Throws后跟的是例外类型。

    断言是一种调试工具(assert)

    其后跟的是布尔类型的表达式,如果表达式结果为真不影响程序运行。如果为假系统出现低级错误,在屏幕上出现assert信息。

    Assert只是用于调试。在产品编译完成后上线assert代码就被删除了。

     

    方法的覆盖中,如果子类的方法抛出的例外是父类方法抛出的例外的父类型,那么编译就会出错:子类无法覆盖父类。

    结论:子类方法不可比父类方法抛出更多的例外。子类抛出的例外或者与父类抛出的例外一致,或者是父类抛出例外的子类型。或者子类型不抛出例外。

    如果父类型无throws时,子类型也不允许出现throws。此时只能使用try catch。

     

    练习:写一个方法:int add(int a,int b)

    {

      return a+b

    }

    a+b=100;抛出100为异常处理。
  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯VIP基础练习 矩形面积交
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    核心思想:想清楚自己创业的目的(如果你没有自信提供一种更好的产品或服务,那就别做了,比如IM 电商 搜索)
    在Linux中如何利用backtrace信息解决问题
  • 原文地址:https://www.cnblogs.com/flyingsir/p/3983761.html
Copyright © 2011-2022 走看看