内部类:
内部类与普通类其实是相似的,只是位置不同导致了有一些使用上的差别(或者说是注意事项)。
package Demo_1_26_内部类; public class Outter { // 外部类 private String msg = "www"; //私有成员属性 public void fun(){// 普通方法 Inner inner = new Inner(); inner.print(); } class Inner{ // 在Out类中定义内部类Inner public void print(){ System.out.println(Outter.this.msg); // Out类中的属性 } } }
package Demo_1_26_内部类; public class Main { public static void main(String[] args) { Outter outter = new Outter(); // 实例化外部类对象 outter.fun(); // 调用外部类方法 } }
所以内部类的结构不合理却还存在的好处是什么?
public class Outter { // 外部类 private String msg = "www"; //私有成员属性
}
如果msg需要被其它类使用,那么就需要各种操作来设置引用的调用。
所以内部类的存在就是可以轻松访问外部类的私有属性或私有方法。
同理外部类也可以轻松地访问内部类的私有属性或私有方法。
package Demo_1_26_内部类; public class Outer { // 外部类 private String msg = "www"; //私有成员属性 public void fun(){// 普通方法 Inner inner = new Inner(); // 创建内部类对象 System.out.println(inner.inFo); // 访问内部类的私有属性 inner.print(); // 调用内部类方法 } class Inner{ // 在Out类中定义内部类Inner private String inFo = "天气真好!"; public void print(){ // 内部类方法 System.out.println(Outer.this.msg); // Out类中的属性 } } }
使用了内部类之后,内部类与外部类之间的私有操作的访问就不再需要通过setteer、getter以及其它的间接方式完成了,可以直接进行处理操作。
需要注意的是:内部类本身也是一个类,虽然大部分时候内部类是被外部类包裹的,但是外部依然可以产生内部类的实例化对象,格式如下:
package Demo_1_26_内部类; public class Main { public static void main(String[] args) { Outer.Inner in = new Outer().new Inner(); // 如果内部类内部还有类就继续 .new 内部类() } }
在内部类编译完成之后会自动形成一个" Outer$Inner.class"类文件,其中" $ " 符号在程序中的符号就是 " . "
如果不允许外部使用内部类,可以将内部类进行私有化,在类前加上private权限控制:
package Demo_1_26_内部类; public class Outer { // 外部类 private String msg = "www"; //私有成员属性 public void fun(){// 普通方法 Inner inner = new Inner(); // 创建内部类对象 System.out.println(inner.inFo); // 访问内部类的私有属性 inner.print(); // 调用内部类方法 } private class Inner{ // 在Out类中定义内部类Inner,权限控制,不允许外部使用 private String inFo = "天气真好!"; public void print(){ // 内部类方法 System.out.println(Outer.this.msg); // Out类中的属性 } } }
static定义的内部类:
static定义的内部类就属于“外部类”了,并且static定义的不管是类还是方法都只能够访问static成员,所以static定义的内部类只能够访问外部类的static属性或方法。
package Demo_1_27_内部类1; public class Outer { private static final String MSG = "www"; static class Inner{ //此时Inner类是一个独立类,如果想要产生Inner类的实例化对象,只需要 new外部类.内部类() 就行了 // 最常用的是使用static定义内部接口 public void sendMessage(){ System.out.println(Outer.MSG); } } }
package Demo_1_27_内部类1; public class Main { public static void main(String[] args) { // Outer.Inner in = new Outer.Inner(); // 与new 外部类.new 内部类();不同,此时的内部类是static定义的,相当于 类名. 的形式直接创建内部类对象 // in.sendMessage(); } }
然后是static修饰内部接口为静态内部接口:
package Demo_1_27_内部类1; public interface IMessageWarp { //消息包装 static interface IMessage{ //消息内容 public String getContent(); //获取消息 } static interface IChannel{ // 消息发送的通道 public boolean connect(); // 连接是否成功 } public static void send(IMessage msg, IChannel ch){ //static静态方法,可以直接使用 接口名. 的形式调用 if (ch.connect()){ System.out.println(msg.getContent()); }else { System.out.println("消息通道无法建立!发送失败"); } } //消息发送 }
package Demo_1_27_内部类1; public class DefaultMessage implements IMessageWarp.IMessage { // 外部类实现消息内容接口 @Override public String getContent() { // 重写消息获取方法 return "看到这个消息表示发送成功!"; } class NetChannel implements IMessageWarp.IChannel{ // 内部类实现通道连接接口 @Override public boolean connect() { // 重写通道连接方法 return false; } } }
package Demo_1_27_内部类1; public class Main { public static void main(String[] args) { IMessageWarp.send(new DefaultMessage(), new DefaultMessage().new NetChannel()); } }
方法中的内部类:
package Demo_1_27_方法中的内部类; public class Outer { private String msg = "今天的时间是:"; public void fun(long time){ class Inner { // 内部类 public void print(){ System.out.println(Outer.this.msg); System.out.println(time); } } new Inner().print(); } }
我们可以发现fun()方法内提供了Inner内部类,并且可以发现内部类能够直接访问外部类的私有属性也可以直接访问方法中的参数,但是对于方法中的参数直接访问是从JDK1.8开始的,在JDK1.8之前,如果方法中定义的内部类想要访问方法中的参数,则参数前必须加上final,局部变量也必须加上final。
public void fun(final long time){ final String s = "sss"; }
package Demo_1_27_方法中的内部类; public class Main { public static void main(String[] args) { new Outer().fun(20220127); } }
匿名内部类:
当一个类只会使用一次的时候,如果再重新创建就会显得十分多余,那么就可以使用匿名内部类进行访问;
package Demo_1_27_匿名内部类; public interface IMessage { public void send(String str); }
package Demo_1_27_匿名内部类; public class Main { public static void main(String[] args) { IMessage msg = new IMessage(){ // 匿名内部类 public void send(String str){ System.out.println(str); } }; msg.send("I am here!"); } }
同时我们也可以在接口中定义静态的匿名内部类:
package Demo_1_27_匿名内部类; public interface IMessage { public void send(String str); public static IMessage getInstance(){ return new IMessage() { //静态的匿名内部类 @Override public void send(String str) { System.out.println(str); } }; } }
package Demo_1_27_匿名内部类; public class Main { public static void main(String[] args) { IMessage.getInstance().send("I am here!"); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)