内部类基本定义
class Outer {
private String msg = "www.mldn.cn" ; // 私有成员属性
public void fun(){ //普通方法
Inner in = new Inner() ; // 实例化内部类对象
in.print() ;
}
class Inner { // 在Outer类的内部定义了Inner类
public void print(){
System.out.println(Outer.this.msg) ; // Outer类中的属性
}
}
}
public class StringDemo {
public static void main(String args[]){
Outer out = new Outer(); //实例化外部类对象
out.fun() ; // 调用外部类中的方法
}
}
如定义在外部
class Outer {
private String msg = "www.mldn.cn" ; // 私有成员属性
public void fun(){ //普通方法
// 思考五:需要将当前对象Outer传递到Inner类之中
Inner in = new Inner(this) ;// 实例化内部类对象
in.print() ;
}
// 思考一:msg属性如果要被外部访问需要提供有getter方法
public String getMsg(){
return this.msg ;
}
}
class Inner { // 在Outer类的内部定义了Inner类
// 思考三:Inner这个类对象实例化的时候需要Outer类的引用
private Outer out ;
// 思考四:应该通过Inner类的构造方法获取Outer类对象
public Inner(Outer out){
this.out = out ;
}
public void print(){
// 思考二:如果要想调用外部类的getter方法,那么一定需要由Outer类对象
System.out.println(this.out.getMsg()) ; // Outer类中的属性
}
}
public class StringDemo {
public static void main(String args[]){
Outer out = new Outer(); //实例化外部类对象
out.fun() ; // 调用外部类中的方法
}
}
以发现,整体的操作之中,折腾了半天主要目的就是为了让Inner这个内部可以访问Outer这个类中的私有属性,但是如果不用内部类的时候整体代码非常麻烦,所以得出内部类的优点:轻松的访问外部类中的私有属性。
内部类相关说明
内部类可以方便的访问外部类私有成员或私有方法,同理,外部类也可以轻松的访问内部类中的私有成员或私有方法。
package com.msc.high;
class Outer {
private String msg = "外部类成员属性" ; // 私有成员属性
public void fun(){ //普通方法
Inner in = new Inner( ) ;// 实例化内部类对象
in.print() ;
System.out.println(in.info) ; // 访问内部类的私有属性
}
public void print(){
System.out.println("外部类方法");
}
class Inner { // 在Outer类的内部定义了Inner类
private String info = "内部类成员属性" ;
public void print(){
System.out.println(Outer.this.msg) ; // Outer类中的属性
Outer.this.print();
}
}
}
public class InnerDemo {
public static void main(String[] args) {
Outer out = new Outer(); //实例化外部类对象
out.fun() ; // 调用外部类中的方法
}
}

但是需要注意的是,内部类本身也属于一个类,虽然在大部分的情况下内部类往往是被外部类包裹的,但是外部依然可以产生内部类的实例化对象,而此时内部类实例化对象的格式如下:
外部类.内部类 内部类对象 = new 外部类().new 内部类() ;
在内部类编译完成之后会自定形成一个“ Outer I n n e r . c l a s s ” 类 文 件 , 其 中 “ Inner.class ”类文件,其中“ Inner.class”类文件,其中“”这个符号换到程序之中就变为了“ . ”所以内部类的全称:“外部类.内部类”。内部类与外部类之间可以直接进行私有成员的访问,这样一来内部类如果要是提供有实例化对象了,一定要先保证外部类已经实例化了,
class Outer {
private String msg = "www.mldn.cn" ; // 私有成员属性
class Inner { // 在Outer类的内部定义了Inner类
private String info = "今天天气不好,收衣服啦!" ;
public void print(){
System.out.println(Outer.this.msg) ; // Outer类中的属性
}
}
}
public class StringDemo {
public static void main(String args[]){
Outer.Inner in = new Outer().new Inner() ;
in.print() ;
}
}
如果此时Inner类只允许Outer类来使用,那么再这样的情况下就可以使用private进行私有定义。
class Outer {
private String msg = "www.mldn.cn" ; // 私有成员属性
private class Inner { // 在Outer类的内部定义了Inner类
private String info = "今天天气不好,收衣服啦!" ;
public void print(){
System.out.println(Outer.this.msg) ; // Outer类中的属性
}
}
}
public class StringDemo {
public static void main(String args[]){
Outer.Inner in = new Outer().new Inner() ;
in.print() ;
}
}
此时的Inner类无法在外部进行使用。
在Java之中类作为最为基础的结构体实际上还有与之类似的抽象类或者是接口,抽象类与接口中都可以定义内部结构。
interface IChannel { // 定义接口
public void send(IMessage msg) ; // 发送消息
interface IMessage { // 内部接口
public String getContent() ; // 获取消息内容
}
}
class ChannelImpl implements IChannel {
public void send(IMessage msg){
System.out.println("发送消息:" + msg.getContent()) ;
}
class MessageImpl implements IMessage {
public String getContent(){
return "www.mldn.cn" ;
}
}
}
public class StringDemo {
public static void main(String args[]){
IChannel channel = new ChannelImpl() ;
channel.send(((ChannelImpl)channel). new MessageImpl()) ;
}
}
内部抽象类可以定义在普通类、抽象类、接口内部都是可以的。
interface IChannel { // 定义接口
public void send() ; // 发送消息
abstract class AbstractMessage {
public abstract String getContent() ;
}
}
class ChannelImpl implements IChannel {
public void send(){
AbstractMessage msg = new MessageImpl() ;
System.out.println(msg.getContent()) ;
}
class MessageImpl extends AbstractMessage {
public String getContent(){
return "www.mldn.cn" ;
}
}
}
public class StringDemo {
public static void main(String args[]){
IChannel channel = new ChannelImpl() ;
channel.send() ;
}
}
如果现在定义了一个接口,那么可以在内部利用类实现该接口,在JDK1.8之后追加了static方法可以不受到实例化对象的控制,现在就可以利用此特性来完成功能。
interface IChannel { // 定义接口
public void send() ; // 发送消息
class ChannelImpl implements IChannel {
public void send(){
System.out.println("www.mldn.cn") ;
}
}
public static IChannel getInstance(){
return new ChannelImpl() ;
}
}
public class StringDemo {
public static void main(String args[]){
IChannel channel = IChannel.getInstance() ;
channel.send() ;
}
}
内部类是一种非常灵活的定义结构,只要语法符合要求,各种需求都可以实现。
static定义内部类
如果说现在在内部类使用了static定义,那么这个内部类就变为了“外部类”,static定义的都是独立于类的外部结构,所以该类结构就相当于是一个独立的程序类。需要注意的是,static定义的不管是类还是方法只能够访问static成员,所有static定义的内部类只能够访问外部的static方法或成员属性。
package com.msc.high;
class Outer {
private static String msg = "外部类成员属性" ; // 私有成员属性
public void fun(){ //普通方法
Inner in = new Inner( ) ;// 实例化内部类对象
in.print() ;
System.out.println(in.info) ; // 访问内部类的私有属性
}
public static void print(){
System.out.println("外部类方法");
}
static class Inner { // 在Outer类的内部定义了Inner类
private String info = "内部类成员属性" ;
public void print(){
System.out.println(Outer.msg) ; // Outer类中的属性
Outer.print();
}
}
}
public class InnerDemo {
public static void main(String[] args) {
Outer out = new Outer(); //实例化外部类对象
out.fun();
}
}
class Outer {
private static final String MSG = "www.mldn.cn" ;
static class Inner {
public void print(){
System.out.println(Outer.MSG) ;
}
}
}
public class StringDemo {
public static void main(String args[]){
Outer.Inner in = new Outer.Inner() ;
in.print() ;
}
}
如果以static定义内部类的形式来讲并不常用,static定义内部接口的形式最为常用。
```java
interface IMessageWarp { // 消息包装
static interface IMessage {
public String getContent() ;
}
static interface IChannel {
public boolean connect() ; // 消息的发送通道
}
public static void send(IMessage msg, IChannel channel){
if(channel.connect()){
System.out.println(msg.getContent()) ;
}else {
System.out.println("消息通道无法建立,消息发送失败!") ;
}
} ; // 消息发送
}
class DefaultMessage implements IMessageWarp.IMessage {
public String getContent(){
return "www.mldn.cn" ;
}
}
class NetChannel implements IMessageWarp.IChannel {
public boolean connect(){
return true ;
}
}
public class StringDemo {
public static void main(String args[]){
IMessageWarp.send(new DefaultMessage(), new NetChannel()) ;
}
}
之所以使用static定义的内部接口,主要是因为这些操作是属于一组相关的定义,有了外部接口之后可以更加明确的描述出这些借口的主要功能。
方法中定义内部类
内部类可以在任意的结构中进行定义,这就包括了:类中、方法中、代码块中,但是从实际的开发来讲在方法中定义内部中形式较多。
范例:观察在方法中定义的内部类
```java
class Outer {
private String msg = "www.mldn.cn" ;
public void fun(long time){
class Inner { // 内部类
public void print(){
System.out.println(Outer.this.msg) ;
System.out.println(time) ;
}
}
new Inner().print() ; // 方法中直接实例化内部类对象
}
}
public class StringDemo {
public static void main(String args[]){
new Outer().fun(23151515) ;
}
}
此时在fun()方法内部提供有Inner内部类的定义,并且可以发现内部类可以直接访问外部类中的私有属性也可以直接访问方法中的参数,但是对于方法中的参数直接访问是从JDK1.8开始支持的,而在JDK1.8之前,如果方法中定义的内部要想访问方法中的参数则参数前必须追加final。
匿名内部类
匿名内部类是一种简化的内部类的处理形式,其主要是在抽象类和接口的子类上使用的。
与内部类相比匿名内部类只是一个没有名字的只能够使用一次的,并且结构固定的一个子类。
package com.msc.high;
class Outer {
private static String msg = "外部类成员属性" ; // 私有成员属性
public void fun(){ //普通方法
Inner in = new Inner( ) ;// 实例化内部类对象
in.print() ;
System.out.println(in.info) ; // 访问内部类的私有属性
}
public static void print(){
System.out.println("外部类方法");
}
static class Inner { // 在Outer类的内部定义了Inner类
private String info = "内部类成员属性" ;
public void print(){
System.out.println(Outer.msg) ; // Outer类中的属性
Outer.print();
}
}
}
interface IMessage {
public void send(String str) ;
}
interface IMath {
public int add(int x, int y) ;
}
class MessageImpl implements IMessage {
public void send(String str){
System.out.println(str) ;
}
}
interface IMessageb {
public void send(String str) ;
public static IMessage getInstance(){
return new IMessage(){
public void send(String str){
System.out.println(str) ;
}
};
}
}
public class InnerDemo {
public static void main(String[] args) {
IMessage msga = new MessageImpl() ;
msga.send("匿名内部类1") ;
IMessage msgb = new IMessage(){
public void send(String str){
System.out.println(str) ;
}
};
msgb.send("匿名内部类2") ;
IMessageb.getInstance().send("匿名内部类3") ;
IMessage msgd = (str)->{
System.out.println("Lambda表达式:"+str);
};
msgd.send("匿名内部类4");
IMath math = (t1,t2)->{
return t1+t2 ;
};
System.out.println("Lambda表达式匿名内部类5:"+math.add(10,20));
IMath mathb = (t1,t2)->t1+t2 ;
System.out.println("Lambda表达式匿名内部类6:"+mathb.add(20,20));
}
}

本文详细阐述了内部类如何访问外部类的私有属性,展示了静态内部类、匿名内部类和方法中定义内部类的应用,以及它们在技术场景中的优势。重点介绍了私有内部类的使用和接口内部类的实例化方式。
243

被折叠的 条评论
为什么被折叠?



