一、接口

1、概念

  1. 抽象类
  2. abstract class A {
  3. show();
  4. add();
  5. }
  6. abstract class B {
  7. fly();
  8. run();
  9. }
  10. class Robot extends A{
  11. }
  12. public interface MyInterface {
  13. public abstract void method(); // 接口中的方法定义
  14. }
  15. 重点:抽象类是必须要被子类继承实现的。如果一个类既想实现A 中的方法又想实现B中的方法是无法完成的。
  16. 但是java类是单继承多实现的。
  17. 接口就是用来定义规则的,接口是为了拓展java单继承的缺陷产生的。

2、语法

属性
- 接口中的属性,默认都是静态常量,访问权限都是public。
- 方法
* - 接口中的方法,默认都是抽象方法,访问权限都是public。

  1. package com.qfedu.day07;
  2. /**
  3. * @Author laoyan
  4. * @Description TODO
  5. * @Date 2022/3/9 9:59
  6. * @Version 1.0
  7. *
  8. *
  9. * 接口中可以定义:
  10. *
  11. * - 属性
  12. * - 接口中的属性,默认都是静态常量,访问权限都是public。
  13. * - 方法
  14. * - 接口中的方法,默认都是抽象方法,访问权限都是public。
  15. *
  16. */
  17. public interface MyInterface {
  18. /**
  19. * 接口中只有两样东西
  20. * 1、常量
  21. * 2、抽象方法
  22. */
  23. int a = 10;
  24. void show();
  25. }

3、接口和抽象类的异同

  1. 相同点:
  2. 1、都有抽象方法
  3. 2、都不能实例化 不能new 接口
  4. 3、都可以声明引用
  5. Calendar c = Calendar.getInstance();
  6. Animal a = new Dog();
  7. Flying 接口
  8. Flying fly = new Flying();// 错误
  9. Flying fly = new Plane();
  10. 4、抽象类和接口都有Object的所有方法
  11. 5、抽象类和接口都有与之对应的class文件 Flying.java --> Flying.class
  12. 不同点:
  13. 1、抽象类中可以有普通方法,接口中没有
  14. 2、抽象类中可以有普通变量,接口中全部是常量
  15. 3、抽象类也是类,可以有构造方法以及代码块。接口没有这些。

4、接口如何实现呢?

  1. public interface Flying {
  2. void fly();
  3. }

再写实现:

  1. public class Dog implements Flying{
  2. //alt + enter
  3. @Override
  4. public void fly() {
  5. System.out.println("飞狗Moco");
  6. }
  7. }

调用

  1. package com.qfedu.day07;
  2. /**
  3. * @Author laoyan
  4. * @Description TODO
  5. * @Date 2022/3/9 10:18
  6. * @Version 1.0
  7. */
  8. public class TestFlyingDemo {
  9. public static void main(String[] args) {
  10. Dog dog = new Dog();
  11. dog.fly();
  12. Plane plane = new Plane();
  13. plane.fly();
  14. /**
  15. * 接口 的多态
  16. */
  17. Flying dog2 = new Dog();
  18. dog2.fly();
  19. }
  20. }

5、需要注意的点:

1、抽象类也可以实现接口,只是里面的方法可以实现也可以不实现。

  1. public abstract class Animal implements Flying{
  2. }
  3. public class Pig extends Animal{
  4. @Override
  5. public void fly() {
  6. }
  7. }

2、一个类可以实现多个接口

public class Dog implements Flying,Running{}

3、接口和接口之间可以继承,还可以多继承

public interface ManRunning extends Running,Flying{
    void manRun();
}

4、两个接口中拥有同名的,同参数的方法,但是可能返回值不同,同一个类是无法同时继承这两个接口的。冲突了。
image.png
可以出现下面这种:
image.png

6、接口的多态:

image.png
作用:

 /**
     *
     *  继承的时候也有多态:
     *    Animal  dog = new Dog();
     *    1、参数多态
     *    2、返回值多态
     *   接口多态的用法:  跟继承的时候一样
     *           1、参数多态
     *      *    2、返回值多态
     * @param args
     */

    public static void show(Flying fly){
        fly.fly();
    }

    public static Flying show(){
        return new Plane();
    }

7、接口中的类型转换:

Flying f1 = new Dog(); // 向上转型自动的
Dog dog3 = (Dog) f1;// 向下转型,需要强制转换

因为强制类型转换有可能出现异常,所以要先判断再转换:
public static void show(Flying fly){
        if(fly instanceof Dog){
            Dog dog = (Dog) fly;
            System.out.println("fly 是狗");
        }
        if(fly instanceof Plane){
            Plane p= (Plane) fly;
            System.out.println("fly 是飞机");
        }
        fly.fly();
}

抽象类一般当做半成品

电脑:
interface Computer{
     // 显示器
    // cpu
     // 内存
    //硬盘
    // 贴牌以及售后
}

/*  抽象类可以当做   半成品  理解*/
abstract class   SubComputer implments Computer{
       // 显示器
       // cpu
      // 内存
      //硬盘
      实现以上方法
     // 留下 贴牌和售后
}

class  Lenovo extends SubComputer {
        // 贴牌和售后
}

二、异常

1、异常的由来
Throwable 有两个儿子: Error & Exception
Error : 错误 —> 坏了
Exception : 异常 —> 两个方向 编译时异常 和 运行时异常;
编译时异常: IDEA中编写代码立即爆红 过不了编译这个时期的。 java —> class
运行时异常: 编译正确,没毛病,运行的时候报错了 ,运行时异常 RuntimeException (重点)

int[] arr = {1,2}
arr[3];  // 数组下标越界

Plane  p = (Plane) dog ; // 数据类型转换异常
int  a = 10 / 0 ;  // 数据运算异常

2、异常出现后的处理办法
1) 可以通过try —catch 进行处理,处理了就没事儿了,否则,没人管,就交给虚拟机,虚拟机就报错。虚拟机一报错,后面代码不执行了。
try{

}catch(e){

}

异常中有一个非常常见的方法: e.printStackTrace();
作用是打印栈异常
image.png

package com.qfedu.day07_02;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/9 14:55
 * @Version 1.0
 */
public class Demo01 {

    /*
         public class RuntimeException extends Exception
         public class ArithmeticException extends RuntimeException

         我们学习的所有的异常,一般指的都是 RuntimeException
     */
    public static void main(String[] args) {
        //int a = 10 / 0;

        divide(10,0);
        System.out.println("我能出现吗?");
    }

    public static int divide(int a ,int b){

          int i = 1;
          try{
              /**
               * try 写业务
               */
               i = a / b;
          }catch(ArithmeticException e){
              // 如果抓住这个异常,准备怎么处理
              e.printStackTrace();
              //System.out.println("快看,有异常了,还是个算数异常");
          }

          return i;
    }
}

2) 不管了,向上抛

public static double array(int[] arr) throws ArrayIndexOutOfBoundsException {
         return arr[10];
    }

向上抛,抛的后果就是谁调用这个方法,谁处理,如果它也不处理,可以选择继续抛。

main  -->   a()   --> b()  -- c();

3) 万能的办法

public void add(){
     try{
          存放方法中的所有代码
    }catch(Exception e){
         e.printStackTrace();
    }

}

 public void add2()  throws Exception{

     // 不管出现啥异常,都扔出去。

}

4) 经常使用的地方
image.png

5) 可以进行多个catch 的案例:

try{
         可能发生异常的代码
}catch(异常一  e){ //捕获异常    e就是要捕获的异常
        对当前异常的处理
}catch(异常二  e){ //捕获异常    e就是要捕获的异常
        对当前异常的处理
}catch(Exception  e){ //捕获异常    e就是要捕获的异常
         对当前异常的处理
}

异常一:   代表数组下标越界
异常二:   代表空指针异常
如果你写成以上的多个catch 请将最大的那个父类异常,放在最后,否则都白写了。
编程经验告诉我们:所有的异常无需搞得那么细,直接用最大的Exception 去接收即可。

try{
         可能发生异常的代码
}catch(Exception  e){ //捕获异常    e就是要捕获的异常
         对当前异常的处理
}

6) try{} catch{} finally{}

try{
   代码从上到下依次执行,一直到有异常为止。


}catch(Exception e){
    e.printStackTrace();
    // 异常真的出现了,才会调用这个里面的代码  -- 有很大可能不执行
}finally{
   // 不管try 和 catch 执行不执行,此处的代码肯定执行。
}

finally 里面的代码一般都是关闭流或者数据库连接之类的代码

final  finally   老婆和老婆饼的关系

7) throw throws

throw  经常 表示手动抛出一个具体的异常,一般在方法中出现
LostWheelException lost =new LostWheelException;
throw  lost;

throws  一般出现在方法的参数的后面,表示该方法抛出了某个异常,需要调用者进行处理。

8) 自定义异常

package com.qfedu.day07_02;

/**
 * @Author 千锋大数据教学团队
 * @Company 千锋好程序员大数据
 * @Description 自定义的异常类
 */
class  FuShuException extends  Exception{
    // 异常的描述信息
    // 在根类 Throwable 中,有一个私有的属性 detailMessage,存储异常的描述信息。
    // 在自定义异常描述信息的时候,只需要添加一个有参的构造方法即可完成
    public FuShuException(){}
    public FuShuException(String message){
        //这行代码必须写
        // 调用父类中的构造方法,
        // 在父类中,再调用它的父类中的构造方法,一层层向上调用,最终可以调用到Throwable类中的有参构造
        // 实现对 detailMessage 属性的赋值。
        super(message);
    }
}
public class Demo02 {
    public static void main(String[] args) //throws FuShuException
    {
        Math math = new Math();

        try {
            math.div(2,-3);
        } catch (FuShuException e) {
            e.printStackTrace();
        }


    }
}

class  Math{
    //异常的声明(我们要给可能发生异常的方法进行异常的声明)----throws      作用:告诉别人我有可能发生异常
    public int div(int a,int b) throws FuShuException
    {
        if (b < 0){
            //创建异常对象并抛出
            throw  new FuShuException("除数为负数了");
        }
        return a/b;
    }
}

三、枚举

1、枚举的例子

package com.qfedu.day07_03;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/9 16:37
 * @Version 1.0
 */
public class TestEnum {

    public static void main(String[] args) {
        Season season = Season.AUTUMN;
        switch (season) {// int,char,String,枚举,byte,short,包装类
            case SPRING:
                System.out.println("春天来了");
                break;
            case SUMMER:
                System.out.println("夏天来了");
                break;
            case AUTUMN:
                System.out.println("秋天来了");
                break;
            case WINTER:
                System.out.println("冬天来了");
                break;
            default:
                System.out.println("其他季节");
                break;
        }
    }
}

2、语法:

public enum Gender {
    // 将这个枚举对象所有可能取到的值, 都列出来
    // 枚举中的元素, 也是标识符, 遵循大驼峰命名法
    Male, Female
}
public enum Month {
    Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
}
public enum Week {
    Mon, Tue, Wed, Thu, Fri, Sat, Sun
}

枚举类型一般用于表示一类数据,比如月份、性别、四季、周天。

3、作用
1)可以替代常量的表达,见名知意。
2) 如果觉得看见名字还不够,还想携带更多的信息,可以通过枚举中的构造方法来表示。

public enum OrderPayLogPaymentStatusEnum {

    //public static final WAITING_TRANSFER = 1;
    //public static final HAVE_TRANSFERRED = 2;
    /**
     * 未支付
     */
    WAITING_TRANSFER("1", "未支付"),
    /**
     * 未支付
     */
    HAVE_TRANSFERRED("2", "已支付");

    private String code;

    private String param;

    OrderPayLogPaymentStatusEnum(String code, String param) {
        this.code = code;
        this.param = param;
    }


    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }


    public String getParam() {
        return param;
    }

    public void setParam(String param) {
        this.param = param;
    }
}

4、代码

package com.qfedu.day07_03;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/9 16:36
 * @Version 1.0
 */
public enum Season { // 枚举类

    SPRING("春"),SUMMER("夏"),AUTUMN("秋"),WINTER("冬");
    String desc;
    Season(String desc){
        this.desc = desc;
    }
}
package com.qfedu.day07_03;

/**
 * @Author laoyan
 * @Description TODO
 * @Date 2022/3/9 16:49
 * @Version 1.0
 *
 *
 *     1、枚举其实就是一个特殊的类  -->  枚举类
 *      拥有Object的所有方法。
 *     2、 SRPING 其实就是Season 枚举类的实例化对象
 *     3、toString方法返回的是一个名字
 *     4、枚举不能被其他类或者枚举类继承。
 *     5、枚举类中可以写其他属性
 *     6、枚举类还可以写构造方法,一旦写了一个有参数的,无参数的构造方法自动消失,之前的实例化对象也会报错
 *     7、枚举类中可以编写普通方法和静态方法。但是作用不大。一般不写
 *     8、枚举可以继承接口,还可以重写Object中的方法 ,一般不写
 *
 */
public class Demo01 {
    public static void main(String[] args) {
        Season s1 = Season.SPRING; //

        System.out.println(s1.toString());
        System.out.println(Season.SPRING);

        System.out.println(Season.SUMMER.getDesc());
    }
}