Java的内部类、枚举、泛型

一、内部类

1.1 成员内部类

成员内部类是定义在类内部的类,不能用static修饰,它其实和普通的成员变量一样,一样具有类的五大成分:成员变量、成员方法、构造器、代码块、内部类,就是说可以在类中用内部类无限套娃,不过不推荐。

创建对象的格式:外部类.内部类 变量名 = new 外部类().new 内部类();

public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().new Inner();
        inner.print();
    }
}

class Outer{
    class Inner{
        public void print(){
            System.out.println("我是内部类的方法....");
        }
    }
}

那么如果我们在内部类中该怎么调用外部类的成员呢?

1、我们可以把内部类看成外部类中的一个方法,当内部类和外部类中没有重名的变量或者方法的时候,直接调用即可
2、当内外部类有重名的变量和方法的时候,我们就要加以区分了。在内部类中,有两种形式调用外部类的属性,一种是new 外部类().外部类属性的形式来调用,另一种是通过外部类.this.外部类属性来调用,两种方式任用其一即可

class Outer{
    int age = 10;
    class Inner{
        int age = 20;
        public void print(){
           int age = 30;
            System.out.println(age);//内部类方法的中局部变量  30
            System.out.println(this.age);//内部类中的成员变量  20
            System.out.println(Outer.this.age);//外部类中的成员变量 10
            System.out.println(new Outer().age);// 10
        }
    }
}

1.2 静态内部类

静态内部类就是在类中定义用static修饰的类,相当于类中的一个静态方法,它也可以定义类的五大成分,
创建对象的格式:外部类.内部类 对象名 = new 外部类.内部类();

public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer.Inner();
        inner.print();
    }
}

class Outer{
    static class Inner{
        public void print(){
            System.out.println("我是静态内部类的方法");
        }
    }
}

那么静态内部类该怎么调用外部类的属性呢?

静态内部类类似于静态方法,内部类中只能调用外部类中的静态成员,不能直接调用外部类的实例成员;遇到重名成员时,在内部类中只能通过new 外部类().外部类静态成员的方式调用

public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer.Inner();
        inner.print();
    }
}

class Outer{
    static int age = 10;
    static class Inner{
        int age = 20;
        public void print(){
            int age = 30;
            System.out.println(age);//30
            System.out.println(this.age);//20
            System.out.println(new Outer().age);//10
        }
    }
}

1.3 局部内部类

局部内部类属于鸡肋写法,开发中一般不适用纯正的局部内部类;局部内部类定义在方法中、代码块中、构造器等执行体中(基本不会用)

注意:局部内部类类似于局部变量,其类中的成员只能在定义局部内部类的代码块中使用,无法到外面的代码块中使用

class Outer{
    public void test(){
        class Inner{
            public void print(){
                System.out.println("我是局部内部类的方法");
            }
        }
        new Inner().print();
    }
}

1.4 匿名内部类

匿名内部类是一种特殊的局部内部类,非常重要,虽然现在的JDK使用了Lambda表达式简化了匿名内部类的书写,但本质上还是属于匿名内部类,在开发和源码中都非常的常见。匿名内部类书写时不用定义类的名字,一般是用于抽象类和接口的方法重写,其本质是创建了一个抽象类或接口的子类,常用于方法中充当实参,编译时也会生成字节码文件(.class)

创建格式:new 抽象类/接口(){重写的方法}

public class Test {
    public static void main(String[] args) {
        USB keyBoard = new USB() {
            @Override
            public void connect() {
                System.out.println("键盘已连接....");
            }
        };
    }
}

interface USB{
    void connect();
}

使用场景:通常作为参数传递给方法

public class Test {
    public static void main(String[] args) {
        new Use().use(new USB() {
            @Override
            public void connect() {
                System.out.println("键盘已连接....");
            }
        });
    }
}

interface USB{
    void connect();
}

class Use{
    public void use(USB usb){
        usb.connect();
    }
}

二、枚举

枚举是一种特殊的类,定义时不用class修饰,而是用enum修饰。
特点:

1、第一行只能定义变量(对象),变量用逗号隔开,用分号结尾,这些变量都默认用static final修饰,是一些常量
2、构造器是默认私有化的,不能在构造器前面加除private的其它权限修饰符,这就意味着此类不能在其他类中创建对象
3、类中可以定义类的五大成分,不过我们一般不会定义
4、枚举类不能被继承

enum Season {
    SPRING, SUMMER, AUTUMN, WINTER;
}

枚举类的使用场景:结合Switch()使用

public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入四季中的其中一个季节");
        String s = sc.next();
        Season season = Season.valueOf(s);
        switch (season){
            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;
        }
    }
}

enum Season {
    SPRING, SUMMER, AUTUMN, WINTER;
}

下面是枚举类的反编译,进一步的解释了上述的四个特点

在这里插入图片描述

三、泛型

(我们的目标是了解泛型,因为泛型在开发中一般不需要我们写,泛型一般出现在源码中,我们能做到看得懂泛型即可,其它方面不深入探究)泛型的本质是把数据类型作为参数传递给数据变量。
泛型类:public class 类名<T,W>{ T、W指的是类型变量 }
泛型接口:interface 接口名<E>
泛型方法:修饰符 <E> 返回值类型 方法名(E e)

//泛型接口
interface test<T>{
    //泛型方法
    public <T> void getName(T t);
}

//泛型类
class Person<T>{
    
}

什么是泛型的擦除?

在编译阶段使用的泛型等到编译完成后的class文件里是会消失的,它底层还是基于object进行操作,只是会在编译阶段限制你的类型,最多返回数据的时候帮你强制转换

泛型上下限
1、?通配符形参能接收任意类型的数据 数据类型<?> 形参
2、extends为泛型上限,形参可以接收此类的对象或者其子类的对象 数据类型<? extends 类> 形参
3、super为泛型下限,形参可以接收此类的对象或者其父类的对象 数据类型<? super 类> 形参

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值