内部类
背景:
虽然在类中的基本组成就是成员属性与方法,但是在任何的语言里面结构也是允许进行嵌套的,所以在一个类的内部都可以定义其他的类,这样的类就称为内部类。
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") ;
}
}
与内部类相比匿名内部类只是一个没有名字的,只能够使用一次。并且结构固定的一个子类。
总结