类的修饰符。只有两个级别的访问控制:
public:...
@Data class StringBook { private String name; private String age; }
成员的修饰符。有四个级别:
public:...
private:
仅限当前类使用。protected:当前包使用+另一个包的
子类。
定义: 嵌套类分为两类:非静态和静态。非静态嵌套类称为内部类。声明static
的嵌套类称为静态嵌套类。
特殊: 嵌套类是其封闭类(外部类)的成员。
内部类可以访问封闭类(外部类)的其他成员,即使它们被声明为私有。
静态嵌套类无权访问封闭类(外部类)的其他成员,但是可以访问static修饰符的成员。一个嵌套类可以声明private
,public
,protected
,或包专用。(回想一下,外部类只能声明public
或(无修饰符)。)
public class SubString{ //内部类 class InnerClass{ } //嵌套类 static class InnerStatic{ } }
使用嵌套类的令人信服的原因包括:
这是一种对只在一个地方使用的类进行逻辑分组的方法:如果一个类只对另一个类有用,那么将它嵌入到该类中并将两者保持在一起是合乎逻辑的。嵌套这样的“辅助类”使它们的包更加精简。
它增加了封装性:考虑两个顶级类 A 和 B,其中 B 需要访问 A 的成员,否则A的成员将被声明private
。
通过将 B 类隐藏在 A 类中,A 的成员可以被声明为私有,而 B 可以访问它们。此外,B 本身可以对外界隐藏,此处指的应该是B对外界隐藏A的成员吧?。B也可以用public修饰。
与实例的方法和变量一样,内部类与其封闭类的实例相关联,并且可以直接访问该对象的方法和字段。此外,由于内部类与实例相关联,因此它本身不能定义任何静态成员。
作为内部类实例的对象存在于外部类的实例中:创建的时候:new外部类.new内部类
有两种特殊的内部类: 本地类和 匿名类。
本地类(局部类):出现在块中,什么是块。{ }就是块,比如 if(){ }, 比如 public void method(){ }
public class OuterClass {
private String outName;
public void method() { final int num = 10; class FirstClass { //比如此处实现个接口了,继承了,还是有点装p的 public FirstClass() { }//局部类构造方法 public String getName(String str) { return str+ num; } //局部类方法
public String getOutName() {reurn OuterClass.this.outName }//局部类对外部类的引用 } FirstClass firstClass = new FirstClass();//当前方法内创建局部类对象 String s = firstClass.getName("李白");//调用局部类方法 System.out.println("s = " + s); } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.method(); } }
局部类特点:
匿名内部类:实现接口回调。
/** * 匿名内部类实现回调 * * @author rxjh_sword */ public class VideoProcess { private Video video;//处理的内容DTO public VideoProcess(Video video) { this.video = video; } public void printVideo() { System.out.println(video); } //对外暴露的外部处理方法 public void process(ResultCallback resultCallback) { VideoProcessTask videoProcessTask = new VideoProcessTask(); //调用自己封装的内部处理方法. videoProcessTask.start(resultCallback); } private VideoResult videoResult; //用来处理客户端请求的任务类 private class VideoProcessTask { //启动任务 public void start(ResultCallback resultCallback) { System.out.println("任务开始..."); printVideo();//随便做点什么,比如调用外部类方法打印一句话 videoResult = new VideoResult(10000, "success", "baidu.com");//得到处理结果 System.out.println(videoResult);//打印一下结果,意思意思. resultCallback.callback(videoResult);//通过客户端传递过来的接口调用即可,不关心客户指定的具体处理逻辑 } //终止任务 public void end() { System.out.println("任务结束..."); } } //作为参数传递的接口,传递时用匿名内部类,callback为回调逻辑 @FunctionalInterface public interface ResultCallback { void callback(VideoResult videoResult); } //main方法测试:理解为 客户端的调用 public static void main(String[] args) { Video video = new Video("java回调", "回调函数"); VideoProcess videoProcess = new VideoProcess(video); videoProcess.process(new ResultCallback() { @Override public void callback(VideoResult videoResult) { //客户端处理结果方式定义,实现回调. } }); } //客户端传递参数的实体DTO @Data @AllArgsConstructor private static class Video { private String name; private String msg; } //处理结果,不理解的话可以剪切出去 @Data public class VideoResult { private int code; private String msg; private String address; public VideoResult(int code, String msg, String address) { this.code = code; this.msg = msg; this.address = address; } } }
步骤总结:
静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。
实际上,静态嵌套类在行为上是一个顶层类,为了方便打包,它嵌套在另一个顶层类中。
一般来说,内部类不需要访问包裹类的非静态成员的时候。或者只是做一个工具给外部调用,而这些工具需要按照功能区分为的时候使用静态内部类
强烈建议不要对内部类进行序列化
原文:https://www.cnblogs.com/rxjh-sword/p/15085103.html