Java基础(三十二)

内部类

背景:

虽然在类中的基本组成就是成员属性与方法,但是在任何的语言里面结构也是允许进行嵌套的,所以在一个类的内部都可以定义其他的类,这样的类就称为内部类。

1:什么是内部类

内部类是一个独立且完善的类结构,在一个类的内部除了属性和方法之外可以继续使用class定义内部类。

class Outer {	// 外部类
	private String msg = "xiaochaochao" ;	// 私有成员属性
	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 Test {
	public static void main(String args[]) {
		Outer out = new Outer() ;	// 实例化外部类对象
		out.fun() ;	// 调用外部类中的方法
	}
} 
//xiaochaochao

在这里插入图片描述

将上述的两个类分为两个类:

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 JavaDemo {
	public static void main(String args[]) {
		Outer out = new Outer() ;	// 实例化外部类对象
		out.fun() ;	// 调用外部类中的方法
	}
} 

在这里插入图片描述

2:内部类的相关说明

在这里插入图片描述

外部类访问内部类中的私有属性

class Outer {	// 外部类
	private String msg = "www.mldn.cn" ;	// 私有成员属性
	public void fun() {	// 普通方法
		Inner in = new Inner() ;	// 实例化内部类对象
		in.print() ;	// 调用内部类方法
		System.out.println(in.info) ;	// 访问内部类的私有属性
	}
	class Inner { // 在Outer类的内部定义了Inner类
		private String info = "今天天气不好,收衣服啦!" ;
		public void print() {
			System.out.println(Outer.this.msg) ;	// Outer类中的属性
		}
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		Outer out = new Outer() ;	// 实例化外部类对象
		out.fun() ;	// 调用外部类中的方法
	}
} 

在这里插入图片描述

3:内部类实例化格式

内部类本身也是一个类,虽然在大部分情况下内部类往往是被外部类包裹的,但是外部依然可以产生内部类的实例化对象,此时实例化对象的格式如下;

外部类.内部类 内部类对象 = new 外部类().new 内部类() ;

在这里插入图片描述

class Outer {	// 外部类
	private String msg = "www.mldn.cn" ;	// 私有成员属性
	class Inner { // 在Outer类的内部定义了Inner类
		public void print() {
			System.out.println(Outer.this.msg) ;	// Outer类中的属性
		}
	}
}
public class JavaDemo {
	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类
		public void print() {
			System.out.println(Outer.this.msg) ;	// Outer类中的属性
		}
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		Outer.Inner in = new Outer().new Inner() ;
		in.print() ;
	}
} 

上述代码中Inner类无法在外部进行使用。

4:定义内部接口

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 JavaDemo {
	public static void main(String args[]) {
		IChannel channel = new ChannelImpl() ;
		channel.send(((ChannelImpl)channel).new MessageImpl()) ;
	}
} 

5:内部抽象类

继续观察内部抽象类:内部抽象类可以定义在普通类,抽象类,接口内部都可以。

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 JavaDemo {
	public static void main(String args[]) {
		IChannel channel = new ChannelImpl() ;
		channel.send() ;
	}
} 

6:接口内进行接口实现

内部类还有一些结构:如果现在定义了一个接口,那么可以在内部利用类实现该接口,在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 JavaDemo {
	public static void main(String args[]) {
		IChannel channel = IChannel.getInstance() ;
		channel.send() ;
	}
} 

7:static定义内部类

在这里插入图片描述

使用static定义内部类:

class Outer {	// 外部类
	private static final String AAA = "xiaochaochao" ;	// 私有成员属性
	static class Inner { // 在Outer类的内部定义了Inner类
		public void print() {
			System.out.println(Outer.AAA) ;	// Outer类中的属性
		}
	}
}

在这里插入图片描述

public class Test {
	public static void main(String args[]) {
		Outer.Inner  in = new Outer.Inner();
		in.print();
	}
} 
//xiaochaochao

以后开发之中如果发现类名称上提供有“.”首先应该立刻想到这是一个内部类的结构,如果可以直接进行实例化,则应该立刻认识到这是一个static定义的内部类。

8:使用static定义内部接口

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 JavaDemo {
	public static void main(String args[]) {
		IMessageWarp.send(new DefaultMessage() , new NetChannel() ) ;
	}
} 

9:方法中定义内部类

内部类可以在任意的结构中进行定义,这就包括了:类中,方法中,代码块中,但是从实际的开发中在方法中定义内部类的形式较多。

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 JavaDemo {
	public static void main(String args[]) {
		new Outer().fun(2390239023L) ;
	}
} 

在这里插入图片描述

在JDK1.85之前的程序结构如下:

class Outer {
	private String msg = "www.mldn.cn" ;
	public void fun(final long time) {
		final String info = "我很好" ;
		class Inner { // 内部类
			public void print() {
				System.out.println(Outer.this.msg) ;
				System.out.println(time) ;
				System.out.println(info) ;
			}
		}
		new Inner().print() ;	// 方法中直接实例化内部类对象
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		new Outer().fun(2390239023L) ;
	}
} 

10:匿名内部类

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

使用匿名内部类:

interface IMessage {
	public void send(String str) ;
}
public class JavaDemo {
	public static void main(String args[]) {
		IMessage msg = new IMessage() {	// 匿名内部类
			public void send(String str) {
				System.out.println(str) ;
			}
		} ;
		msg.send("www.mldn.cn") ;
	}
} 

在这里插入图片描述

interface IMessage {
	public void send(String str) ;
	public static IMessage getInstance() {
		return new IMessage() {
			public void send(String str) {
				System.out.println(str) ;
			}
		} ;
	}
}
public class JavaDemo {
	public static void main(String args[]) {
		IMessage.getInstance().send("www.mldn.cn") ;
	}
} 

与内部类相比匿名内部类只是一个没有名字的,只能够使用一次。并且结构固定的一个子类。

总结

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35649064/article/details/83830695