• Java内部类


    内部类

    通常情况

    一个 Java 文件中只有一个主类,也就意味着下面这样是错误的:

    // 编译器会报错,一个 java 文件中只能有一个被 public 修饰的类,并且该类的类名与 java 文件名一致(Outer.java)
    public class Outer{
    }
    public class Other{
    }
    

    将第二个类的 public 权限修饰符删除,就可以在 java 文件中定义多个类
    并且每个类都可以被访问到

    内部类的结构

    内部类,顾名思义,就是 java 一个类中定义另一个类,如下所示:

    public class Outer{
    	class Inter{
    	}
    }
    

    创建内部类

    内部类在实例化的时候偷偷保留了指向外部类的引用。因此在创建内部类对象的同时,必须先创建外部类对象(静态内部类除外)

    • 通过外部类中的方法得到内部类
    public class Outer{
    	public Inter inter() {
    		return new Inter();
    	}
    	class Inter{
    	}
    	public static void main(String[] args) {
    		Outer outer = new Outer();
    		Inter inter = outer.inter();
    	}
    }
    
    • 内部类对象通过 外部类对象的 .new 方法创建
    public class Outer{
    	class Inter{
    	}
    	public static void main(String[] args) {
    		// 通俗易懂的创建方式
    		Outer outer = new Outer();
    		Outer.Inter inter0 = outer.new Inter();
    		// 一次创建完毕
    		Inter inter1 = new Outer().new Inter();
    		Outer.Inter inter2 = new Outer().new Inter();
    	}
    }
    

    内部类对象通过 外部类.this 方法得到父类

    public class Outer{
    	class Inter{
    		Outer getOuter() {
    			return Outer.this;
    		}
    	}
    	public static void main(String[] args) {
    		Outer outer1 = new Outer();
    		Outer.Inter inter = outer1.new Inter();
    		Outer outer2 = inter.getOuter();
    		// 两个对象是同一个
    		System.out.println(outer1 == outer2);	// true
    	}
    }
    

    内部类的特点

    内部类默认可以访问外部类中所有的成员

    public class Outer{
    	Object[] items = new Object[2];
    	private int index = 0;
    	class Inter{
    		public void add(String s) {
    			// 在Inter类中,可以访问到外部的private成员变量
    			if (index<items.length) items[index++]=s;; 
    		}
    	}
    	public static void main(String[] args) {
    		Outer outer = new Outer();
    		Outer.Inter inter = outer.new Inter();
    		inter.add("元素一");
    		inter.add("元素二");
    		System.out.println(outer.items[1]);	// print:元素二
    	}
    }
    

    内部类与向上转型

    将内部类声明为private或者protected。同时,在创建内部类实例对象的时候,通过内部类的父接口来声明对象变量,这样一来,客户端程序员就只能访问接口中定义的公共方法。因而实现了对接口实现过程代码的隐藏。

    public class Outer{
    	public Inter inter() {
    		return new Inter();
    	}
    	interface People{
    		void speak();
    	}
    	class Inter implements People{
    		public void speak() {
    			System.out.println("这是接口中的一个方法");
    		}
    		public void sleep(){
    		}
    	}
    	public static void main(String[] args) {
    		// 程序员无法访问到内部类实现的接口以外的方法
    		Outer outer = new Outer();
    		People inter = outer.inter();
    		inter.speak();
    		// inter.sleep()	访问不到
    	}
    }
    

    在方法中和作用域内的内部类

    内部类可以在方法里面或者在任意的作用域中定义内部类。

    匿名内部类

    看起来就像创建类对象的时候,同时在这里插入该类的定义。

    用的比较多的: new 接口(){ 接口的实现 },这样就不用再定义具体的一个实现类了

    public class Outer{
        // 接口
    	interface Inter{
    		void speak();
    	}
    	public Inter inter() {
            // 返回的时候,将接口实现
    		return new Inter(){
    			public void speak() {
    				System.out.println("hello");
    			}
    		};
    	}
    }
    

    嵌套类(静态内部类)

    使用 static 修饰的内部类就是嵌套类了。内部类不依赖于外部类对象,没有 .this方法,普通内部类中不能有static方法或成员和嵌套类。而嵌套类里边可以有static方法和成员,也可以继续嵌套一个类

    public class Outer{
    	static class Inter{
    		static String des = "静态成员变量";
    		static void speak() {
    			System.out.println("静态方法");
    		}
    		static class InterInter{
    			static {
    				String des = "嵌套类中的嵌套类";
    			}
    		}
    	}
    	public static void main(String[] args) {
    		Inter.speak();
    	}
    }
    
    • 接口内部的嵌套类
      接口中的类都会被声明为public,static。可以通过在接口内部写一个嵌套类,并且在这个嵌套类中创建公共代码

    每个类中测试的时候都需要主方法,但是你可以在一个嵌套类中定义一个main方法,这样外部类在解析这个嵌套类的时候会执行其中的静态main方法,从而外部类不用特意写个主方法了

    • 无论嵌套多少层都没事,嵌套类总能访问外部类的成员(无论其访问修饰符是什么),最里层的嵌套类可以访问外层的所有成员

    为什么使用内部类

    每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否及经济成了某个(接口的)实现,对于内部类都没有影响

    • 可以解决多重继承问题
    • (闭包与回调)通过内部类提供闭包的功能是优良的解决方案,他比指针更灵活、更安全。

    闭包(closure)是一个可调用的对象,他记录了一些信息,这些信息来自创建它的作用域。

    • 内部类和控制框架
      每个内部类都可以独立地实现一个action
      内部类可以很容易访问外围类的任意成员
  • 相关阅读:
    ESP-12F WIFI模块开发(NonOS, RTOS, NodeMCU固件编译)(原创)
    如何将笔记本上的SD卡接入Ubuntu虚拟机中(原)
    第2步
    第1步
    详解linux下的串口通讯开发 (转载)
    C中如何调用C++函数 (转载)
    ubuntu下安装与使用json-c(原创)
    static, const 和 static const 变量的初始化问题(定义/声明)
    图片三级缓存的原理
    Windows平台下Git服务器搭建
  • 原文地址:https://www.cnblogs.com/llf7/p/12996847.html
Copyright © 2020-2023  润新知