美文网首页
2020-07-20(接口、各种类、异常)

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

作者: MHLEVEL | 来源:发表于2020-07-20 11:54 被阅读0次

    个人笔记,没有参考价值😈,为节约您的学习时间,请绕道查找其他资料
    接口中的方法都是且只能用 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!

    匿名内部类实例演示

    关于各种的小总结

    • 枚举
      枚举就是有固定个数实例的类;枚举的父类是Enum
    • 非公有类
      最不特殊的类,可以认为就是被缺省访问控制符修饰的类,也就是说,和public class 的区别仅仅是可以被访问的范围不一样;如果一个文件只有非公有类,那么类名可以和文件名不一样
    • 内部类
      内部类的特殊之处在于可见性和可以访问的数据以及方法,内部类会被认为是类本身的代码,所以外部类的 private 成员对其可见;
      三种内部类的对比记忆:


      三种内部类
    • 匿名类
      匿名类是一种创建接口和抽象类对象的语法,任何可以 new 一个对象的地方都可以使用匿名类;匿名类只能实现/继承一个接口/抽象类,本身没有名字;如果是在成员方法或者成员方法赋值时创建匿名类,那么会有外部对象的 this 自引用;匿名类也可以访问外部类的 private 属性

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

    异常
    所有异常的父类:Throwable

    • 按异常的继承关系分类
      两类异常:Error 和 Exception
      其中 Error 是程序不可修复的(比如磁盘不够用等等资源不够用之类的...)
      和业务逻辑有关的,可以补救的就是 Exception
    • 按处理方式不同分类
      checked excepted : 语法要求必须要用try catch 或者 throws 语句处理的异常
      unchecked exception : 语法不要求要用 try catch 或者throws 语句处理的异常
      Error 和 RuntimeException 是 unchecked exception 的父类,我们一般使用 RuntimeException


      RuntimeException的子类们...,👆这些都是unchecked exception

    如果继承链路中不是继承的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用的变量赋值是没有用的

    相关文章

      网友评论

          本文标题:2020-07-20(接口、各种类、异常)

          本文链接:https://www.haomeiwen.com/subject/cbxekktx.html