黑马程序员---多态,内部类,异常,包

来源:互联网 发布:js原型继承原理 编辑:程序博客网 时间:2024/04/29 12:33

                                        -----------android培训java培训、java学习型技术博客、期待与您交流!---------

多态

 

    定义:某一种事物的多种存在形态

 

       1.   多态的体现形式:

 

             父类的引用指向了自己的子类对象。父类的引用也可以接受自己的子类对象。

   

       2.   多态的前提

 

            必须是类与类之间有关系,要么继承,要么实现,通常还有一个前提:存在覆盖。   

 

       3.   多态的好处

 

             多态的出现提高了程序的扩展性。

 

 

       4.   多态的弊端

 

              虽然多态提高了扩展性,但是只能使用父类的引用访问父类中的成员。

 

              如果想调用特有方法要如何操作?

 

                       强制转换:将父类引用,转换成子类类型。

 

                       千万不要出现把父类对象转换成子类类型。

 

                        我们能转换的是父类引用指向了自己的子类对象时, 该引用可以被提升(多态),也可以被强制转换。

 

           多态自始至终都是子类对象在做变化。

 

         如下面的程序所示

 

/*多态的使用示例我现在身边正好有一瓶可乐,就用可乐举例啦*///定义一个饮料父类abstract class Drinsk{//定义一个糖浆方法,因为不知道是那种糖浆的饮料,所以是抽象方法,抽象类abstract void syrup();}//定义一个可乐类,继承饮料类class Coke extends Drinks{//重写糖浆方法,定义可乐的方法体public void syrup(){System.out.println("可乐糖浆");}//定义可乐的特有方法public void color(){//可乐是黑的色System.out.println("黑色");}}class  DuoTaiDemo{public static void main(String[] args) {//这就是多态,父类的引用指向子类对象Drinks d = new Coke();//调用父类中的方法d.syrup();//父类的引用不可以调用子类的方法,所以要进行强制转换//将父类的引用转换成子类类型Coke c = (Coke)d;//这时再调用子类中的方法就可以了c.color();}}

           运行结果为


 

       

       5.   多态的应用:

 

             思想:多态将对象调用这件事变简单了,以前是指挥每一个对象做事,现在是指挥一批对象做事。 因为找到了这些对象的共同所属类型。

 

             记住:只要把事物不断的向上抽取,总能找到共同点,找到后就可以统一操作很多对象。

 

             我们对类型进行抽取,导致了多态的产生,操作一个大类型,对大类型中所有小类型都能进行操作,


             这就是多态的核心思想。因为这个思想,才可以提高扩展性。

 

             理解:就比如刚才的例子,糖浆就是抽取的共性,所有饮料都有糖浆, 黑色就是事物特有的,


                         我们既可以输出糖浆,也可以输出黑色。

 

    在多态中成员函数的特点

 

       在编译时期

 

           参阅引用型变量所属的类中是否有调用的方法, 如果有,编译通过。如果没有,编译失败。

 

       在运行时期

 

           参阅对象所属的类中是否有调用的方法。

 

       简单总结就是:成员函数在多态调用时编译看等号左边,运行看等号·右边。(如果右边所属的类没有该方法,就去父类找)

 

       以下是面试中考到到的知识点,需注意!!!!

   

       在多态中成员变量的特点

 

           (子父类中有同名的成员变量时)无论编译和运行,都参考左边(引用变量所属的类)

 

       在多态中静态成员函数的特点

 

           (子父类中有同名静态成员函数时)无论编译和运行,都参考左边(引用型数据变量所属的类)

 

           也就是父类的引用在调用静态成员函数时,被调用的是父类中的静态函数。

 

           原因:

 

                   因为是静态,所以在类建立时静态方法就已经存在,不需要对象直接用类名调用即可。


                   当父类引用指向子类对象时,只要是父类的所属引用,就会用父类的静态方法。


                   调用那个类中的静态成员方法看的是引用型变量所属类的内容。


                 因为静态成员函数比对象先加载,所以调用的静态成员函数不属于对象。

 

instanceof

 

       它的作用是判断其左边对象是否为其右边类的实例。

 

              返回boolean类型的数据。可以用于判断继承中子类的实例是否为父类的实现。

 

       instanceof 不经常使用,使用的情况如下:

 

           1.   子类类型有限时。

 

           2.   当传的类型需要进行其他操作,如:比较

 

            必须要确定是哪种子类型,要调用特有方法来比较,这时会用instanceof判断一下。

 

    下面我们来看一个多态的实例

 

/*多态示例手机的运行实例。手机的运行由手机的主板控制,我们都知道在智能手机还没有被发明出来的年代手机只能简单的运行,打电话,发短信等操作,到了智能手机时代手机就可以照相,听音乐了。我们可以把手机的主板当做一个底座,底座上面有可以安装耳机孔和摄像头的凹槽,而这个凹槽呢有特殊的形状,只要符合这个形状的耳机孔和摄像头都可以在这个手机主板上使用,这样就降低了他们之间的耦合性。下面我们来用程序体现。*///定义凹槽接口,用来接收耳机孔,摄像头等外接设备interface AoCao{//定义凹槽的通电和断电方法。public abstract void open();public abstract void close();}//定义耳机孔类,实现凹槽接口class ErJiKong implements AoCao{//因为接口的成员函数都是public修饰的,复写方法需要权限比被覆盖的方法大或一样 所以public修饰//复写凹槽的通电断电方法public void open(){System.out.println("耳机孔通电————听音乐");}public void close(){System.out.println("耳机孔断电");}}//定义摄像头类,实现凹槽接口class SheXiangTou implements AoCao{//复写通电断电方法public void open(){System.out.println("摄像头通电——————照相");}public void close(){System.out.println("摄像头断电");}}//定义手机类class Phone{//按了开机键,手机开机public static void run(){System.out.println("手机开机");}//定义使用凹槽方法,接收凹槽对象,但其实我们知道凹槽不能创建对象,所以实际运用中接受的是凹槽的子类对象//其实就是:AoCao Ao = new ErJiKong() 这就是多态,父类的引用指向了子类对象public static void useAoCao(AoCao ao){//判断传入的对象是否属于凹槽接口,或者它的子类。if(ao instanceof AoCao){//调用通电,断电方法。通过刚才我们学的,对于多态中的成员方法,编译看左边,运行看右边//左边引用类型所属的类是凹槽接口(父类),有这两个方法,编译可以通过//右边对象所属的类会是凹槽接口的子类,都复写了这两个方法,所以运行时就运行子类中的通电断电方法。ao.open();ao.close();}}}class PhoneDemo{public static void main(String[] args){//创建一个手机对象Phone p=new Phone();//手机开机运行p.run();//将耳机孔对象作为参数传入使用凹槽方法中,使用耳机孔听歌。p.useAoCao(new ErJiKong());////将摄像头对象作为参数传入使用凹槽方法中,使用摄像头拍照。p.useAoCao(new SheXiangTou());}}

       程序运行结果

 


 

内部类

 

       内部类:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

 

       个人理解:类是用来描述事物的,事物中还有事物,该事物就用内部类来描述,就比如:

 

                            我现在打字的键盘是一个事物,而每个按键又是一个事物, 这是可以再键盘这个类中,定义一个按键内部类,来描述按键。

 

       内部类访问特点

 

              1.   内部类可以直接访问外部类成员,包括私有成员,

 

                     之所以可以访问外部类的成员,是因为内部类中持有了一个外部类的引用,

 

                     格式:外部类名.this

 

              2.   外部类要访问内部类中的成员,必须要建立内部类的对象。

              

       访问格式

 

              1.   当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部对象。

 

                     格式: 外部类名.内部类名 引用变量名 = 外部类对.内部类对象

 

                            如: Outer.Inner in =new Outer().new Inner();

 

                     当内部类在成员位置上,就可以被成员修饰符所修饰

 

                            比如:private:将内部类在外部类中进行封装;

 

                                        static:内部类就具备了static的特性,当内部类被static修饰后, 只能访问外部类中的static成员,出现了访问局限。

 

                     在外部其他类中如何直接访问static内部类的非静态成员?

 

                     格式:  new 外部类名.内部类名().方法();

 

                            如:  new  Outer.Inner().funvtion();

 

                     在外部其他类中如何直接访问static内部类的静态成员呢?

 

                            格式:  外部类名.内部类名

 

                            如:   Outer.Inner.function();

 

                     注意:当内部类中定义了静态成员,该内部类必须是静态的

 

                                  当外部类中的静态方法访问内部类时,内部类也必须是静态的

               

              2.   内部类定义在局部时

 

                     a.   不可以被成员修饰符修饰。

 

                     b.    可以直接访问外部类中的成员,因为还持有外部类的引用。但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量

 

       下面我们来看一个内部类的例子

 

              因为我是先看完的视频才写的博客,所以这里的例子我想用基础测试中的题

/*内部类代码演示定义一个包含私有成员变量和函数的类,再定义一个内部类,在内部类函数中访问外部成员变量,并调用外部函数。在外部类函数中创建内部类对象,调用内部类函数。*/class InnerClassDemo{public static void main(String[] args) {//调用外部类的方法来完成程序的检验//因为每一步前我都加了输出代码,可以很清楚的看到整个程序的步骤和过程。OuterClass.outerMethod2();}}//为了老师阅读起来比较方便新建一个名叫OuterClass的类,用于题目的完成class OuterClass{//定义这个类中的私有成员变量private static int i = 123;//定义类中的私有方法private static void outerMethod1(){//输出“我是OuterClass类中的私有函数”,输出了,证明方法被调用System.out.println("我是OuterClass类中的私有函数~");}//定义内部类public class InnerClass{//定义一个方法,用于访问外部类的成员变量和调用外部类的方法public void innerMethod(){//输出内部类方法在被调用的语句,告诉用户内部类调用成功//先给后面调用外部类私有成员的语句铺垫一下,说明一下先后顺序System.out.println("内部类的方法正在被调用,内部类方法正在调用外部类的私有成员:");//输出外部类的私有成员变量System.out.println("外部类的私有成员变量:"+i);//调用外部类的私有方法,因为是静态的,直接调用即可outerMethod1();}}//在外部类中定义一个方法,用于创建内部类对象,调用内部类函数public static void outerMethod2(){//输出语句“外部类的方法被调用了”System.out.println("外部类的方法被调用啦~");//输出创建对象内部类对象的语句System.out.println("在外部类中创建内部类对象......");//创建内部类对象,因为内部类在外部类中,所以要如以下方法创建内部类对象InnerClass innerClass = new OuterClass().new InnerClass();//输出内部类对象调用外部类私有方法的语句System.out.println("内部类对象调用自己的方法啦~");//内部类的对象调用内部类的函数innerClass.innerMethod();}}

                    运行结果



 


匿名内部类 


       特点:

                

              1.   匿名内部类其实就是内部类的简写格式


              2.   定义匿名内部类的前提:内部类必须继承一个类或者实现接口


              3.   匿名内部类的格式: new 父类或者接口 .(){定义子类的内容}


              4.   其实匿名内部类就是一个匿名子类对象,而且这个对象有点儿“胖”。可以理解为带内容的对象


              5.   匿名内部类中定义的方法最好不要超过三个,因为定义太多方法会没有阅读性。


       好处:简化书写

            

       缺点:


              1.   不能直接调用自己的特有方法


              2.   不能做强转动作。


              3.   如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,且调用会很麻烦。


                    所以匿名内部类中定义的方法有一般不超过3个。


       使用匿名内部类的场景之一


              当使用的方法的参数类型是一个接口类型时,该接口中的方法不超过三个


              可以定义一个匿名内部类,把匿名内部类作为参数传入。


       匿名内部类的应用

/*匿名内部类使用示例*///定义一个接口interface Inter{//定义一个方法public abstract void method();}class  InnerClassDemo2{public static void main(String[] args) {//调用show方法。因为接口不能创建对象,所以使用匿名内部类//就当匿名内部类就是Inter的子类,并复写Inter接口中的方法show(new Inter(){public void method(){System.out.println("匿名内部类中方法在被调用");}});}//定义一个show方法,接收Inter对象public static void show(Inter in)      {  //调用Inter类中方法        in.method();      }  }


下面我们来看一个小练习


/*内部类小练习*///定义一个接口interface Inter{//定义一个方法public abstract void method();}class Test{//补足代码}class InnerClassTest{public static void main(String[] args) {Test.function().method();}}

       分析: 


              练习中的Test.function().method();语句


              Test.function():  Test类中有一个静态方法function.


              .method():   fanction这个方法运算后的返回值类型是一个对象,而且是Inter类型对象。 因为只有是Inter类型的对象才可以调用method方法。

      

       所以通过分析Test.function().method()语句,补全的代码为   

/*内部类小练习*///定义一个接口interface Inter{//定义一个方法public abstract void method();}class Test{//补足代码,通过匿名内部类//静态方法function的返回值类型是个对象static Inter function(){//返回的是Inter对象,但是Inter接口不能创建对象,所以要用匿名内部类//创建Inter接口的子类return new Inter(){//复写Inter接口中的方法public void method(){System.out.println("内部类练习---内部类学完啦!");}};}}class InnerClassTest{public static void main(String[] args) {Test.function().method();}}

       程序运行结果



      

 

异常


       因为java是面向对象的语言,所以就算是错误也被封装成了对象,就是我们接下来要学习的异常类。


       异常类就是描述程序中可能出现的错误和问题而存在的。


              流水线上的产品,前面一直都很顺利,到了某个环节发生了问题,产品就做不下去了,要人为的去检查哪儿出了错误,


              对于不同的错误需要用不同的解决方案,不同的解决方案在异常中就可以体现。


       异常就是程序在运行时出现的不正常的情况


       异常的由来:


            问题也是现实生活中具体的失误,也可以通过java的类的形式进行描述,并封装成对象。


            其实就是java对不正产的情况进行描述后的对象体现(把问题封装成对象就是异常)


      异常的好处:


            1.   将问题进行封装


            2.   将正常流程代码和问题处理相分离,方便阅读。


      程序中可能出现的问题:


            a.   用户输入错误导致的异常:如用户不正常使用程序,输入一些非法参数


            b.   设备硬件等发生的错误:如硬盘损坏等


            c.   物理限制:如存储空间不足等


            d.   代码错误:在程序编写的方法可能不正确,返回错误参数等。


       对问题的划分为两种:


            1.   严重的问题


                  对于严重的问题通过Error类进行描述,对于Error一般不编写针对性的代码对其进行处理


             2.   非严重的问题


                   对于非严重的问题通过Exception类进行描述,对于Exception可以使用针对性的处理方式进行处理。


                  无论Error或者Exception都具有一些共性内容,比如:不正常情况的信息或者引发的原因等


      异常的体系:Throwable

                              |--Error

                              |--Exception

                                     |--RuntimeException

            1.   Error:通常出现重大问题,如:运行的类不存在,或者内存溢出等。用Error处理


                  出现这种问题一般不进行针对性处理,直接修改程序


                  通常是不编写代码对其进行针对性处理的。


            2.   Exception:可以处理的问题,通过两种方式可以进行处理


                  a.   运行时出现的情况,可以通过 try catch finally代码块来处理


                  b.   通过throws再函数上声明(如果异常内throw异常那么函数必须声明)


            小技巧:Exception和Error的子类名都是以父类名作为后缀的。


      异常体系的特点


            异常体系中所有类以及建立的对象都具备可抛性,也就是说可以被throw和throws关键字所操作,只有异常体系具备这个特点。


      异常有两种


            1.   编译时被检测的异常:该异常在编译时,如果没有处理(没有抛也没有try)编译失败。该异常被标识,则代表着可以被处理


            2.   运行时异常(编译时不被检测):在编译时,不需要处理,编译器不检查。

  

                  该异常发生,建议不处理让程序停止,需要对代码进行修正。


       异常的处理

            

            Java提供了特有的语句对异常进行处理


                     try{


                            需要被检测的代码


                     }catch(异常类    变量){


                            处理异常的代码(处理方式)


                     }finally{


                     一定会执行的语句


                     }


              try代码块有三种结合格式


                  1.   try{


                        }catch( ){


                       }finally{


                        }

                  2.   try{


                        }catch( ){


                        }


                  3.   try{


                        }finally{


                        }


            记住:catch是用于处理异常的,如果没有catch就代表一场没有被处理过,如果该异常是检测时异常,那么必须声明


            注意:1.   finally中放的是一定会执行的语句,一般存放关闭资源的语句,因为资源必须要被释。


                        2.   如果在一个功能中有必须要执行的语句,可以用try{}finally{}代码块来执行,


                              尽管没有异常需要处理也可以用这个,如果有必须要执行的语句就放在finally中


                        3.   finally只在一种情况下不会执行,在前面的代码中出现System.exit(0)时,finally中的代码不会执行。


      对捕获的异常对象进行常见方法操作


            1.   String getMessage():获取异常信息。


            2.   String toString():获取异常类名称,异常信息。


            3.   printStackTrace():获取异常名称,异常信息,还有异常出现的位置(因为返回值为void所以不需要打印语句打印,即可返回信息)


            4.   printStackTrace(PtintStream s):用该方法把异常信息保存在日志文件中,方便日后查看。


            其实JVM默认的异常处理机制就是在调用printStackTrance()方法,打印异常在堆内存和栈内存中的跟踪信息。


            建议:在进行catch处理时,catch中一定要定义具体的处理方式,不要简单的定义一句。


                        也不要就简单的写一句e.printStackTrace()输出语句。


      throw(抛出)


            throws Exception       在功能上通过throws的关键字声明了该功能有可能会出现问题

            

                                                  在函数行声明异常,便于提高安全性,让调用处进行处理,不处理便以失败。


            throw和throws的用法

                  

                  throw定义在函数内,用与抛出异常对象。


                  throws定义在函数上,用与抛出异常类,可以抛出多个,用逗号隔开。


                  当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败。


                  throw单独存在时下面不要再写语句,因为他就是程序结束的标识


            注意:RuntimeException除外,也就是,函数内如果抛出的是RuntimeException异常,函数上可以不用声明。


            如果函数声明了异常,调用者需要进行处理,处理方式可抛可try


            调用者对抛出信息的处理:当在函数内部出现了throw抛出异常对象,那么就必须要给出对应的处理动作,


                  要么在内部try catch处理,要么在函数上声明,让调用者处理,一般情况下,函数内出现异常,函数上需要申明。


                  在功能上通过throws的关键字声明了该功能可能会出现异常类型。


            Exception中有一个特殊的子类异常:RuntimeException运行时异常


                  如果在函数内抛出该异常,函数上可以不用声明,编译一样通过


                  如果在函数上声明该异常,调用者可以不用进行和处理,编译一样通过。


                  之所以不用在函数上声明,是因为不需要让调用者处理,当该异常发生,希望程序停止。


                  因为在运行时出现了无法继续运算的情况,希望停止程序后对代码进行修正。


      对于异常两种分类的详细解读


            1.    编译时被检测的异常


                    在java编译时期,它会去检测,如果方法中抛出了非RuntimeException异常或者其子类,如果在方法上没有标识,就视为安全隐患。


                   所以不标识就会编译失败,为什么要检测?


                        因为这个异常是可以处理的,要标识出去,让调用者处理,如果函数上标识了被检测异常,


                        调用者也必须有对应的处理方式,要么抛要么try


            2.    编译时不被检测的异常(运行时异常,RuntimeException以及其子类)


                   在函数内抛出异常,在函数上不用声明,因为凡是RuntimeException及其子类会判断异常对象是否intstanceof RuntimeException。


                   如果是,则编译通过,目的是让程序停止。


            判断用哪种异常处理方式


                   在自定义问题时要分析,这个问题发生以后能否处理,如果不想能处理需要修正代码,就要继承RuntimeException


                   如果问题发生以后可以处理,处理完成后程序可以继续运行,那么就继承Exception。


      自定义异常


            因为项目中会出现特有的问题,而这些问题并未被Java所描述并封装对象,所以对于这些特有的问题可以按照Java对问题进行封装的思想,


                   将特有的问题进行自定义的异常封装。


            定义类要么集成Exception要么继承RuntimeException,为的是让自定义类具备可抛性,让该类具备操作异常的共性方法。


                   当要自定义异常的信息时,可以使用父类已经定义好的功能,异常信息传递给父类的构造函数。


            自定义异常按照java的面向对象思想,将程序中出现的特有问题进行封装。


            当自定义了异常类继承Exception后,如果未在类中定义异常信息,


                     那么通过toString方法打印出来的结果就只有自定义的异常类名,不会显示异常信息。


              如何定义异常信息呢?


                     因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时将异常信息传递给父类,通过super语句,


                     那么就可以直接通过getMessage()方法获取异常信息了

 
                     如下代码所示

class ZiDingYiException extends Exception  {  private String msg;  ZiDingYiException(String msg)  {  super(msg);//将会返回输入的信息  }  } 

              自定义异常时:如果该异常的发生,无法再继续进行运算的话,就让自定义异常继承RuntimeException

      
             注意:自定义异常必须是自定义类有继承关系,一般是继承Exception


             继承Exception的原因


                     异常体系有一个特点,因为异常和异常对象都需要被抛出,他们都具备可抛性


                   这个可抛型是Throwable这个体系的独有特点,只有这个体系中的类和对象才可以被throws和throw操作(有局限性)


       异常处理的原则


             1.  处理方式有两种:try或者throws


             2.  调用到抛出异常的功能时,抛出几个就处理几个,会出现一个try对应多个catch的情况


             3.  多个catch,父类的catch放在最下


             4.  catch内需要定义针对性的处理方式,不要简单的定义pringStackTrace(),或输出语句也不要不写。


                     当捕获到的异常,本功能处理不了时,可以继续在catch中抛出

       

                   如下面的程序

try{throw new AException}catch (AException){throw e;}

                     如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后再抛出和功能相关的异常。


                            或者异常可以处理,但需要将异常产生后和本功能相关的问题提供出去,让调用者知道并处理。


                            也可以将捕获异常处理后,转换新的异常抛出。


                            这样就好比在给别人汇款时,如果ATM机出现故障,这时可以另外找地方去转,也可以告诉对方,汇款不成功。


                     转换成新的异常,代码如下:

try{throw new AException}catch (AException){//对AException异常进行处理throw new BException();}


       异常在子父类覆盖中的体现


             1.  子类在覆盖父类方法时,如果父类的方法抛出异常,那么子类的覆盖方法,


                   如果需要抛出异常只能抛出父类的异常,或者该异常的子类。也可以不抛。


             2.  如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子类


             3.   如果父类或者接口中的方法没有异常抛出,那么子类在覆盖方法时也不可抛出异常,


                   如果子类方法发生了异常,就必须要进行try的处理,绝对不能抛


      异常注意事项


              问题在内部被解决就不需要被声明


              在子类覆盖父类时


                     1.   子类抛出的异常必须是父类的异常的子类或者子集


                     2.   如果付类或者接口没有异常抛出是,子类覆盖出现异常,只能try不能抛。


                         如下列程序所示

//AException继承Exceptionclass AException extends Exception{}//BException继承AExceptionclass BException extends AException{}//CException继承Exceptionclass CException extends Exception {}/*以上代码的继承关系为Exception|--AException|--BException|--CException*///定义一个父类class Father{//定义一个方法,抛出A异常void show() throws AException{}}//定义一个测试类class Test{//定义一个方法参数接收父类对象void function(Father f){//通过try,catch代码块处理父类方法异常try{//调用父类show方法f.show();}//处理AException异常catch (AException e){}}}//定义一个子类,继承父类class Son extends Father{//复写父类中方法void show() throws CException{//这样会编译失败,因为子类继承了父类,复写父类方法时抛出的异常应该是//父类抛出的异常的子类,如果抛出BException就不会出错了。}}

       异常练习

/* 异常练习我去饭馆吃饭  描述我对菜进行的动作:     点菜    重新点描述菜的问题    菜卖完了     菜太贵了,超出我的预算了 描述我    我看菜单    我开始选菜(选不是点,选是在脑子里想想自己吃什么) 我可能出现的问题菜太贵了,我不要了*/    //建立自定义异常类,想点的菜没有了class NoHaveException extends Exception  {      NoHaveException(String str)      {  //利用super语句访问父类的构造函数。        super(str);      }  }  //自定义异常类,菜太贵了超出预算 class TooExpensiveException extends Exception  {         TooExpensiveException(String str)      {          super(str);      }  }    //自定义异常类,回家,无法继续吃饭了 class GoHomeException extends Exception  {         GoHomeException(String str)      {          super(str);      }  }  //创建一个饭馆类class Restaurant  {  //定义标记    int start=2;      //点菜方法,可能会没有菜或者太贵    void order()throws NoHaveException,TooExpensiveException    {          if(start==2)  //抛出没有菜异常            throw new NoHaveException("我要的菜没有(小沈阳语调)");          else if(start==3)  //抛出菜太贵异常            throw new TooExpensiveException("唉呀妈呀,这菜太贵了");  //重新点菜elseSystem.out.println("开始点菜了啊");      }      //重新点菜吧      void reordering()      {             start=1;          System.out.println("你家菜要什么什么没有,有的又太贵,我重新点");      }  }    class Me  //我类{      private String name;      private Restaurant  res;        //对我进行初始化      Me(String name)      {          this.name=name;  //我对象已建立,饭馆对象也建立        res=new Restaurant();      }        //我开始跟服务员说我要什么菜,可能会发生我退菜,程序无法运行    public void speak()throws GoHomeException    {  //异常处理        try          {  //调用点菜方法            res.order();                  }  //处理没有菜异常        catch (NoHaveException e)          {  //没有菜了就调用重新点菜方法。            res.reordering();          }  //处理菜太贵异常        catch (TooExpensiveException e)          { //太贵了,前面的菜我也不要了//调用喊退菜方法            back();   //抛出回家一场,并输出异常信息            throw new GoHomeException("这菜我不要了 太贵了也"+e.getMessage());          }          System.out.println(name+"吃饭");      }      void back()      {          System.out.println("退菜,我要退菜!!");      }  }  class ExceptionTest  {      public static void main(String[] args)       {  //创建我对象        Me m=new Me("萌萌的我"); //处理异常        try          {  //调用点菜方法            m.speak();          }          catch (GoHomeException e)          {  //输出异常名称,异常信息            System.out.println(e.toString());              System.out.println("不吃了,直接回家");          }      }  }


运行结果


       正常情况



             

       菜没有




       菜太贵了


             

      

       因为不太想和别人的一样,是临时想出来的例子,其实还是老师讲课的例子比较好,不过用这种轻松的方式来写博客。


       我写的很开心,老师看着也会很放松吧,虽然可能逻辑有点儿不对,什么菜太贵点了都不吃什么的,


       不过我已经很好的理解了异常,这种例子的小错误,希望老师见谅啦~



       PPT上的定义


             对类文件进行分类管理,给类提供多层命名空间,写在程序的第一行,类名的全称是包名.类名。包也是一种封装形式(包名所有字母小写)


       我的理解

       

              包就相当于一个文件夹,里面装的全都是类文件,在编写程序的过程中难免会有重名的情况,重名在中国更常见


              因为太复杂的名字也不太好记,外国名就好一点,因为他们有中间名,还可能有好几个中间名。咳咳,话题扯远了。


              为了对类进行分类的管理,就有了包的出现,在不同的包中可以有相同的类名,不会冲突。


              写项目必须先写包,后写类,因为项目会有很多类组成,必须要进行有效的分区!


       包的好处:包的出现可以让Java的运行文件和Java的源文件相分离


       包的作用


             1.   为避免多个类重名的情况,如果出现两个相同名字的类,可通过包将两者区分,从而避免冲突。


             2.   对类文件进行分类管理,可以将相关的一些类放在同一个包中。


             3.   给类提供多层命名空间。


       使用包的规则     


             1.  包必须写在程序的第一行。


             2.  类的全称:包名.类名。


             3.   编译定义了包的程序文件时,在编译时要指定包的存储目录。


                   如:javac–d c:\mypack类名.java(-d:指定包所存放的目录    .:代表当前目录)


       包与包之间的访问     


             1.   被访问的包中的类权限必须是public的。


             2.   protected:保护权限。不同包中的子类还可以直接访问父类中被protected修饰的成员。


             3.   包与包之间可以使用的权限只有两种,public、protected,而protected修饰的只能只能给子类使用


             下面我们来看四中权限下是否可以访问的表,权限从左至右,由大到小排序




       类加了public之后类名和Java文件名必须保持一致,一个java文件里不能出现2个共有类或接口


import(导入)


       为了简化书写使用import导入包中的类。


       注意事项


              1.   在导入包时,如果包中有很多类,可以使用通配符 *来替代包中的所有类。但是,建议不要使用通配符 * ,


                     因为将不需要使用的类导入后,会占用内存空间。所以在编写程序时,使用包中的哪些类,就导入哪些类。


              2.   定义包名不要重复,可以使用url来完成定义,url是唯一的。


              3.  导入的不同包中有相同类时,必须写类的全名来区分,否则将会报错。


Jar包


       Jar包就是java的压缩包,方便项目的携带,方便于使用,只要在classpath设置jar路径即可,数据库驱动,SSH框架都是以jar包体现的。


       jar.exe工具的命令



      

       下面我们来看一个练习,创建两个包,并把它们存入jar包中


              PackageDemo1程序

package package1;//定义包package1//被访问的包中的类一定是public修饰的public class PackageDemo1 {public void show() {System.out.println("package.PackageDemo类中的show方法正在被调用");}}

              

              PackageDemo2程序

package package1;//定义包package2//导入package1包中的PackageDemo1类import package1.PackageDemo1;public class PackageDemo2{public static void main(String[] args){//创建PackageDemo1的匿名对象,并调用PackageDemo1中的show方法new PackageDemo1().show();}}

              创建package1和package2包,并运行PackageDemo2程序




              目录下产生的包


 


              通过Dos命令行生成jar包



              现在目录下就有了jar包和package1 package2



      

              将两个包删除,只留下jar包,通过DOS命令行制定classpath,输出前面程序的结果





 

谢谢大家的观看~!

                     -----------android培训java培训、java学习型技术博客、期待与您交流!---------

 

0 0