一,内部类
一,概述
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
二,访问规则
1,内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this。
2,外部类要访问内部类,必须建立内部类对象。
三、访问格式
1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。
格式:
外部类名.内部类名 变量名 =外部类对象.内部类对象;
2,在外部其他类中,直接访问static内部类的非静态成员的格式为:
new 外部类名.内部类名().方法名();
3,在外部其他类中,直接访问static内部类的静态成员格式为:
外部类名.内部类名.方法名();
4,内部类定义在局部
内部类定义在外部类中的某个方法中,创建了这个类型的对象时,且仅使用了一次,那么可在这个方法中定义局部类。
1)不可以被成员修饰符修饰。如public、private、static等修饰符修饰。它的作用域被限定在了声明这个局部类的代码块中
2)可以直接访问外部类中的成员,因为还持有外部类中的引用。
注意:内部类不可以访问它所在的局部中非最终变量。只能访问被final修饰的局部变量。
/* 定义一个包含私有成员变量和函数的类,再定义一个内部类,在内部类函数中访问外部成员变量,并调用外部函数。
在外部类函数中创建内部类对象,调用内部类函数。*/
public class text8 {
public static void main(String[] args) {
outer oer=new outer();
oer.outMethod(8);
}
}
class outer{
private int x=100;
private void outMethod2(int a)
{
System.out.println(a+" outMethod2");
}
void outMethod(int x)
{ inner inn=new inner(); //创建内部类对象
inn.inMethod(45); //调用内部类函数
System.out.println(x+" outMethod");
}
//内部类
class inner{
void inMethod(int a)
{ int y=a+x; //访问外部类中的x
outMethod2(6); //调用外部类函数
System.out.println(y+" inMethod");
}
}
}
4,匿名内部类
1、匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
特殊情况:因为所以的类都有一个父类Object,所以在定义时也可以用Object。
3,匿名内部类的格式: new父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。
匿名内部类的利与弊:
好处:简化书写
弊端:1,不能直接调用自己的特有方法、
2,不能做强转动作。
3,如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,且调用会很麻烦。所以匿名内部类中定义的方法有一般不超过3个。
二,异常
1,概述
1,异常:就是程序在运行时出现不正常情况。
2,异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。其实就是java对不正常情况进行描述后的对象体现。
3,程序可能出现的错误或问题
a,用户输入错误导致的异常:如用户不正常使用程序,输入一些非法参数
b,设备硬件等发生的错误:如硬盘损坏等
c,物理限制:如存储空间不足等
d,代码错误:在程序编写的方法可能不正确,返回错误参数等。
2、异常体系
Java的异常体系:
Throwable
|---Error //通常出现重大问题如:运行的类不存在或者内存溢出等。
|---Exception //运行时出现的一起情况
|---RuntimeException //特殊异常类,抛时不需要声明
Exception和Error的子类名都是以父类名作为后缀。
异常体系的特点:
1,异常体系中的所有类以及建立的对象都具备可抛性。
2,也就是说可以被throw和throws关键字所操作。
3,只有异常体系具备这个特点。
3,异常的处理
1, java提供了特有的语句进行处理。
try
{
需要被检测的代码。
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
有三个结合格式:
a,try
{
}
catch ()
{
}
b,try
{
}
finally
{
}
c,try
{
}
catch ()
{
}
finally
{
}
注意:
1)finally中定义的通常是关闭资源代码。因为资源必须释放。
2)如果在一个功能中,定义了一些必须要执行的代码,可以用try{}finally{}的方式,将一定执行的代码放在finally代码块中。
3)finally只有一种情况不会执行。当执行到System.exit(0);finally不会执行。
2,throw和throws的用法
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
3,调用者对抛出信息的处理
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。要么在内部try catch处理。要么在函数上声明让调用者处理。
一般情况下,函数内出现异常,函数上需要声明。在功能上通过throws的关键字声明了该功能有可能会出现异常类型。
4,异常的好处与原则
好处:
1,将问题进行封装。
2,将正常流程代码和问题处理代码相分离,方便于阅读。
原则:
1,处理方式有两种:try或者 throws。
2,调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch。
3,多个catch时,父类的catch放到最下面。否则编译会报错,因为其余的catch语句执行不到。
4,catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。也不要不写。当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后,在抛出和该功能相关的异常。
或者异常可以处理,当需要将异常产生后和本功能相关的问题提供出去,让调用者知道。并处理。也可以将捕获异常处理后,转换新的异常。
5、异常的注意事项
1,问题在内部被解决就不需要声明。
2,catch是用于处理异常。如果没有catch就代表异常没有被处理,如果该异常是检测时异常。那么必须声明。
3,在子父类覆盖时:
a 子类抛出的异常必须是父类的异常的子类或者子集。
b 如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。
/*
毕老师用电脑上课。
开始思考上课中出现的问题。
比如问题是
电脑蓝屏。
电脑冒烟。
要对问题进行描述,封装成对象。
可是当冒烟发生后,出现讲课进度无法继续。
出现了讲师的问题:课时计划无法完成。
*/
class LanPingException extends Exception//自定义蓝屏异常
{
LanPingException(String message)
{
super(message);
}
}
class MaoYanException extends Exception //自定义冒烟异常
{
MaoYanException(String message)
{
super(message);
}
}
class NoPlanException extends Exception//出现新的异常-课时无法继续异常
{
NoPlanException(String msg)
{
super(msg);
}
}
class Computer
{
private int state = 3;
public void run()throws LanPingException,MaoYanException//电脑运行
{
if(state==2)
throw new LanPingException("蓝屏了");
if(state==3)
throw new MaoYanException("冒烟了");
System.out.println("电脑运行");
}
public void reset()//电脑重启
{
state = 1;
System.out.println("电脑重启");
}
}
class Teacher
{
private String name;
private Computer cmpt;
Teacher(String name)
{
this.name = name;
cmpt = new Computer();
}
public void prelect()throws NoPlanException
{
try
{
cmpt.run();
}
catch (LanPingException e)
{
cmpt.reset();
}
catch (MaoYanException e)
{
test();//对异常进行处理
throw new NoPlanException("课时无法继续"+e.getMessage());//转换成新的异常抛出。
}
System.out.println("讲课");
}
public void test()
{
System.out.println("练习");
}
}
class ExceptionTest
{
public static void main(String[] args)
{
Teacher t = new Teacher("毕老师");
try
{
t.prelect();
}
catch (NoPlanException e)
{
System.out.println(e.toString());
System.out.println("换老师或者放假");
}
}
}