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为异常处理。
  • 相关阅读:
    pip 查看软件包 可用版本并安装; pip 查看 numpy 可用版本并安装
    git submodule git 子模块管理相关操作
    git 取消文件跟踪
    C 实战练习题目1
    VC6.0设置注释快捷键
    2019-11-29-WPF-非客户区的触摸和鼠标点击响应
    2019-11-29-VisualStudio-使用新项目格式快速打出-Nuget-包
    2019-11-29-WPF-从触摸消息转触摸事件
    2019-11-29-win7-无法启动-WPF-程序-D3Dcompiler_47.dll-丢失
    2019-11-29-C#-序列类为-xml-可以使用的特性大全
  • 原文地址:https://www.cnblogs.com/flyingsir/p/3983761.html
Copyright © 2011-2022 走看看