上一篇:初见“子母类”-内部类 | 带你学《Java面向对象编程》之八十二
【本节目标】
通过阅读本节内容,你将了解到内部类与外部类之间数据访问的互通性及其编译后的形态,并学会创建与使用内部的抽象类或接口。
内部类的相关说明
现在已经清楚地认识到内部类的优势以及结构,那么随后需要对内部类进行相关的说明,现在所定义的内部类都属于普通的内部类形式,普通的类内部往往会提供有属性和方法,需要注意的是,内部类虽然可以方便的访问外部类中的私有成员或私有方法,同理,外部类也可以轻松访问内部类中的私有成员或私有方法。
范例:外部类访问内部类中的私有成员属性
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类中的属性
} //www.mldn.cn
}
}
public class JavaDemo{
public static void main(String args[]) {
Outer out = new Outer() ; //实例化外部类对象
out.fun() ; //调用外部类中的方法
}
}
使用了内部类之后,内部类与外部类之间的私有操作的访问就不再需要通过setter、getter以及其它的间接方式完成了,可以直接进行处理操作。
但是需要注意的是,内部类本身也属于一个类,虽然在大部分情况下内部类往往是被外部类包裹的,但是外部依然可以产生内部类的实例化对象,而此时内部类实例化对象的格式如下:
外部类.内部类 内部类对象 = new 外部类().new 内部类() ;
在内部类编译完成之后会自动形成一个“Outer$Inter.class”类文件,其中“$”这个符号换到程序之中就变为“.”,所以内部类的全称:“外部类.内部类”。内部类与外部类之间可以直接进行私有成员的访问,这样一来内部类如果提供有实例化对象了,一定要先保证外部类已经实例化了。
class Outer { //外部类
private String msg = "www.mldn.cn" ; //私有成员属性
class Inner { //在Outer类的内部定义了Inner类
public void print() {
System.out.println(Outer.this.msg) ; //Outer类中的属性
} //www.mldn.cn
}
}
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类中的属性
} //www.mldn.cn
}
}
此时的Inner类无法在外部进行使用。
在Java之中类作为最基础的结构体实际上还有与之类似的抽象类或者是接口,抽象类与接口中都可以定义内部结构。
范例:定义内部接口
interface Channel { //定义接口
public void send(Message 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()) ;
}
}
下面继续观察一个内部抽象类,内部抽象类可以定义在普通类、抽象类、接口内部都是可以的。
范例:观察内部抽象类
interface Channel { //定义接口
public void send(String msg) ; //发送消息
abstract class AbstractMessage {
public abstract String getContent() ;
}
}
class ChannelImpl implements IChannel {
public void send() {
AbstractMessage msg = new MessageImpl() ;
System.out.println(msg.getContent()) ; //www.mldn.cn
}
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() ;
}
}
内部类还有一些更为有意思的结构,即:如果现在定义了一个接口,那么可以在内部利用类实现该接口,在JDK1.8之后在接口中追加了static方法可以不受实例化对象的控制,现在就可以利用此特性来完成此功能。
范例:接口内部进行接口实现
interface Channel { //定义接口
public void send(String msg) ; //发送消息
class ChannelImpl implements IChannel {
public void send() {
System.out.println("www.mldn.cn") ; //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() ;
}
}
内部类一种非常灵活的定义结构,只要语法满足了,各种需求都可以帮你实现。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学
下一篇:内部类的“独立”-static内部类 | 带你学《Java面向对象编程》之八十四
更多Java面向对象编程文章查看此处