面向对象高级三:内部类 枚举 泛型 java.lang包下常用API
一.内部类1.内部类概述2.成员内部类实例内部类1成员内部类可以定义类的一切成员2当创建对象时不能直接给内部类创建对象而要先创建外部类的对象 然后new成员内部类的对象3在成员内部类的实例方法中 可以直接访问外部类的成员4在成员内部类的实例方法中访问三个位置不同值的变量3.静态内部类省了一个外部类对象1静态内部类 可以直接New出来2静态内部类无论是实例方法还是静态方法只能直接访问外部类的静态成员但不能直接访问外部类的实例成员4.局部内部类鸡肋5.**匿名内部类1认识匿名内部类本质是子类-------普通代码只用到一次 不必专门为此设定一个类优化计算机会自动把这个匿名内部类编译成一个子类 然后立即创建出一个子类对象2匿名内部类的使用场景本来既要创建类又要在测试类里创建对象现在直接在测试类创建一个不需要名声类的对象匿名内部类直接在这个匿名类里进行原本需要在类里进行的操作或者更简化成也可以直接实现接口的方法3注意事项为什么a 100;会报错匿名内部类本质是一个类的子类 / 接口实现类它的类体和普通类一样只允许成员变量包括静态 / 实例方法抽象 / 实例 / 静态构造代码块 / 静态代码块内部类不能直接放执行语句比如赋值、打印、循环等这些语句必须包裹在方法、构造代码块或静态代码块里。6.对比内部类类型创建方式核心语法依赖外部类对象访问外部类成员限制适用场景成员内部类new 外部类.new 内部类()是可访问所有成员包括 private外部类和内部类强关联复用外部类成员静态内部类new 外部类.静态内部类()否仅能访问静态成员无需外部类对象独立使用内部类局部内部类仅在方法内new 局部内部类()是隐含可访问外部类 方法 final 变量方法内临时使用复用逻辑匿名内部类new 接口/抽象类() { 重写方法 }是隐含可访问外部类 方法 final 变量快速实现接口 / 抽象类一次性使用二.枚举1.认识枚举------------------------------------------抽象枚举------------------------------枚举常量可以被视为已经实例化的对象因此它们不能再使用new关键字来创建对象------------------2.枚举的常见应用场景做信息标志和分类并且在测试运行时 只能填所枚举过的常量三.泛型1.认识泛型没有添加泛型时 集合可以添加任何元素此时强制转换类型有可能出错加了后就能约束操作 避免报错2.泛型类E数据类型 e参数--------------------------------------泛型类可以声明多个类型变量---------------------------------------泛型可以通过继承某个类 它的数据可以是Animal或者Animal的子类3.泛型接口应用场景系统需要处理老师和学生的数据提供两个功能保存信息和根据名称查询数据------------------接口的泛型继承后 实现他的类的类型也只能是泛型继承的类或者子类4.泛型方法 泛型通配符 上下限1泛型方法不是泛型方法原因此时E不是这个方法自己定义的 而是这个泛型类声明给到这个方法使用的-----------------在创建泛型类对象/实现泛型接口时需要通过尖括号指定实际类型而调用泛型方法不用传入的参数是什么类型就是什么类型eg.----------------报错原因 虽然BMW和BENZ都继承了Car 但ArrayListBMW ArrayListBENZ和ArrayListCar并不存在继承关系此时需要用到泛型方法 但要注意的是为避免任何类型都能加到T内 需要限定T必须是Car及其子类2泛型通配符用T代表一个东西通用类、工具类、单个数据用E代表集合 / 数组里的元素List、Map、自定义容器T/E 是确定的类型必须先声明能读能写? 是不确定的类型不用声明代表任意 / 未知类型当你不关心具体类型只做通用操作 → 用于上述例子而言要限定类型也可以用extends。。。3上下限extendsCar上限Car及其子类superCar下限Car及其父类通配符类型读写规则适用场景? extends T只能读get不能写除了nullset读取数据生产者? super T可以写 T / 子类只能读成 Object写入数据消费者(Plate? extends Fruit能接收PlateFruitPlateApplePlateBanana但编译器不知道盘子里具体装的是什么可能是PlateApple→ 只能放Apple可能是PlateBanana→ 只能放Banana可能是PlateFruit→ 可以放Apple/Banana为了保证类型安全编译器禁止向? extends T类型的容器中写入任何非null的值super不管盘子是 PlateFruit / PlateFood放进去一个 Apple / Banana都是安全的Apple是FruitFruit是Food→ 怎么放都不会类型不匹配super能读但只能读成Object因为盘子可能是PlateFoodPlateObject编译器不知道具体是哪个父类所以只能安全地当成Object读出来。1.? extends 水果上界只能往外拿不能往里放你不知道盘子里是苹果还是香蕉不敢乱塞东西2.? super 水果下界只能往里放拿出来只能当 Object反正都是水果 / 食物放苹果香蕉绝对安全应用另5.泛型的注意事项擦除问题 基本数据类型问题1擦除问题class文件底层还是基于object类型的 只在赋值时强转 泛型只在写代码时进行约束--关于桥接方法但 Java编译后泛型会被删掉》编译器自动加个桥接方法对上 看不见也不用写2里必须是包装类型 不能是基本数据类型四.java.lang包下常用API1.Object类1toString重写后 可以输出内容而非地址2equalsequals默认比较地址是否相同 此时也能实现 要比较两个内容是否相同 就要重写equals方法3hascode方法class Person { private String name; private int age; // 重写equals Override public boolean equals(Object o) { if (this o) return true; if (o null || getClass() ! o.getClass()) return false; Person person (Person) o; return age person.age Objects.equals(name, person.name); } // 重写hashCode基于equals中用到的属性name age Override public int hashCode() { // 用Objects.hash()简化底层是组合属性计算哈希值 return Objects.hash(name, age); } // 构造方法 public Person(String name, int age) { this.name name; this.age age; } }hashCode()vsequals()核心关系场景要求反例后果a.equals(b) truea.hashCode() b.hashCode()HashSet/HashMap 无法去重a.equals(b) falsea.hashCode()尽量b.hashCode()哈希表效率降低大量元素挤在一个桶对象属性未修改hashCode()返回值不变哈希表中对象 “丢失”4clone注意clone方法是用protected修饰的 直接调用会报错 应在子类(extends Object)中重写clone-------此时直接调用还会报错 牵扯到处理异常----------------------2.Objects1equals方法如果s1为null的话 调用s1的equals方法 就会出现空指针异常但是Objects.equals不会---Objects源码先确定a不为空 再比较ab2isNull方法或者isNull源码3nonNull方法3.包装类1Valueof装、intValue拆实现万物皆对象但实际代码中会自动装箱拆箱用途泛型和集合不支持使用基本类型 只能使用对应的引用类型自动装箱也会自己调用valueOf 所以应关注valueOf的源码2字符串类型转换toStringvalueOf结果都是231更好的方案直接调用valueOf4.StringBuilder StringBuffer(1)StringBuilder(StringBuilder重写了toString方法 所以输出的是内容)------String是不可变字符串------------------(2)StringBuffer线程安全在很多人一起修改字符串时 StringBuffer更安全5.StringJoiner则StringBuild的案例可以简化为
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2453460.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!