文章目录
前言
做一下内部类笔记总结复习一下
一、内部类
1. 基本介绍
-
主要有成员内部类、静态内部类、局部内部类、匿名内部类(重点)
-
是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类
-
场景:当一个类需要封装某种信息或行为,但这种信息或行为可以组成类但没有足够的独立性或必要来单独设计成一个独立的类时,可以考虑使用内部类。从现实层面上类似汽车里发动机。
2. 成员内部类
2.1 创建对象
格式 外部类名.内部类名 对象名 = new 外部类( ).new 内部类
Outer.Inner in = new Outer().Inner();
2.2 访问成员
public class Outer {
private int age = 99;
private static String a;
public class Inner{
private String name;
public static int age = 1000; // 类变量不能和成员变量重复
//private int age = 88;
public void test(){
int age = 20;
System.out.println(age); // 一般来说 age搜索从里到外,
// 只有当age被内部定义了才需要用this或者外部类名.this.变量名去访问变量
System.out.println(this.age); // this = 当前类类名
// 当this.age时候访问类变量或者成员变量 类变量不能和成员变量重复
System.out.println(Outer.this.age); // Outer.this.可以拿到外部类对象 输入 99;
}
3. 静态内部类
差不多其实就是成员内部类的静态版,跟实例方法类方法的变化类似
3.1 创建对象
格式 外部类名.内部类名 对象名 = new 外部类.内部类
Outer.Inner in = new Outer.Inner();
3.2 访问对象
能访问静态成员,不能访问实例成员
4. 局部内部类
局部内部类是定义在在方法中、代码块中、构造器等执行体中,一般很少用。
5. 匿名内部类
5.1 含义
一种特殊的匿名的局部内部类
5.2 特点
其本身是个子类,会立刻创建出一个子类对象
5.3 作用
适用于接口(函数式接口)或重写抽象类不需要重复使用的方法,可以快速创建子类对象,减少不必要的步骤,增强代码内聚性
//1. 传统用类实现再用类操作
// class Dog implements Swimming {
//
// @Override
// public void swim() {
// System.out.println("开始");
// System.out.println("狗在游泳");
// }
// }
// Dog dog = new Dog();
// dog.swim();
// 2. 创建对象记住(不算完全的匿名类)
// Swimming swimming = new Swimming() {
// @Override
// public void swim() {
// System.out.println("开始");
// System.out.println("狗在游泳");
// }
// };
// swimming.swim();
// 3. 直接方法作参数送入
swim(new Swimming() {
@Override
public void swim() {
System.out.println("狗在游泳");
}
});
// 4. 匿名表达式
swim(() -> System.out.println("狗在游泳"));
}
public static void swim(Swimming s) {
System.out.println("开始");
s.swim();
}
二、其他类
1. 枚举类
1.1 含义
枚举类是一个用来存储常量以及相关处理方法的特殊类,本质上是用来限制输入数据的,目的是增强代码可读性
public class Constant { // 一般情况用的常量
public static final int BOY = 0;
public static final int GIRL = 1;
}
public enum Constant2 { // 最好用枚举类,直接限制输入类型,且把抽象数据具体化增加可读性
// 信息标准和分类
BOY , GIRL;
}
public static void main(String[] args) {
check(Constant.BOY); // 但其实它也可以填0/1,数据也没有真正限制住,可能会被修改
check(Constant2.BOY);
}
public static void check(Constant2 sex){
switch (sex){
case BOY:
System.out.println("");
break;
case GIRL:
}
反编译后的代码如图,所有的类都是设定为最终类而且有一些返回值的方法
还有抽象枚举,但实际运用不多
2. 泛型
2.1 含义
定义类、接口、方法时,同时声明了一个或者多个类型变量(如:< E >,< T >) ,称为泛型类、泛型接口,泛型方法、它们统称为泛型,E / T代表任何类型。
2.2 作用:
泛型作用是可以应用于不同数据类型的通用代码(不是一个用多,而是一个多用,不同于Object数组),其主要目的是提高代码的重用性、类型安全性和可读性,Java 泛型在编译时执行类型检查,可以捕获许多在运行时可能导致错误的问题。
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("play");
list.add(new Cat());
//
// for (int i = 0; i < list.size(); i++) {
// String e = (String) list.get(i);
// System.out.println(e);
// }
System.out.println("----------");
ArrayList<String> list1 = new ArrayList<>(); // 在尖括号内填入类型,限制只能传入String类型
list1.add("Java1");
list1.add("Java2");
list1.add("Java3");
}
public boolean add(E e) { // 这解释了为什么ArrayList同时放所有类型原因,本身就只有一个类型变量,但是如果没限定的话可以每次放不同的 不是一个多用,而是一个用多
modCount++;
add(e, elementData, size);
return true;
}
2.3 种类
2.3.1 泛型类
(1)书写格式:
public class 类名 <类型变量>{
}
(2)实例
public class Animal {
}
public class Cat extends Animal {
}
public class Dog extends Animal{
}
public class Myarraylist<E> {
private Object[] arr = new Object[10];
private int size;
// public boolean add(E e){
// return true;
// }
public boolean add(E e){
arr[size++] = e;
return true;
}
public E get(int index){
return (E) arr[index];
}
}
public class MyClass2 <E, T>{ // 必须填入两个类型
public void put(E e, T t){
}
}
public class MyClass3 <E extends Animal> {
}
public class Test {
public static void main(String[] args) {
Myarraylist<String> list = new Myarraylist();
//Myarraylist<String, Integer> list = new Myarraylist(); 如果Myarraylist填够足够多,确实可以送所有基本类型的
list.add("Java1");
list.add("Java2");
Object ele = list.get(1);
System.out.println(ele);
MyClass2<Cat, String> c2 = new MyClass2<>();
MyClass3<Animal> c3 = new MyClass3<>();
// MyClass3<String> c3 = new MyClass3<>(); 规定了E要继承Animal
MyClass3<Dog> c4 = new MyClass3<>();
}
2.3.2 泛型接口
(1)书写格式
public interface 接口名 <类型变量, 类型变量..>{
}
(2)实例
public interface Data<T> {
void add(T t);
ArrayList<T> getByName(String name);
}
public class Student {
}
public class Teacher {
}
public class StudentData implements Data<Student>{
@Override
public void add(Student student) {
}
@Override
public ArrayList<Student> getByName(String name) {
return null;
}
}
public class TeacherData implements Data<Teacher>{
@Override
public void add(Teacher teacher) {
}
@Override
public ArrayList<Teacher> getByName(String name) {
return null;
}
}
public class Test {
}
2.3.3 泛型方法
(1)区分
public E get(int index){ // × 这种不算是泛型方法 它是类里面使用类给的参数当类型变量而不是自己声明类型变量
return (E) arr[index];
}
public static <T> T test(T t) { // 这是自己控制类型变量,而不是用类给自己去作类型变量
return t;
}
(2)实例
public class Car {
}
public class BENZ extends Car {
}
public class BMW extends Car {
}
public class Dog {
}
public class Test {
public static void main(String[] args) {
String rs = test("java");
System.out.println(rs);
Dog d = test(new Dog());
System.out.println(d);
ArrayList<Car> cars = new ArrayList<>();
cars.add(new BMW());
go(cars);
ArrayList<BMW> bmws = new ArrayList<>();
BMW bmws1 = new BMW();
bmws.add(new BMW());
bmws.add(new BMW());
go(bmws);
ArrayList<BENZ> benzs = new ArrayList<>();
ArrayList<Dog> dog = new ArrayList<>();
dog.add(new Dog());
benzs.add(new BENZ());
benzs.add(new BENZ());
go(benzs);
go(dog);
}
public static <T> T test(T t) {
return t;
}
public static <T> void go(ArrayList<T> T){
System.out.println(T);
}
// ? 通配符以及extends 和super关键字
// public static <T extends Car> void go(ArrayList<T> cars){
//
//
// }
// public static void go(ArrayList<? extends Car> cars) { // 能接收的是Car或者其子类 super则是Car或者父类
//
// }
// public static void go(ArrayList<? super Car> cars) { // 能接收的是Car或者其子类 super则是Car或者父类
//
// }
}
2.4 泛型擦除
所有泛型标记都已经擦除,泛型是工作在编译阶段的,主要是约束使用者,代码实际运行会进行擦除。
// 反编译代码
public class Test
{
public Test()
{
}
public static void main(String args[])
{
String rs = (String)test("java");
System.out.println(rs);
Dog d = (Dog)test(new Dog());
System.out.println(d);
ArrayList cars = new ArrayList();
cars.add(new BMW());
go(cars);
ArrayList bmws = new ArrayList();
BMW bmws1 = new BMW();
bmws.add(new BMW());
bmws.add(new BMW());
go(bmws);
ArrayList benzs = new ArrayList();
ArrayList dog = new ArrayList();
dog.add(new Dog());
benzs.add(new BENZ());
benzs.add(new BENZ());
go(benzs);
go(dog);
}
public static Object test(Object t)
{
return t;
}
public static void go(ArrayList T)
{
System.out.println(T);
}
}
三、总结
总的来说,Java这些类可以分为这两种,第一种是像成员内部类、静态内部类、局部内部类、匿名内部类这种辅助类,它们的出现是更好方便其他类功能拓展或方便使用的,第二种是枚举类和泛型类这种功能类,它们是为了对数据操作的约束,枚举类是为了防止输入到错误的数据类型或数值,而泛型类只能让你只能输入对应的类型。