2020-07-20(接口、各种类、异常)

2020-07-20  本文已影响0人  MHLEVEL

个人笔记,没有参考价值😈,为节约您的学习时间,请绕道查找其他资料
接口中的方法都是且只能用 public abstract 修饰,所以这两修饰符也可以省略
接口中不能定义局部变量,定义的变量默认都是 public static final 修饰的,这三个修饰符同样可以省略

接口中可以有缺省实现的方法,要用 default 修饰(Java8),接口中有 default 修饰的方法在继承类中可以选择实现,也可以选择不实现,直接用 default 那个实现也是可以的。如果一个类实现了两个接口,并且两个接口里有相同的接口实现,编译器会报错
也可以有私有的方法,用 private 修饰(Java9)

可用的类中必须要实现接口中的所有方法
抽象类不用(如图示)


接口类、抽象类、可实例化的类

静态内部类是在类中用 static 修饰的类,可以有访问控制符。静态内部类和静态方法,静态变量一样,都是类的组成部分。静态内部类也是类,在继承,实现接口方面是一样的

package com.geekbang.supermarket;

public class Phone extends MerchandiseV2 {

    // 给Phone增加新的属性和方法
    private double screenSize;
    private CPU cpu;
    private int memoryG;
    private int storageG;
    private String brand;
    private String os;

    // >> TODO 静态内部类,是在类中使用static修饰的类
    // >> TODO 静态内部类,可以有访问控制符。静态内部类和静态方法,静态变量一样,都是类的静态组成部分
    // >> TODO 静态内部类也是类,在继承,实现接口方面,都是一样的。以后我们讲的类,不特殊说明,在这方面都是一样的
    public static class CPU {
        private double speed;
        private String producer;

        public CPU(double speed, String producer) {
            this.speed = speed;
            this.producer = producer;
        }

        public double getSpeed() {
            // >> TODO 静态内部类,代码和这个类本身的访问权限一样,可以访问外部(Phone)的private属性
            // >> TODO 注意,这并不少说它可以访问private变量,
            // >> TODO 静态内部类是静态的,就好像静态方法一样,没有this自引用,可以通过引用访问Phone对象的private属性
            // 仅作演示访问性,不具有实际意义
            Phone phone = null;
            phone.memoryG = 99;
            return speed;
        }

        public void setSpeed(double speed) {
            this.speed = speed;
        }

        public String getProducer() {
            return producer;
        }

        public void setProducer(String producer) {
            this.producer = producer;
        }

        @Override
        public String toString() {
            return "CPU{" +
                "speed=" + speed +
                ", producer='" + producer + '\'' +
                '}';
        }

        // >> TODO 静态内部类,里面可以有任意合法的类的组成部分,包括静态内部类
//        public static class ABC{
//
//        }

    }

    public void accessStaticClass(){
        // >> TODO 同样,外部类也可以访问静态内部类(CPU)的private属性
        // 仅作演示访问性,不具有实际意义
        this.cpu.producer = "";
    }


    public Phone(
        String name, String id, int count, double soldPrice, double purchasePrice,
        double screenSize, double cpuHZ, int memoryG, int storageG, String brand, String os
    ) {

        this.screenSize = screenSize;
        // >> TODO 可以像平常的类一样使用静态内部类
        this.cpu = new CPU(cpuHZ, "Default");
        this.memoryG = memoryG;
        this.storageG = storageG;
        this.brand = brand;
        this.os = os;

        this.setName(name);
        this.setId(id);
        this.setCount(count);
        this.setSoldPrice(soldPrice);
        this.setPurchasePrice(purchasePrice);
    }

    public void describePhone() {

        System.out.println("此手机商品属性如下");
        describe();
        System.out.println("手机厂商为" + brand + ";系统为" + os + ";硬件配置如下:\n" +
            "屏幕:" + screenSize + "寸\n" +
            "cpu信息:" + cpu + " \n" +
            "内存" + memoryG + "Gb\n" +
            "存储空间" + storageG + "Gb\n");

    }

}

// >> TODO 非共有类和静态内部类,实际区别就在于能否访问类的private成员
class Memory {
    private long capacity;
    private String producer;

    public Memory(long capacity, String producer) {
        this.capacity = capacity;
        this.producer = producer;
    }

    public void test(){
        // >> TODO 在类的外面的代码,不能访问类的private成员
        // 仅作演示访问性,不具有实际意义
//        Phone ph = null;
//        ph.screenSize = 9;
    }

    public long getCapacity() {
        return capacity;
    }

    public void setCapacity(long capacity) {
        this.capacity = capacity;
    }

    public String getProducer() {
        return producer;
    }

    public void setProducer(String producer) {
        this.producer = producer;
    }
}

成员内部类是在类中直接定义一个类,可以有访问修饰符。成员内部类和成员方法、成员变量一样,都是类的组成部分。
成员内部类不可以包含任何静态的成分,比如静态方法,静态变量,静态内部类,否则会造成内外部类初始化问题,可以有final static的基本数据类型变量

成员内部类中有一个外部类的引用,其访问外部类的对象的成员属性就是使用这个引用,完整写法是:类名.this.属性/方法

匿名类 is coming!

匿名内部类实例演示

关于各种的小总结

理解: 类只有一个,但实例是可以多个~

异常
所有异常的父类:Throwable

如果继承链路中不是继承的error 也不是继承的 RuntimeException ,那么这种就是checked exception

关于 checked exception 和 unchecked exception 异常一篇博文

如果一个接口的方法定义中没有抛出异常,那么在他的实现类中该方法也不建议抛出异常,因为这样会改变接口中这个方法的定义。但是可以在实现类中try catch 住异常

show code
IntfWithEx.java (接口定义)

public interface IntfWithEx {

    void danger() throws Exception;

    void safe();

}

ImplIntfWithEx.java (实现类)

public class ImplIntfWithEx implements IntfWithEx {

    @Override
    public void danger() throws Exception {
        // >> TODO 接口中声明了抛出异常,实现类中可以抛,也可以不抛。抛的话必须是接口声明的类或其子类
        throw new Exception("");
    }

    @Override
    public void safe() {
        // >> TODO 接口中没有声明抛出异常,实现类中可以抛RuntimeException,也可以不抛。
        // >> TODO 如果抛 checked exception,就会出错
        // >> TODO 可以选择catch住 checked exception,然后将它封在RuntimeException里
//         throw new Exception();
//         throw new RuntimeException();
    }
}

当 ImplIntfWithEx 类中safe() 方法需要抛出异常时应该try catch 住

public class ImplIntfWithEx implements IntfWithEx {

    @Override
    public void danger() throws Exception {
        // >> TODO 接口中声明了抛出异常,实现类中可以抛,也可以不抛。抛的话必须是接口声明的类或其子类
        throw new Exception("");
    }

    @Override
    public void safe() {
        // >> TODO 接口中没有声明抛出异常,实现类中可以抛RuntimeException,也可以不抛。
        // >> TODO 如果抛 checked exception,就会出错
        // >> TODO 可以选择catch住 checked exception,然后将它封在RuntimeException里
        try {
            throw new Exception();
        } catch (Exception e) {
            e.printStackTrace();
        }
//         throw new RuntimeException();
    }
}

Java 异常的最终归宿,要么沿着方法调用栈一路抛,最终造成当前线程出错退出,要么被 catch 住。

try catch finally 在finally 中给return用的变量赋值是没有用的

上一篇下一篇

猜你喜欢

热点阅读