-------
一、内部类:
定义在外部类中的类的或者方法体中,作为外部类的成员或者局部变量。
1、访问规则:
1>内部类可以直接访问外部类中的成员,包括私有;
2>外部类通过建立内部类对象才可以访问内部类。
2、访问格式:
1>当内部类定义在外部类成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象,格式:
外部类名.内部类名 变量名 = 外部类对象.内部类对象。(记住)
Outer.Inner in = new Outer( ).new Inner( );
2>当内部类定义在成员位置上,就可以被成员修饰符所修饰(理解,开发一般不写)。如:private:将内部类在外部类中进行封装;
static:内部类就具备了静态的特性。只能直接访问外部类中的静态成员,出现访问局限性。
3>在外部其他类中,如何直接访问静态内部类中的非静态和静态成员呢?
非静态成员:new Outer.Inner( ).function( );
静态成员:Outer.Inner.function( );
说明:Outer是外部类,Inner是Outer中的内部类,function是Inner中的方法。
注意:当内部类中定义了static成员,该内部类也必须是静态的;当外部类中的static方法访问内部类时,内部类也必须是静态的。
3、什么时候使用内部类:
当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物直接使用外部事物的内容。(人体.心脏)
4、局部内部类:(小知识点,多了解)
1>不可以被成员修饰符修饰;
2>可以直接访问外部类中的成员,因为还特有外部类中的引用(外部类名.this.)。但只能访问被final修饰的局部变量。
5、匿名内部类:(开发中的AWT常用,多练多写,注意)
1>其实就是内部类的简写格式,格式:new 父类或接口名( ){定义子类的内容;}
2>定义匿名内部类的前提:内部类必须是继承一个类或实现接口;
3>就是一个你名子类对象,而且这个对象有点胖,可以理解为带内容的对象。
目的:简化书写,重写方法。
示例:
需求:通过main方法中的这么一句代码补足其他部分:Test.function().method();
思路:
Test.function():通过分析该语句可以知道Test类中有一个静态方法function,
.method:function这个方法运算后的结果是一个对象,而且是一个Inter类型的对象。
步骤:
方法一:建立完整的Inner内部类来实现接口,这样看直观,然后在function方法中将该类的对象作为返回值;
方法二:在function方法体中,直接将Inter接口的匿名子类对象作为返回值;
题外:在InnerClassTest方法中可以定义一个show方法,参数列表为:Inter in,再调用method方法。在main方法中直接调用show方法,且将Inger接口的匿名子类对象作为值传递,也能满足覆盖接口的method方法并输出。
interface Inter //定义的接口,已知。
{
void method();//复原: public abstract void method();
}
//需要补足代码的Test类:通过匿名内部类
class Test
{
/*
//方法一:内部类实现接口,这样写比较麻烦。
static class Inner implements Inter
{
public void method()
{
System.out.println("method run...");
}
}
*/
static Inter function() //静态成员方法,可直接由类名调用。
{
//方法一:
//return new Inner();
/*
方法二:匿名内部类:建立接口Inter的子类对象(多态:向上转型),
等价于:Inter in = new Inner();in.method();
*/
return new Inter()
{
//该方法体中成员是属于Inter子类的成员,别弄混。
public void method()
{
System.out.println("method run...");
}
};
}
}
class InnerClassTest
{
public static void main(String[] args)
{
//Test.function():Test类中有一个静态的方法function。
//.method():function这个方法运算后的结果是一个对象,而且是一个Inter类型的对象。
//因为只有是Inter类型的对象,才可以调用method方法。
//Inter in = Test.function(); in.method();
Test.function().method();
//题外:在main方法中定义个show方法,然后调用show方法,
//且将Inter接口的匿名子类对象作为参数值进行赋值,也能达到上述效果。
show(new Inter()
{
public void method()
{
System.out.println("method show run");
}
});//注意这仨符号的层次关系,千万别少写。
}
public static void show(Inter in)
{
in.method();
}
}
总结:记住内部类和一般类的不同,如可以被私有,可以被static修饰,以及对内对外的访问方式。特别注意匿名内部类,是面试和程序设计中都要用到的。
二、异常:(excption)
1、异常:是对问题的描述,将问题进行对象的封装。
1>异常体系:
Throwable (错误和异常的超类(上帝))
|--Error (严重问题)
|--Exception (一般问题)
|--RuntimeException (特殊的运行时异常)
2>异常处理语句:
try{需要被检测的代码;}
catch ( ){处理异常的代码;}
finally{一定会执行的代码;}
有三种结合格式:
第一种:try{ }
catch ( ) { }
第二种:try{ }
finally{ }
第三种:try{ }
catch ( ) { }
finally{ }
注意:
a:catch用于处理异常,如果没有catch就代表异常没有被处理;如果该异常是检测时异常,那么必须声明。
b:finally中定义的通常是关闭资源代码。因为资源必须释放。
c:finally只有一种情况不会执行。当执行到System.exit(0); fianlly不会执行。
如: {
连接数据库; //a—>try
操作数据库; //b—>catch
关闭数据库; //c—>finally
}
分析:假如b语句段发生异常,那么c语句将不会执行,如果不用finally关闭连接,那么该程序会一直占用数据库连接,浪费资源,影响服务器性能。
3>异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性,也就是说可以被throw和throws关键字所操作,只有异常体系具备这个特点。
4>throw和throws的用法:
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,都在编译失败。注意:RuntimeException除外,也就说,函数内如果抛出的RuntimeExcpetion异常,函数上可以不用声明。如果函数声明了异常,调用者需要进行处理。处理方法可以throws可以try。
5>异常有两种:(面试考点)
编译时被检测异常:该异常在编译时,如果没有处理(没有抛也没有try),编译失败。 该异常被标识,代表这可以被处理。
运行时异常(编译时不检测,运行时异常:RuntimeException):在编译时,不需要处理,编译器不检查。该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
2、自定义异常:
1>按照Java对问题封装的思想,定义类继承Exception或者RuntimeException,处理特有且未被Java描述并封装的问题。
目的:让该自定义类具备可抛性;让该类具备操作异常的共性方法。
当要定义自定义异常的信息时,可以使用父类已经定义好的功能,通过super关键字将异常信息传递给父类的构造函数。
class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}
自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。如果该异常的发生,无法再继续进行运算,就让自定义异常extents RuntimeException。
2>异常的好处:
a:将问题进行封装。
b:将正常流程代码和问题处理代码相分离,方便于阅读。
3>异常的处理原则:
a:处理方式有两种:try 或者 throws。
b:调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch。
c:多个catch,父类的catch放到最下面。
d:catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句,也不要不写。
d:当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
try
{
throw new AException( );
}
catch (AException e)
{
throw e;
}
e:如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,再抛出和该功能相关的异常。或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,当调用者知道,并处理,也可以将捕获异常处理后,转换新的异常。
try
{
throw new AException( );
}
catch (AException e)
{
// 对AException处理。
throw new BException( );
}
比如,汇款的例子。计算机会告知客户汇款失败的结果,都可能有哪些原因造成,而不会告知具体失败的过程。
4>异常的注意事项:
在子父类覆盖时:
a:子类抛出的异常必须是父类的异常或者异常的子类或者子集。
b:如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。
需求:
有一个圆形和长方形,都可以获取面积。对于面积如果出现非法的数值,视为是获取面积出现问题。
问题通过异常来表示,现有对这个程序进行基本设计。
思路:
1.该题涉及到的是RuntimeException异常,因为若出现非法值,那么后续计算也将无意义,所以不需要处理,只需修改传入的值保证正确即可。
2.图形面积计算我们可以设计一个接口,通过子类实现接口来实例化各个图形的面积计算方式。
步骤:
1.首先定义一个运行时异常类的子类IllegalValueException,通过super语句指向父类构造函数并传入异常信息,来进行异常输出。
2.定义Shape接口,且声明抽象方法getArea,通过圆形和长方形子类实现接口来实例化。
3.定义Rec(长方形)类,在其构造函数中进行异常信息判断抛出IllegalValueException异常,若不存在异常信息就进行长宽赋值操作,并且复写getArea方法输出面积值。Circle类同上。
4.在main方法中通过建立接口子类对象,调用getArea方法,来获取面积值。
总结:异常在开发中很常用,需要掌握什么时候在函数上抛出异常,什么时候在函数内抛出异常,若在函数上抛出异常,那么在执行前必须处理该异常。有些时候,异常导致的结果导致后续语句执行将无意义,那么就需要用到运行时异常,提示我们需要修改代码来解决该异常。在开发过程中,不同的程序员负责不同的模块,那么我们在抛出异常时就需要考虑到,其他人在看到该异常时会不知道怎么处理该异常,所以我们需要抛出因该异常导致的另外的异常且是其他人可以处理的异常。熟悉异常机制需要多练习,多动手动脑,才有比较好的把握在面对异常时我们该怎么去做。
三、包:(package)
包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。
不同包中的子类还可以直接访问父类中被protected权限修饰的成员。
包与包之间可以使用的权限只有两种:public和protected
访问权限图:
public protected default(默认) private
同一个类中 ok ok ok ok
同一个包中 ok ok ok
子 类 ok ok
不同包中 ok (仅父子关系)
有些时候我们定义的包名中还有子包(子文件夹),如果要使用子文件夹中的java文件,每次都要写一串文件夹名很麻烦。Java中为了简化类名的书写,使用一个关键字import。(记住包名要小写)
如:pack.packA.packA_1.packA_1_3.InnerClass,在packA_1_3子文件中有一个InnerClass.class的文件。
import pack.packA.packA_1.packA_1_3.InnerClass; //将导入InnerClass.class文件。
import pack.packA.*; //导入packA文件夹中的所有class文件。
建议:一般 不要写通配符*,一般需要用到哪个类就导入哪个类。定义包名不要重名,可以使用url来完成定义,url(统一资源定位符)是唯一的。如:www.itcast.cn,我们可以搬照网址的格式来定义包名:package cn.ticast.pack;package cn.ticast.test