首页 > 编程语言 >javaSE基础-内部类

javaSE基础-内部类

时间:2022-10-21 22:12:10浏览次数:37  
标签:内部 基础 System public Person println javaSE class

内部类

定义:一个类A定义在类B中,则类A为内部类,类B为外部类

分类:

成员内部类

  • 静态成员内部类
  • 非静态成员内部类

局部内部类

  • 方法内
  • 代码块内
  • 构造器内

示例一:

//InnerClassTest.java

/**
 * 内部类<br>
 * 1、定义:一个类A定义在类B中,则类A为内部类,类B为外部类<br>
 * 2、分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)<br>
 * 3、成员内部类:<br>
 * <span>3.1、作为外部类的成员:<br>
 * <span><span>a、调用外部结构<br>
 * <span><span>b、可以被static修饰<br>
 * <span><span>c、可以被被4种不同权限修饰<br>
 * 
 * <span>3.2、作为一个类:<br>
 * <span><span>a、类内部可以定义属性、方法、构造器等<br>
 * <span><span>b、可以被final修饰,表示此类不能被继承<br>
 * <span><span>c、可以被abstract修饰<br>
 *
 * @author jb
 * @date 2022/08/07
 */
public class InnerClassTest {
    public static void main(String[] args) {
        // 创建成员内部类Dog实例(静态的)
        Person.Dog dog = new Person.Dog();
        dog.show();
        // 创建成员内部类Bird实例(非静态的)
        Person p = new Person();
        Person.Bird bird = p.new Bird();
        bird.sing();
        System.out.println("*************");
        bird.dispaly("args");

    }
}

class Person {
    private String name = "张三";
    private Integer age = 18;

    public void run() {
        System.out.println("Person is running...");
    }

    // 静态成员内部类
    static class Dog {
        private String name;
        private Integer age;

        public void show() {
            System.out.println("The Dog is Kala.");
        }

    }

    // 非静态成员内部类
    final class Bird {
        private String name = "麻雀";

        public Bird() {
            System.out.println("this is a bird");
        }

        public void sing() {
            System.out.println("bird is singing。。。");
            Person.this.run(); // 调用外部类方法的完整写法
            System.out.println(age);// 外部类的成员变量
        }

        public void dispaly(String name) {
            System.out.println(name);// 形参的变量 -> args
            System.out.println(this.name);// 局部变量 -> 麻雀
            System.out.println(Person.this.name);// 外部类的成员变量 -> 张三
        }
    }

    public void method() {
        // 局部内部类 -> 方法内
        class AA {

        }
    }

    public Person() {
        // 局部内部类 -> 构造器内
        class BB {

        }
    }

    {
        // 局部内部类 -> 代码块内
        class CC {

        }
    }
}

使用问题

1、如何实例化成员内部类的对象:

// 创建成员内部类Dog实例(静态的)
Person.Dog dog = new Person.Dog();
dog.show();
// 创建成员内部类Bird实例(非静态的)
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();

静态内部类实例化对象格式:

外部类类名.内部类类名 xxx = new 外部类类名.内部类类名()

非静态内部类实例化对象格式:

外部类类名.内部类类名 xxx = 外部类对象名.new 内部类类名()

2、如何在成员内部类中区别调用外部类的结构:

在内部类的方法内,针对有相同名的变量:
如:name在外部类成员变量、内部类局部变量、方法的形参变量都同时存在的调用方式:

class Person {
    private String name = "张三";
    private Integer age = 18;
    
    ...
        
	// 非静态成员内部类
    final class Bird {
        private String name = "麻雀";

        public Bird() {
            System.out.println("this is a bird");
        }

        public void sing() {
            System.out.println("bird is singing。。。");
            Person.this.run(); // 调用外部类方法的完整写法
            System.out.println(age);// 外部类的成员变量
        }

        public void dispaly(String name) {
            System.out.println(name);// 形参的变量 -> args
            System.out.println(this.name);// 局部变量 -> 麻雀
            System.out.println(Person.this.name);// 外部类的成员变量 -> 张三
        }
    }
}

3、开发中局部内部类的一般使用方式:

示例二:

//InnerClassTest2.java

/**
 * @author jb
 * @date 2022/08/07
 */
public class InnerClassTest2 {

    public Comparable getComparable() {

        // 方式一:标准的局部内部类定义
        class MyComparable implements Comparable {

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();

        // 方式二:直接返回Comparable接口的一个匿名实现类
        return new Comparable() {

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
}

成员内部类被类继承的使用方式:

示例三:

class WithInner {
    class Inner{
         
    }
}
class InheritInner extends WithInner.Inner {
      
    // InheritInner() 是不能通过编译的,一定要加上形参
    InheritInner(WithInner wi) {
        wi.super(); //必须有这句调用
    }
  
    public static void main(String[] args) {
        WithInner wi = new WithInner();
        InheritInner obj = new InheritInner(wi);
    }
} 
  • 成员内部类的引用方式必须为 Outter.Inner,如:WithInner.Inner
  • 构造器形参必须指向外部类对象的引用,并通过这个引用调用super(),如:wi.super();

局部内部类的方法中使用局部变量的注意

在局部内部类的方法调用局部内部类的局部变量,要求此变量必须声明为final

  • Jdk7及之前的版本:要求此局部变量是显式的声明为final
  • Jdk8及之后的版本:可以省略final声明

示例四:局部内部类

public class InnerClassTest{
    public void method(){
        //局部变量-- jdk7
        //final int num = 10; 
        //局部变量-- jdk8
        int num = 10;
        
        class AA{
            
            public void show(){
                //num = 20; 此处无法覆盖num值,原因是num声明为final
                System.out.println(num);
            }
		}
    }
}

示例五:自定义异常类

public class MyException extends RuntimeException{
    static final long serialVersionUID = -7034897193246938L;
    public MyException(){
        
    }
    public MyException(String msg){
        super(msg);
    }
}

总结:

成员内部类和局部内部类,在编译之后,生成字节码文件

格式:成员内部类:外部类$内部类名.class

局部内部类:外部类$数字 内部类名.class

标签:内部,基础,System,public,Person,println,javaSE,class
From: https://www.cnblogs.com/bione/p/16789737.html

相关文章

  • 计算机基础知识
    计算机基础知识目录计算机存储单位进制转换进制之间的转换计算机的储存单位编码计算机存储单位进制转换二级制进制是计算机中广泛采用的一种数制,二进制使用0和1......
  • Docker 基础详解
     一、docker安装(ubuntu22.04)配置阿里源sudosed-i-r's#http://(archive|security).ubuntu.com#https://mirrors.aliyun.com#g'/etc/apt/sources.list&&sudoapt-......
  • Docker基础:Docker是什么,为什么这么火
    一、Docker是什么?Docker是一个开源的应用容器引擎,它基于go语言开发,并遵从Apache2.0开源协议。使用Docker可以让开发者封装他们的应用以及依赖包到一个可移植的容器中,然后发......
  • 致敬Excel基础函数(20):Datestring函数和Datevalue函数
    1概念Datestring函数的定义:将对应的日期转换为“年月日”的形式。Datevalue函数的定义:返回以字符串所表示的日期值所对应的序列号。2语法Datestring函数语法:​=DATESTRING(......
  • Docker基础:Docker运行原理笔记
    ​今天给大家继续分享Docker相关的知识,今天主要介绍Docker运行原理以及生命周期,希望对大家能有所帮助!1、Docker底层运行原理Docker基于客户端(容器)-服务器(Docker引擎)结构的系......
  • Docker基础:Docker 常用命令梳理
    ​今天给大家梳理一下Docker常用的命令,希望对大家有所帮助1、Docker环境信息命令dockerversion说明:用于显示docker的版本信息,包括docker客户端和docker服务端基本信......
  • MyBatis基础使用五
    MyBatis基础使用五MyBatis缓存(了解即可,现在主流的缓存通过redis)MyBatis的一级缓存一级缓存是SqlSession级别的,通过同一个SqlSession查阅的数据会被缓存,下次查阅相同的数......
  • kubernete学习1-基础环境部署
    一、环境信息:操作系统:ubuntu18.04serveramd64docker:docker19.03.cekubernetes:v1.19IP地址主机名  角色172.29.9.1k8s-masterk8s-master.ilinux.iok8s......
  • 多线程基础知识
    【单核处理器和多核处理器的多线程】单核处理器:为每个线程分配时间片。来模拟并发多核处理器:一核一线程,真正实现并发 【标志】线程一致性,IsAlive就为true,否则为fals......
  • 网络工程知识(二)VLAN的基础和配置:802.1q帧;Access、Trunk、Hybrid接口工作模式过程与配
    介绍-VLANVLAN(VirtualLocalAreaNetwork)即虚拟局域网,工作在数据链路层。交换机将通过:接口、MAC、基于子网、协议划分(IPv4和IPv6)、基于策略的方式划分VLAN的方式,将接......