内部类相关📄
分类
类别 | 解释 |
---|---|
本地内部类 | 定义在方法中的类 |
实例内部类 | 定义在一个类的内部,并且没被static修饰 |
静态内部类 | 相比较于实例内部类而言,多了个static修饰 |
匿名内部类 | 不带名字的内部类,多用于接口的实现类 |
实例内部类🌊
- 或者叫非静态内部类,常规的类和类之间是相互独立的,那使用了非静态内部类之后呢就会出现非静态内部类依赖于外部类对象的情况,因此非静态内部类就和一个普通的类里的成员变量或者方法地位相同,而后者也同样是依赖于外部类对象的引用来进行调用的.
- 为什么要存在内部类?可以更好的隐藏细节,封装效果更好,编码更加优雅.
- 举例:
public class OuterClass {
//成员变量
private String outerName;
//成员方法
public void display(){
System.out.println("outerClass::display");
System.out.println(outerName);
}
//内部类(与上述的成员方法/变量 同等级别)
public class innerClass{
private String innerName;
public void display(){
System.out.println("innerClass::display");
System.out.println(innerName);
}
public innerClass() {
this.innerName = "inner Class";
}
}
}
实例内部类的注意事项💅
-
如何实例化?
刚才也提到了,实例内部类依赖于外部类,针对实例内部类的实例化而言,实例内部类的构造方法需要外部类对象的引用来进行调用,比如上述的实例内部类可以这样实例化:
OuterClass out=new OuterClass(); OuterClass.innerClass in=out.new innerClass(); //注意:第二行代码的等号左边,OuterClass可以省略,只不过写出来可以显示的告诉大家这里有一个内部类 //并且谁是内部类一目了然
-
实例内部类里头是什么成员都可以定义吗?
不是!因为这个内部类本身都是要依赖于外部类对象的,那它自己还包含静态字段或者方法,那岂不是和依赖于对象的引用才能构造出内部类对象的前提相矛盾了吗,所以非静态内部类内不可以定义static修饰的字段或者方法;但有一个特例:字段如果是被static修饰,则必须再加一个final修饰!但是static修饰方法是一定不行的!
-
实例内部类可以被继承吗?
可以,但没必要,平常一般也不会有这种用法,所以不过多介绍.
-
什么时候用内部类呢?
比如说:什么由…组成?就可以将…写成一个内部类!更具体的来说,我们自己创建链表的时候,链表是由节点组成的,那我们就可以把节点写成内部类呀!那此时就相当于定义了一个类型.
-
内部类生成的字节码文件长啥样?
外部类类名$实例内部类类名.class
-
如果实例内部类里有和外部类同名的字段,那怎么个调用呢?
优先调用自己的,自己没有的,就会去外部类里去找,那我非要调用外部类的那个同名字段怎么办?那就在字段前面加上外部类类名.this.字段名
如果仅仅就只是一个this,那就只是知道内部类对象的引用,跟省略不写一样,默认先调用自己的.
静态内部类✌️
- 相比于实例内部类,多了个static修饰
- 静态内部类里可以定义普通字段或者方法,也可以定义静态字段或者方法,因为此时的内部类已经不需要依赖于外部类对象的引用来调用内部类的构造方法了,不依赖于对象了,那定义静态的东西就不冲突咯.
- 既然不依赖于对象,那要想访问到外部类的普通成员变量等依赖于对象的东西,那就只能实例化外部类对象来进行调用了,使用外部类的匿名对象来调用也行
public class OuterClass {
//成员变量
private String outerName;
//静态内部类
public static class innerClass{
private static String name;
public int age;
public void display(){
System.out.println(new OuterClass().outerName+"inner display");
}
}
}
匿名内部类🌵
- 没有名字的内部类,匿名内部类只要用于接口等的具体实现类的简化,因为如果是常规写法,那接口写一个文件,具体实现类写一个文件,就是两个文件,而使用匿名内部类就可以写一个接口文件即可完成相同的目的,如代码:
public interface MyInterface {
void display();
}//在另一个文件内
public class TestDemo {
public static void main(String[] args) {
//等号右边的new MyInterface()就等价于有一个类实现了MyInterface接口,花括号内的内容是这个匿名内部类的内容!
MyInterface myInterface=new MyInterface() {
@Override
public void display() {
System.out.println("hehe");
}
};
myInterface.display();
}
}
//如果是常规写法,具体实现类要写一个文件,具体实现类实现了MyInterface接口,总之就要写两个文件了!
2.当然内部类也可以实现接口
public class TestDemo {
public class InnerClass implements MyInterface{
@Override
public void display() {
System.out.println("hehe");
}
}
public static void main(String[] args) {
TestDemo testDemo=new TestDemo();
TestDemo.InnerClass innerClass=testDemo.new InnerClass();
innerClass.display();//打印"hehe"
}
}
关于内部类,掌握这么多差不多了,细节可后续深化.
本地内部类⚡️
- 定义在方法内部
- 如:
public class OuterClass {
//成员变量
private String outerName;
//成员方法
public void display(){
//方法内部类,此时的内部类不再依赖于外部类
class innerClass{
private String innerName;
public void display(){
System.out.println("local display");
}
}
innerClass innerClass=new innerClass();
innerClass.display();
}
//内部类(与上述的成员方法/变量 同等级别)
public static void main(String[] args) {
OuterClass outerClass=new OuterClass();//等号前面的外部类.内部类只是表明内部类隶属于外部类,其实不写外部类也可以,只不过这样写更加直观
outerClass.display();
}
}
//打印:local display
本地内部类不可以被public修饰哦.
看完有收获的,请点个赞,谢谢