内部类可以直接访问外部类的成员
外部类想要访问外部类的成员,先需要实例化内部对象也就是(new内部对象)
- 成员内部类
Outer.Inner inner=new Outer().new Inner()
成员内部类持有外部类对象的引用
- 我的理解:(外部类对象可以引用成员内部类)
要想有成员内部类对象,先要有外部类对象
先创建一个Net类
public class Net {
UI ui;
public void setUi(UI ui){
this.ui = ui;
}
public void loadData( ){
String str="Hello wrold";
ui.updateUI(str);
}
}
然后再创建UI类
public class UI {
public void updateUI(String str){
System.out.println("正在更新"+str);
}
class Net{
public void loadData(){
}
}
}
UI类里面有Net内部类
再创建一个测试类Test
public class Test {
public static void main(String[] args) {
UI ui=new UI();
Net net=new Net();
net.setUi(ui);
net.loadData();
}
}
输出结果为:正在更新Hello wrold
成员内部类可能出现内存泄漏的问题,内存越用越少,有些对象没有释放完毕。(如果你想释放外部类对象,但是成员内部类持有外部对象的引用。因此回收不了。)
- 静态内部类
静态内部类不需要有外部类对象,静态内部类不持有外部类的引用,静态内部类不能访问外部的非静态成员,但是可以通过new()外部类 .成员的方法访问
创建静态内部类
public class HelloWorld {
private int dynamic_score = 77;
public static class SInner {
int score = 91;
public void show() {
System.out.println("访问外部类中的非静态变量dynamic_score:" + new HelloWorld().dynamic_score);
System.out.println("访问内部类中的score:" + score);
}
}
测试静态内部类
public static void main(String[] args) {
// 直接创建内部类的对象
SInner si = new SInner();
// 调用show方法
si.show();
}
}
输出结果:
访问外部类中的非静态变量dynamic_score:77
访问内部类中的score:91
- 匿名内部类
匿名内部类最长用:
Net net=new Net(){loadDate(){}};
BufferedReader br=new BufferedReader(new FileReader(""));
注意事项:
1、匿名内部类中是不能定义构造函数的。
2、匿名内部类中不能存在任何的静态成员变量和静态方法。
3、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
4、没有抽象方法的抽象类。
这里定义了一个人吃的抽象方法
要想在抽象类中使用匿名内部类,必须实现一个继承或者一个接口
abstract class Person {
public abstract void eat();
}
class Child extends Person {
public void eat() {
System.out.println("eat something");
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}
输出结果为:
eat something
- 局部内部类
写在方法中的,一般来说,需要返回对象,之后想什么时候调用就什么时候调用。
在局部内部类访问方法中的变量的时候,变量需要是final的,(常量)如果不定义成final的,变量就会随着方法的结束从栈内存消失、导致局部内部类不能访问局部变量。
体现局部内部类的代码
class Out {
private int age = 12;
public void Print(final int x) {
class In {
public void inPrint() {
System.out.println(x);
System.out.println(age);
}
}
new In().inPrint();
}
}
final int x
由上面代码可知:
局部内部类访问方法中的变量的时候,变量需要是final修饰的
测试类
public class Demo {
public static void main(String[] args) {
Out out = new Out();
out.Print(3);
}
}
运行结果为:
3
12
在上面的代码中,我们将内部类移到了外部类的方法中
内部类移到了外部类
public void Print(final int x) {
class In {
在外部类的方法中再生成一个内部类对象去调用内部类方法
main方法中的:
out.Print(3);
注意事项:
1、此类不能使用public、private修饰。
2、其作用域被限定在声明此类的方法中。
3、和其他内部类相比,它具有可以访问方法参数的优点。
4、被局部内部类使用的方法参数必须是final的。
5、局部类只能访问(使用)这个块中(局部类外)final属性。这里的块包括了上面说的块、构造器、方法。
6、在类外不可直接生成局部内部类,要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部类。