面向对象入门异常、内部类 - 图1

异常类

exceptions1.jpg

异常的作用域

  1. public class ExceptionTest2 {
  2. public static void main(String[] args) {
  3. try {
  4. int len = getStrLength(null);
  5. } catch (NullPointerException e) {
  6. }
  7. System.out.println("程序执行到这"+len);
  8. }
  9. // 获取字符串的长度
  10. public static int getStrLength(String str) {
  11. return str.length();
  12. }
  13. }

这段代码会执行失败,是因为 int len 这个变量定义在try的代码块里,要想打印 len 就需要提升作用域 ,就是把变量定义在代码块前面,如下。

  1. public class ExceptionTest2 {
  2. public static void main(String[] args) {
  3. int len = 0;
  4. try {
  5. len = getStrLength(null);
  6. } catch (NullPointerException e) {
  7. }
  8. System.out.println("程序执行到这"+len);
  9. }
  10. // 获取字符串的长度
  11. public static int getStrLength(String str) {
  12. return str.length();
  13. }
  14. }

手动抛出异常

只要在想抛出异常的地方使用throw关键字,使用如下。

  1. public int getInt(String str){
  2. if(str == null){
  3. throw new IllegalArgumentException("姓名不能为空");
  4. }
  5. return Integer.parseInt(str);
  6. }

IllegalArgumentException的父类是RuntimeException,在手工抛出时不需要在方法上约定可能抛出的异常,如果换成Exception,就需要在方法签名上声明它同时一定要调用它,否则就会报错。如下:

  1. public class ExceptionTest7 {
  2. public static void main(String[] args) {
  3. int num = 0;
  4. //调用
  5. try{
  6. num = getInt(null);
  7. }catch(Exception e){
  8. System.out.println(e.getMassage());//获取异常的字符串消息,这里就是“姓名不能为空”
  9. }
  10. System.out.println(num);
  11. }
  12. public static int getInt(String str) throws Exception{//在签名上声明
  13. if(str == null){
  14. throw new Exception("姓名不能为空");//手动抛出
  15. }
  16. return Integer.parseInt(str);
  17. }
  18. }

自定义异常类

创建一个异常类让它继承于Exception就可以了,但是需要注意的是,创建的时候要定义super构造函数,而且也需要创建一个空的构造函数,不然会报错。如下。

  1. public class ParamNullException extends Exception {
  2. public ParamNullException() {
  3. }
  4. public ParamNullException(String msg) {
  5. super(msg);
  6. }
  7. }

内部类

在过去内部类经常用于解决子类只能继承一个父类的缺陷,在Android场景上使用的多一些,但是随着Java的不断升级,其使用场景就越来愈少了。
如下,内部类InnterTool创建在外部类Outer里面。

  1. public class Outer {
  2. public class InnerTool { // 内部类
  3. public int add(int a,int b){
  4. return a+b;
  5. }
  6. }
  7. }

如果想调用内部类,就要先实例化,但是实例化只能在外部类内部,语法和普通类一样,例子如下。

  1. public class OuterUtil {
  2. public class InnerTool { // 内部类
  3. public int add(int a,int b){
  4. return a+b;
  5. }
  6. }
  7. private InnerTool tool = new InnerTool();
  8. }

外部访问内部类,内部类的访问控制修饰符需要时public,而且实例化内部类比较麻烦,不建议,语法如下:

  1. OuterUtil.InnerTool tool = new OuterUtil().new InnerTool();

静态内部类,只需增加static关键字即可,声明为静态内部类后,可以直接调用内部类,不需要先实例化外部类,如下。

  1. package com.youkeda.test;
  2. import com.youkeda.util.OuterUtil;
  3. // 静态内部类是需要单独 import 的
  4. import com.youkeda.util.OuterUtil.InnerTool;
  5. public class OuterUtilTest {
  6. public static void main(String[] args){
  7. InnerTool tool = new InnerTool();
  8. int sum = tool.add(1,2);
  9. System.out.println(sum);
  10. }
  11. }

局部内部类:在方法内部定义一个类,如下。

  1. public class Tester {
  2. public void test(){
  3. class B{
  4. int a;
  5. }
  6. B b = new B();
  7. }
  8. }

匿名类

  1. 匿名类可以直接实现接口的实例化。 ```java public class ATest {

    public static void main(String[] args){ A a = new A(){

    1. public void method(){
    2. System.out.println("执行内部类");
    3. }

    }; a.method(); }

} //A a = new A(){};这个语法等同于下面 public class AImpl implements A{ public void method(){ System.out.println(“执行类”); } }

  1. 2. 继承父类
  2. ```java
  3. public class Sub {
  4. public void print(){
  5. }
  6. }
  7. public class SubTest {
  8. public static void main(String[] args){
  9. Sub sub = new Sub(){
  10. public void print(){
  11. System.out.println("执行内部类");
  12. }
  13. };
  14. sub.print();
  15. }
  16. }
  17. //相当于
  18. public class SubNode extends Sub {
  19. public void print(){
  20. System.out.println("执行");
  21. }
  22. }

抽象类

Java的继承关系中,抽象类首先时一个父类,实例化必须有子类,如同接口要通过实现类实例化一样。抽象类也可以添加普通方法方便子类复用。
例子如下:

  1. // 定义一个武器的抽象类
  2. public abstract class Weapon{
  3. // 抽象方法:攻击
  4. public abstract void attack();
  5. }

子类必须实现抽象方法。

  1. public class GoldenBar extends Weapon {
  2. public void attack(){
  3. System.out.println("使用金箍棒进行劈一棍");
  4. }
  5. }

接口的默认方法

接口的默认方法,实现类可以不实现(也就是可以覆盖也可以不覆盖),直接调用默认方法
默认方法的语法如下:

  1. public interface Vehicle {
  2. default void print(){
  3. System.out.println("我是一辆车!");
  4. }
  5. }