目录
简述内部类:
内部类顾名思义是定义在另一个类中的类,而类的基本结构应该是属性加方法,内部类无疑破坏了类的原有结构。但是存在即合理,所以内部类的存在必定有他的优势。
简单看一下内部类的表示:
/*代码1*/
class Outer{
private String msg ="一个消息!";
public void fun(){
Inner in = new Inner();
in.print();
}
class Inner{
public void print(){
System.out.println(Outer.this.msg);
}
}
}
由代码显然可见Outer为外部类,Inner为内部类。在外部类的send()方法中,可以直接实例化内部类对象并通过该对象访问其方法。在内部类中,print()方法中输出了外部类的中的私有属性的msg,这里体现了内部类的一个有点即它可以访问外部类中的私有属性或者方法。
现在我试着对上述的两个类进行拆分,即两个类不再有内外的关系。
首先是外部类Outer:
class Outer { private String msg="一个消息!"; public void fun(){ Inner in = new Inner(); in.print(); } }
其次是内部类Inner:
class Inner{ public void print(){ System.out.println(Outer.this.msg); } } /*毋庸置疑,print()方法中的输出Outer.this.msg肯定会报错,我们不能在一个类的外面去访问其私有变量,如要访问,则应该在该类中添加一个get方法去获取该属性的值,再在类外面实例化一个对象去调用该方法以获取该属性的值。那么经过修改,最后的代码就会变成这样。*/class Outer { private String msg="一个消息!"; public String getMsg() { return msg; } public void fun(){ new Inner().print(); } } class Inner{ public void print(){ System.out.println(new Outer().getMsg()); } }
观察修改后的代码,Inner类的print()方法中实例化了一个Outer类对象,而在Outer类中我实例化了一个Inner类对象,并且调用了print方法,所以造成了一个我Outer类在自己的方法中好像又创建了一个自己,这是不是显得自己很呆。所以我选择了内部类。而且看起来代码也更简单,更合理。
内部接口/抽象类:
接口和内部类在抽象类的应用中没什么很大的区别,这里主要看一下内部抽象类在外部被继承,外部接口被内部类实现。
内部抽象类在外部被继承:
/*代码2*/
abstract class AbstractMessage{
public abstract void send();
abstract class AbstractService{
public abstract void service();
}
}
class NetMessage extends AbstractMessage{
@Override
public void send() {
System.out.println("发送网络消息!");
}
class HouseService extends AbstractService{
@Override
public void service() {
System.out.println("提供住房服务!");
}
}
}
外部接口被内部类实现:
/*代码3*/
interface IMessage {
void send();
class NetMessage implements IMessage{
@Override
public void send() {
System.out.println("发送网络消息!");
}
}
}
内部类的实例化:
下面讲一下内部类是如何使用的,即如何对内部类在外部实例化。一般情况下在外部实例化内部类对象遵循这样一个规则:内部类.外部类 类名 = new 外部类().new 内部类();
因此在代码1中可以采用如下创建方式。
Outer.Inner in = new Outer().new Inner();
in.print();
值得注意的是,对于代码3来说,因为内部类实现外部接口,所以内部类的创建方式会有所不同,如下所示。
IMessage message = new IMessage.NetMessage();
message.send();
虽然有所差距,但是也并不难理解。
Static修饰内部类
我所常见的static修饰有修饰一段代码块,成员变量,方法,这是我第一次接触static去修饰一个类的,不过static如果修饰一个类则该类必须为内部类。闲话少说,直接看代码。
class Outer{
private static String msg ="一个消息";
public void fun(){
Inner in = new Inner();
in.print();
}
static class Inner{
public void print(){
System.out.println(Outer.msg);
}
}
}
这里对msg稍作修改,加了一个static,而且内部类的print()函数中直接使用Outer.msg即可使用,对于这部分很好理解。关键在于他的内部类实例化,又与前面有所不同。具体如下:
Outer.Inner inner = new Outer.Inner();
匿名内部类:
匿名内部类是一个没有名字的内部类,在程序中只能使用一次。
IMessage iMessage = new IMessage() {
@Override
public void send() {
System.out.println("你好");
}
};
iMessage.send();
如上所示,就是一个在程序中的匿名内部类的实现,匿名内部类在多线程的编程中会比较常见,如:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("多线程中的匿名内部类");
}
}).start();
(该文章内容来自与阿里云中的教学视频学习,仅为学习笔记用)