14.接口的实现以及新特性、内部类、异常

1. 接口的实现

interface  USB{
    //常量:定义的USB的尺寸等

    void start();

    void stop();
}

class Printer implements USB{//打印机

    @Override
    public void start() {
        System.out.println("打印机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("打印机结束工作");
    }
}

class KeyBoard implements USB{

    @Override
    public void start() {
        System.out.println("键盘开始工作");
    }

    @Override
    public void stop() {
        System.out.println("键盘结束工作");
    }
}
public class USBTest {

    public static void main(String[] args) {
        //1. 创建了接口的实现类的对象
        Printer printer = new Printer();
//        operate(printer);
        //2. 创建了接口的实现类的匿名对象
//        operate(new KeyBoard());

        //3. 创建接口的匿名实现类的对象
        USB usb1 = new USB(){
            public void start(){
                System.out.println("mp3开始工作");
            }

            public void stop(){
                System.out.println("mp3结束工作");
            }
        };
//        operate(usb1);

        //4. 创建接口的匿名实现类的匿名对象
        operate(new USB(){

            @Override
            public void start() {
                System.out.println("电纸书开始工作");
            }

            @Override
            public void stop() {
                System.out.println("电纸书结束工作");
            }
        });
    }

    public static void operate(USB usb){ //USB usb = new Printer();

        System.out.println("========检测外部设备=========");

        usb.start();

        System.out.println("==========具体的数据传输过程===========");

        usb.stop();
    }

}

相对应的,抽象类也可以考虑使用匿名子类的方式。比如:

abstract class Person {
    String name;
    int age;

    public abstract void eat();

    public void walk(){
        System.out.println("人:走路");
    }
}

abstract class Order{
    public void method(){
        System.out.println("method");
    }
}
public class PersonTest {
    public static void main(String[] args) {
        //创建Person类的匿名子类的对象
        Person p1 = new Person(){

            @Override
            public void eat() {
                System.out.println("工人吃饭");
            }


        };

        p1.eat();
        System.out.println(p1.getClass());

        Order order = new Order(){};

        order.method();
    }
}

2. 接口的新特性

/*       jdk8新特性:
 *           静态方法(有方法体)、默认方法(有方法体)
 *       jdk9新特性:
 *           私有方法
 */

知识点1:接口中的静态方法只能被接口调用,实现类不可以调用
知识点2:实现类可以重写接口中的默认方法
— 1)实现类如果没有重写接口中的默认方法,则实现类的对象调用的是接口中的默认方法
— 2) 实现类如果重写了接口中的默认方法,则实现类的对象调用的是重写的后的方法
知识点3:如果实现类实现的多个接口中定义了同名同参数的方法,则在实现类没有重写此方法的情况下,会报错—> 接口冲突为了避免接口冲突,要求实现类必须重写此同名同参数的方法。
知识点4:如果子类(或实现类)继承的父类和实现的接口中定义了同名同参数的方法,则在子类(或实现类)没有重写此方法的情况下,不会报错。默认调用的是父类中声明的方法。—>类优先原则
知识点5:如何调用接口中的默认方法。见下面

interface CompareA{

    //静态方法
    public static void method1(){
        System.out.println("CompareA:武汉");
    }

    //默认方法
    public default void method2(){
        System.out.println("CompareA:北京");
    }

    default void method3(){
        System.out.println("CompareA:上海");
    }

    default void method4(){
        System.out.println("CompareA:深圳");
    }

}
interface CompareB{
    default void method3(){
        System.out.println("CompareB:上海");
    }
}

class SuperClass{
    public void method4(){
        System.out.println("SuperClass:深圳");
    }
}

class SubClass extends SuperClass implements CompareA,CompareB{
    public void method2(){
        System.out.println("SubClass:北京");
    }

    public void method3(){
        System.out.println("SubClass:上海");
    }

    public void method(){
        super.method4();//调用的是父类中声明的方法
        CompareA.super.method3();//调用接口中的默认方法
        CompareB.super.method3();
    }

}

3.相关练习

/**
 * 定义一个接口用来实现两个对象的比较。
 * interface CompareObject{
 *     public int compareTo(Object o);   //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
 *  }
 */
public interface CompareObject {
    //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
    int compareTo(Object o);
}


/**
 * 定义一个Circle类,声明redius属性,提供getter和setter方法
 *
 */
public class Circle {
    private double radius;//半径

    @Override
    public String toString() {
        return "Circle{" +
                "radius=" + radius +
                '}';
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public Circle(double radius) {
        this.radius = radius;
    }

    public Circle() {
    }
}

package com.atguigu.exer1;

/**
 * 定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
 * 在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。
 *
 */
public class ComparableCircle extends Circle implements CompareObject{

    public ComparableCircle(double radius) {
        super(radius);
    }

    public ComparableCircle() {
    }

    @Override
    public int compareTo(Object o) {
        if(this == o){
            return 0;
        }
        if(o instanceof ComparableCircle){
            ComparableCircle c = (ComparableCircle)o;

//            return (this.getRadius() > c.getRadius())? 1 : ((this.getRadius() == c.getRadius())? 0 : -1);

            return Double.compare(this.getRadius(),c.getRadius());
        }

//        throw new RuntimeException("输入的类型不匹配");
        return 0;
    }
}

/**
 * 定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
 *
 */
public class InterfaceTest {
    public static void main(String[] args) {
        CompareObject c1 = new ComparableCircle(2.3);
        CompareObject c2 = new ComparableCircle(2.4);

        System.out.println(c1.compareTo(c2));

    }
}

4. 类的成员之五:内部类

* 类的成员之五:内部类(innerclass)
*
* 1. 分类:成员内部类: 静态的成员内部类、非静态的成员内部类
*          局部内部类:方法内、构造器内、代码块内
2. 内部类的内容需要大家掌握的有如下三个点:
*     ① 如何创建成员内部类的实例
*     ② 如何在成员内部类中调用外部类的相关结构
*     ③ 关于局部内部类的常见使用的掌握

4.1 成员内部类

* 3. 理解成员内部类:
*          一方面,内部类作为类:
*              > 内部可以定义属性、方法、构造器、代码块、内部类....
*              > 可以被final修饰
*              > 可以被abstract修饰
*
*          另一方面,内部类作为外部类的成员:
*              > 可以被4种权限修饰结构来修饰
*              > 可以被static修饰
*              > 可以调用外部类的结构:属性、方法、。。。
class Person{
    String name = "Tom";


    //静态的成员内部类
    public static class Dog{
        public void shout(){
            System.out.println("汪~汪~汪~");
        }

    }
    //非静态的成员内部类
    public class Bird{

        String name = "布谷鸟";

        public void shout(){
            System.out.println("喳~喳~喳~");
        }

        public void show(String name){
            System.out.println(name);//show()的形参
            System.out.println(this.name);//Bird类中的成员变量
            System.out.println(Person.this.name);//外部类的成员变量

            this.eat();
            Person.this.eat();
        }

        public void eat(){
            System.out.println("鸟找食物吃");
        }
    }

    public void method(){
        //局部内部类
        class A{

        }
    }
    public Person(){
        //局部内部类
        class B{

        }
    }

    {
        //局部内部类
        class C{

        }
    }

    public void eat(){
        int num = 1;
        System.out.println("人吃饭");

    }
}

public class InnerClassTest {

    public static void main(String[] args) {
        //1.创建静态的成员内部类的对象
        Person.Dog dog = new Person.Dog();
        dog.shout();
        //2. 创建非静态的成员内部类的对象
//        Person.Bird bird = new Person.Bird();
        Person p = new Person();
        Person.Bird bird = p.new Bird();
        bird.shout();

        System.out.println();
        bird.show("黄鹂");


    }
}

4.2 局部内部类的使用

/**
 *
 * 关于局部内部类的常见使用的掌握
 *
 */
public class InnerClassTest1 {

    //局部内部类的如下场景少见
    public void method(){
        //内部类
        class InnerClass{

        }

        //使用内部类
    }

    public Comparable getInstance(){
        //内部提供一个接口的实现类
//        class MyComparable implements Comparable{
//
//            @Override
//            public int compareTo(Object o) {
//                return 0;
//            }
//        }
//
//        return new MyComparable();

        //上述代码可以修改为:创建接口的匿名实现类的匿名对象
        return new Comparable(){

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
}
Button btn = XXX.getButtonById("btn001");
btn.setOnClickListener(new ClickListener(){
	public void click(){
		alert("haha");
	}
});

5. 异常的体系结构

* 一、异常的体系结构:
*   java.lang.Throwable
*      |----java.lang.Error :错误 ,我们不编写针对性的代码进行处理。
*             |----StackOverflowError \ OutOfMemoryError
*      |----java.lang.Exception : 异常,我们可以编写针对性的代码进行处理
*          |---编译时异常:
*              |---FileNotFoundException
*              |---IOException
*          |---运行时异常:
*               |----InputMismatchException
*               |----ArrayIndexOutOfBoundsException
*               |----NullPointerException
*               |----ClassCastException
*               |----NumberFormatException
*               |----ArithmeticException
*
*
* 复习:java程序执行过程分为:过程一:编译:javac.exe  --->此过程中出现的异常,称为:编译时异常
*                           过程二:运行:java.exe   --->此过程中出现的异常,称为:运行时异常

6. 常见的“异常”及举例

6.1 Error

/**
 *
 *  Error: Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。
 *
 *  一般不编写针对性的代码进行处理。
 *
 */
public class ErrorTest {
    public static void main(String[] args) {
        //StackOverflowError
//        main(args);
        //设置虚拟机参数:-Xms50m -Xmx50m
        //报错误:OutOfMemoryError:Java heap space
        byte[] arr = new byte[1024 * 1024 * 100];//100MB


    }
}

6.2 Exception

public class ExceptionTest {

    //InputMismatchException
    @Test
    public void test1(){
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入你的年龄:");
        int age = scan.nextInt();
        System.out.println(age);
    }
    //ArrayIndexOutOfBoundsException
    @Test
    public void test2(){
        int[] arr = new int[10];
        System.out.println(arr[-1]);
    }

    //NullPointerException
    @Test
    public void test3(){
        //情况1:
//        int[] arr = null;
//        System.out.println(arr[0]);
        //情况2:
//        int[][] arr = new int[10][];
//        System.out.println(arr[0][0]);

        //情况3:
        String str = "hello";
        str = null;
        System.out.println(str.toString());//bank.getCustomer(0).getAccount().withdraw(500);


    }

    //ClassCastException
    @Test
    public void test4(){
        Object obj = new String("hello");
        Date date = (Date)obj;
    }

    //NumberFormatException:数字转换异常
    @Test
    public void test5(){
        String str = "123";
        str = "123a";
        int num = Integer.parseInt(str);
        System.out.println(num);
    }

    //ArithmeticException:算术异常
    @Test
    public void test6(){
        int m = 10;
        int n = 0;
        System.out.println(m / n);
    }

    @Test
    public void test7(){
//        File file = new File("hello.txt");
//        FileReader fr = new FileReader(file);
//        char[] buffer = new char[4];
//        int len;
//        while((len = fr.read(buffer)) != -1){
//            String str = new String(buffer,0,len);
//            System.out.print(str);
//        }
//        fr.close();
    }
}

7. 异常的处理方式一:try-catch-finally

7.1 异常处理的概述

 * 二、异常(Exception)的处理
 *  * 有两种方式:方式一:try-catch-finally  方式二:throws + 异常类型
 *  * Java提供的是异常处理的抓抛模型。
 *  程序执行过程中,出现了异常,并处理异常,对应着两个过程。
 *  过程一:“抛”:程序执行过程中,一旦出现异常,就会在异常位置生成一个对应异常类型的对象,并将此
 *  对象抛出。
 *  * 过程二:“抓”  可以广义的理解为异常处理的两种方式。

7.2 try-catch

 * 三、try-catch-finally的使用
 *  * try{
 *     //可能出现异常的代码
 *  * }catch(XxxException e){
 *    处理异常的方式
 * }catch(XxxException e){
 *    处理异常的方式
 * }
 * ...
 * finally{
 *    一定会被执行的代码
 * }
 *  * 说明:
 * 1. finally是可选的。
 * 2. try中声明的变量,在出了try结构之后就失效了
 * 3.
 * ① 执行try中的代码时,一旦执行过程中出现异常,则会在指定代码的位置生成相应的异常类的对象,并将此
 *    对象抛出。之后try中的代码不再执行。
 * ② 抛出的对象根据其类型依次匹配try后面的catch,一旦匹配成功,就进入catch结构,进行异常的处理。处理完以后,
 * 不再匹配其后的catch结构,而是跳出try-catch继续执行其后的代码。
 * 4. 如果声明了多个catch结构,且多个catch中的异常类型没有子父类关系,则多个catch结构谁先声明,谁后声明都可以。
 *    如果多个catch中的异常类型满足子父类的关系,则子类异常类型必须声明在父类异常类型的上面,否则报错。
 *  * 5. 常见的catch中异常处理的方式:
 *   ① 自定义输出信息
 *   ② 异常类的方法:getMessage() / printStackTrace()
 *  * 6. 经验:
 *   ① 实际开发中,针对于运行时异常,通常我们就选择不进行异常的处理了。
 *   ② 实际开发中,针对于编译时异常,我们必须进行异常的处理,否则编译不通过。
 *     进行try-catch处理以后,就可以编译通过。那运行是否可以通过,就需要真正执行来看了。
 *  * 7. try-catch-finally结构可以嵌套使用
  • 代码举例
public class ExceptionTest1 {

    //NumberFormatException:数字转换异常
    @Test
    public void test1(){
        try {
            String str = "123";
            str = "123a";
            int num = Integer.parseInt(str);//生成了一个NumberFormatException类的对象
            System.out.println(num);
        }catch(NullPointerException e){
            System.out.println("出现了空指针的异常.....");
        }catch(NumberFormatException e){
            //处理方式
            System.out.println("出现了数字转换异常....");
        }catch(Exception e){
            System.out.println("出现了异常....");
        }

        System.out.println("hello!");
    }
    //NullPointerException
    @Test
    public void test2(){
        try{
            String str = "hello";
            str = null;
            System.out.println(str.toString());

        }catch(NullPointerException e){
//            System.out.println(e.getMessage());

            e.printStackTrace();
        }


    }

    //ClassCastException
    @Test
    public void test3(){
        try{
            Object obj = new String("hello");
            Date date = (Date)obj;

        }catch(ClassCastException e){
            e.printStackTrace();
        }
    }

    @Test
    public void test7(){
        try {
            File file = new File("hello.txt");
            FileReader fr = new FileReader(file);
            char[] buffer = new char[4];
            int len;
            while ((len = fr.read(buffer)) != -1) {
                String str = new String(buffer, 0, len);
                System.out.print(str);
            }
            fr.close();
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

7.3 finally

/**
 * 测试finally的使用
 *
 * 1. 体会finally中存放一定会被执行的代码。
 *  说明:不管try、catch中是否存在未被处理的异常,不管是否存在return语句等。finally都要被执行的。
 *
 * 2. 什么样的代码需要声明在finally中呢?
 *     涉及到系统相关资源的位置。比如:IO流、网络Socket、数据库连接等
 *
 */
public class FinallyTest {

    @Test
    public void test1() {
        try {

            System.out.println( 10 / 0);

            File file = new File("hello.txt");
            FileReader fr = new FileReader(file);
            char[] buffer = new char[4];
            int len;
            while ((len = fr.read(buffer)) != -1) {
                String str = new String(buffer, 0, len);
                System.out.print(str);
            }
            fr.close();
        }catch(IOException e){
            e.printStackTrace();
        }

        System.out.println("程序执行结束");
    }

    @Test
    public void test2() {
        try {

            System.out.println(10 / 0);

            File file = new File("hello.txt");
            FileReader fr = new FileReader(file);
            char[] buffer = new char[4];
            int len;
            while ((len = fr.read(buffer)) != -1) {
                String str = new String(buffer, 0, len);
                System.out.print(str);
            }
            fr.close();
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            System.out.println("程序执行结束");

        }

    }
    @Test
    public void test3(){
        System.out.println(method1());
    }

    public int method1(){
        try{
            return 1;
        }catch(Exception e){
            e.printStackTrace();
        }finally{

            return 2;
        }

    }

    @Test
    public void test4() {
        FileReader fr = null;
        try {
            File file = new File("hello.txt");
            fr = new FileReader(file);
            char[] buffer = new char[4];
            int len;
            while ((len = fr.read(buffer)) != -1) {
                String str = new String(buffer, 0, len);
                System.out.print(str);
            }

        }catch(IOException e){
            e.printStackTrace();
        }finally{
            //流资源的关闭操作。此操作必须执行,否则会出现内存的泄漏
            try {
                if(fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println("程序执行结束");
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值