1.接口:初期理解,可以认为是一个特殊的抽象类。当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。class用于定义类,interface用于定义接口
接口定义时,格式特点:
1.接口中常见定义:常量,抽象方法
2.接口中的成员都有固定修饰符
常量:public static final
方法:public abstract
常量和方法的修饰符都可以省略,因为interface会自动加上,但是不推荐省略,因为会降低可读性
记住:接口中的成员都是public的
接口是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。
接口的特点:1.接口是对外暴露的原则
2.接口是程序的功能扩展
3.接口可以用来实现
4.类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口
5.接口与接口之间可以有继承关系
2.多态:可以理解为事物存在的多种体现形态
1.多态的体现:父类的引用指向了子类对象
2.多态的前提:必须是雷玉磊之间的关系,要么继承,要么实现,并且要存在覆盖
3.多态的好处:多态的出现大大的提高了程序的扩展性
4.多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员
5.多态的应用
instaceof 判断是否属于某一类型 例如 a instaceof Cat
在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败
在运行时期:参阅对象所属的类中是否有调用的方法。
简单来说,成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:无论编译与运行,都参考左边
Object类中已经提供了对对象是否相同的比较方法,如果自定义类中也有比较相同的功能,没有必要重新定义,只要沿袭父类中的功能,建立自己特有比较内容 即可,这就是重写。
3.内部类的访问规则
1.内部类可以直接访问外部类中的成员,包括私有,是因为内部类中持有了一个外部类的引用,格式:外部类名.this
2.外部类要访问内部类,必须建立内部类对象
访问格式:
1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,直接建立内部类对象
格式: 外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
2.当内部类定义在成员位置上,就可以被成员修饰符所修饰,比如private(将内部类在外部类中进行封装),static(内部类就具备static的特性)。当内部类被 static修饰后,只能直接访问外部类中的static成员,出现了访问局限
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类不许是static的,当外部类中的静态方法访问内部类时,内部类也必须是static的
当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容;
内部类定义在局部时:1.不可以被成员修饰符修饰
2.不可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可访问它所在的局部中的变量,只能访问被final修饰的局部变量
匿名内部类:
1.匿名内部类其实就是内部类的简写格式
2.定义匿名内部类的前提:内部类必须是继承一个类或者实现接口
3.匿名内部类的格式:
new 父类或者接口(){定义子类的内容}
4.其他匿名内部类就是一个匿名子类对象,而且这个对象有点胖,也可以理解为带内容的对象。
5.匿名内部类中定义的方法最好不要超过3个(即1个或者2个);
4.异常:就是程序在运行时出现不正常情况。
1.异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。异常其实就是java对不正常情况进行描述后的对象体现
对于问题的划分两种:一种是严重的问题,java通过Error类进行描述
一种是非严重的问题,java通过Exception类进行描述,可以使用针对性的处理方式进行处理
无论Error或Exception都具有一些共性内容。比如:不正常情况的信息,引发原因等。
2.异常的处理:java提供了特有的语句进行处理
try{需要被检测的代码}
catch(异常类 变量){ 处理异常的代码; }
finally{一定会执行的语句;}
3.对捕获到的异常对象进行常见方法操作
String getMessage(); // 获取异常信息
在函数上声明异常:便于提高安全性,让调用处进行处理,不处理编译失败
对多异常的处理:
1.声明异常时,建议声明更为具体的异常,这样可以处理的更具体
2.对方声明几个异常,就对应有几个catch块,不要定义多余的catch块,如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面
建议在进行catch处理时,catch中一定要定义具体处理方式,不要简单定义一句e.printStackTrace();也不要简单的就书写一条输出语句。
4.因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象,所以对于这些特有的问题可以按照java的对问题封装的思想,将特有的问题进行自定义的异常 封装
5.自定义异常
在本程序中,对于除数是-1,也视为是错误的,是无法进行运算的,那么就需要对这个问题进行自定义的描述,当在函数内部出现了throw抛出异常对象,那么就必须要 给对应的处理动作,要么内部try catch处理,要么在函数上声明让调用者处理,一般情况下,函数内出现异常,函数上需要声明。
发现程序打印的结果中只有异常的名称,却没有异常的信息。因为自定义的异常并未定义信息,如何定义异常信息呢?因为父类中已经把异常信息的操作都完成了,所以 子类在构造函数时,只要将异常信息传递给父类,通过super语句,那么就可以直接通过getMessage方法获取自定义的异常信息了
自定义异常:必须是自定义类继承Exception
继承Exception的原因:
异常体系有一个特点:因为异常类和异常对象都被抛出,他们都具备可抛性,这个可抛性是Throwable这个体系中的独有特点。只有这个体系中的 类和对象才可以被throws和throw操作
throws和throw的区别:throws使用在函数上上,后面跟的异常类,可以跟多个,用逗号隔开
throw使用在函数内,后面跟的是异常对象。
Exception中有一个特殊的子类异常,RuntimeException运行时异常,如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过,如果在函数上声明了该异常, 调用者可以不用进行处理,编译一样通过。
自定义异常时,如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException
对于异常分为两种: 1.编译时被检测的异常
2.编译时不被检测的异常(运行时异常RuntimeException以及其子类)
finally代码块:定义一定执行的代码,通常用于关闭资源
第一个格式:
try{}
catch(){}
第二个格式:
try{}
catch(){} //中间可以有多个catch
finally{}
第三个格式
try{}
finally{}
记住一点:catch是用于处理异常,如果没有catch就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明。
异常在子父类重写中的体现:
1.子类在重写父类时,如果父类的方法抛出异常,那么子类的重写方法,只能抛出父类的异常或者该异常的子类
2.如果父类方法抛出多个异常,那么子类在重写该方法时,只能抛出父类异常的子集
3.如果父类或者接口的方法中没有异常抛出,那么子类在重写方法时,也不可以抛出异常。
如果子类方法发生了异常,就必须要进行try处理,绝对不能抛
异常总结:
异常是对问题的描述,将问题进行对象的封装。
异常体系: Throwable
|--Error
|--Exception
|--RuntimeException
异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性,只有异常体系有这个特点。
finally只有一种情况不会执行,当执行到System.exit(0);
异常的好处:1.将问题进行封装
2.将正常流程代码和问题处理代码相分离,方便于阅读
异常的处理原则 :处理方式有两种,try或者throws
当捕捉到的异常,本功能处理不了时,可以继续在catch中抛出
try{throw new Aexception;}
catch(Aexception e) {throw e;}
如果该异常处理不了,但并不属于该功能出现的异常,可以将异常转换后,再抛出和该功能相关的异常。或者异常可以处理,但需要将异常产生的和本功能相关的问题 提供出去,让调用者知道并处理,也可以将捕获到的异常处理后,转换为新的异常。
try{ throw new Aexception() ; }
catch(Aexception e)
{
// 对Aexception 处理
throw new BException;
}