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

                                        -----------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继承Exception
class AException extends Exception
{
}
//BException继承AException
class BException extends AException
{
}
//CException继承Exception
class 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("唉呀妈呀,这菜太贵了");  
		//重新点菜
		else
			System.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学习型技术博客、期待与您交流!---------

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值