面向对象(下)
接口:
什么是接口:
接口就是抽象方法和常量值的集合,从本质上讲,接口是一种特殊的抽象类
为什么需要接口:
通过接口可以实现不相关类的相同行为
接口提供了不同对象进行协作的平台
接口可以实现多继承,从一定程序上弥补了类只能单继承的缺点
说明:
- 接口中的方法不允许有方法体,但抽象类允许
- java不允许多继承,接口却允许多继承,即一个接口可以有多个父类
- 接口定义的属性必须是public static final的,而接口上定义的方法必须是public abstract的,因此这些修饰符可以部分或全部省略
- 一个类只能实现某个接口,不能继承某个接口,但接口可以继承接口
- 接口不但可以继承接口,而且可以继承多个接口,允许多继承
- 如果一个类只实现了一个接口的部分方法,则该类必须声明为抽象类
- 一个类可以在继承一个父类的同时实现一个或多个接口,但extends关键字必须的在implements前面
- 不可以new接口对象,但可以定义一个接口引用类型的变量并将其指向实现接口的对象,达到多态的目的
class A { } interface It1 { } interface It2 { } //接口可以多重继承,即一个接口可以有多个父接口,但是一个类只能有一个父类,Java类不允许多继承,接口却允许多继承 interface It3 extends It1, It2 { } interface It4 { int i = 20; } //一个类可以在继承一个父类的同时实现一个或多个接口,但extends关键字必须的在implements 之前 class T extends A implements It4,It3 { } class TestInter_2 { public static void main(String[] args) { System.out.println("嘿嘿!"); } }
异常:
什么是异常:
异常是程序运行过程中发生的事件,该事件可以中断程序指令的正常执行流程
为什么需要异常:
来举个例子吧
public class TestInput { public statiac void main(String[] args) { Scanner sc = null; sc = new Scanner(System.in); int i = sc.nextInt(); // 要求用户输入一个整数 System.out.println("%d\n",i); // 如果用户输入是的一串字符,程序就死翘翘了 //本程序出现的问题是无法通过逻辑判断来解决的, //不过java为我们提供了异常处理机制,我们可以很好的解决这个问题 } } 接下来 public class TestInput { public static void main(String[] args) { Scanner sc = null; boolean flag = true; while (flag) // 做了一个循环,当用户输入非法时,重新输入 { try { int i = sc.nextInt(); //这里出现异常时,程序会不停的循环,直到没有异常,flag = false,程序终止 System.out.println(i); flag = false; // } catch(Exception e) { System.out.println("输入数据不合法!"); } } } }
异常处理机制:
当java程序运行时出现问题时,系统会自动检测到该错误,并立即生成一个与该错误对应的异常对象
然后把该异常对象提交给java虚拟机
java虚拟机会自动寻找相应的处理代码来处理这个异常,如果没有找到,则程序终止
程序员可以自己编写代码来捕捉可能出现的异常,并编写代码来处理相应的异常
throw用来抛出异常,要抛出的异常必须是Throwable的子类
假设f方法抛出了A异常,则f方法有两各方式来处理A异常
1. throws A
谁调用 f 方法,谁处理A异常
2. try{...} catch(){....}
f 方法本身自己来处理A异
注意:
所有的catch只能有一个被执行
有可能所有的catch都没有执行
先catch子类异常再catch父类异常,如果先catch父类异常再catch子类异常,则编译时会报错
重写方法抛出异常的范围不能大于被重写方法排除的异常范围
finally的作用:
无论try所指定的程序块中是否抛出异常,也无论catch语句的异常类型是否与所抛的异常类型一致,finaaly中的代码都会得到执行
finally语句为异常处理提供一个统一的出口,全得在控制流程转到程序的其他部分之前,能够对程序的状态作统一的管理
通常在finally语句中可以进行资源的清除工作,如关闭打开的文件,删除准时文件等
异常的优点:
强制程序员考虑程序的安全性与健壮性
增强了程序员对程序的可控性
有利于代码的调试
把错误的代码从常规代码中分离出来
/* Exception类中有一个private的Message属性,通过构造函数 public Exception(String message) 可以完成对该属性的初始化 */ class E extends Exception { public E() { super("哈哈"); //这实际是调用父类Exception的构造函数: public Exception(String message) } } class M { public static void f() throws E //也可以改为 throws Exception { throw new E(); } public static void main(String[] args) { try { f(); } catch (Exception e) { String strExcep = e.getMessage(); System.out.println("strExcep = " + strExcep); } System.out.println("程序正常终止了!"); } } /* 在JDK 1.6中的运行结果是: -------------------------------- 程序正常终止了! -------------------------------- 总结: getMessage() 返回的是异常的具体信息,是个String类型 public Exception(String message) 用message字符串来表示异常的具体信息 */
异常处理步骤:
try { 可能出现的异常代码 } catch(ExceptionName1 e) { 当产生ExceptionName1异常的处理措施 } catch(ExceptionName2 e) { 当产生ExceptionName2异常的处理措施 } finally { 无论是否捕捉到异常都必须处理的代码 }
内部类:
什么是内部类:
比如在A类的内部但是所有方法的外部定义了一个B类,则B类就是A类的内部类
为什么需要内部类:
可以让一个类方便的访问另一个类中的所有成员
增加程序的安全性,有效避免其他不相关类对该类的访问
什么时候该使用内部类:
如果一个A类要使用B类的所有成员,并且A类不需要被B类以外的其他类访问,则我们应当把A类定义为B类的内部类
特性:
一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称.名字不能与包含它的类名相同
可以使用包含它的类的静态和实例成员变量,也可以使用它所在方法的局部变量
可以定义为abstract
可以声明为private或protected
若被声明为static,就变成了顶层类,不能再使用局部变量
若想在Inner Class中声明任何static成员,则该Inner Class必须声明为static
匿名类:
什么是匿名类:
匿名类是一种特殊的内部类
说明:
如如在一个方法内部定义一个匿名类,则该匿名类可以访问:
外部类的所有成员
包裹该匿名类的方法中的所有final类型的局部变量,非final类型的局部变量无法被匿名类访问
/* 假设A是接口名 new A() { 实现接口中方法的代码 }; 功能:生成一个实现了A接口的匿名类 */ interface It { void f(); //void g(); // 如果该语句生效的话,21行到27行的代码中就必须的实现g方法 } public class TestAnonyClass_1 { public static void main(String[] args) { It it = new It() { //21行 public void f() { System.out.println("哈哈"); } }; //27行 //error // It it = new It1() // ( //是{ 不是( // public void f() // { // System.out.println("哈哈"); // } // ); // 是} 不是) //error // It it = new It() // ( // { // public void f() // { // System.out.println("哈哈"); // } // } // ; it.f(); } }
生成一个匿名类,该匿名类必须得实现了A类的所有抽象方法,当然该匿名类也可以定义自己的属性和方法
/* 假设A是抽象类 new A() { 实现了A类的所有抽象类的方法代码 添加自己的方法或属性代码【不建议,因为没有实际意义】 } 功能: 生成一个匿名类,该匿名类必须得实现了A类的所有抽象方法, 当然该匿名类也可以定义自己的属性和方法 */ abstract class A { abstract public void f(); public void g() { } } public class TestAnonyClass_2 { public static void main(String[] args) { A aa = new A() { //f方法不可以被注释掉, 因为f是抽象方法,匿名类必须的实现 public void f() { System.out.println("FFFF"); } //g方法可以被注释掉 public void g() { System.out.println("GGGG"); } public void k() { } }; aa.f(); aa.g(); //aa.k(); } }