java当中一个类可以作为另一个类的成员,这样的类就称为内部类。
非静态内部类:在一个外部类里创建一个非静态的内部类,可以用访问限制修饰符修饰,与普通成员没区别。内部类对象可以在外部类之内创建,也可以在外部类之外创建。
外部类和内部类之间的成员互访
内部类的成员访问外部类的成员时和普通成员互访一样。而外部类访问内部类非静态成员时要先创建内部类对象,外部类可以访问内部类的私有成员。
要注意,内部类不能有静态成员。
内部类想使用this调用外部类的成员需要 <外部类类名>.this.<外部类成员>,因为直接使用this调用的是内部类本身。
局部内部类:内部类可以和局部变量相同,只在其所在的语句块中有效,如在外部类的一个方法中定义一个内部类。通过这样方法创建的内部类,在其所在的语句块结束后,内部类对象依然存在。局部内部类可以访问外部类的成员,但是要注意,如果局部内部类位于静态方法中,则只能访问外部类静态的成员。、
静态内部类:在外部类里用static定义内部类,就是静态内部类,静态内部类不能访问外部的非静态成员。在外部类之外创建静态内部类,不需要构建外部类对象,直接调用静态内部类构造方法就可以,而且可以在外部直接使用内部类中的方法。
package com.example.lfz;
interface ForInner{
void hello();
void show();
}
class Outter {
int x = 999;
// 非静态内部类
class Inner {
// priate static int x=100 这是非法的
int x = 100;
public void show() {
System.out.println("this is inner function in Inner class");
}
//这是一个私有方法,外部类可以访问
private void show2() {
System.out.println("this is private in inner class");
System.out.println("x at inner class is" + this.x);
System.out.println("x at inner class is" + Outter.this.x++);
}
}
ForInner forInner=null;
public void defineInner(){
int x=128;
class Inner implements ForInner{
public void hello(){
System.out.println("hello");
}
public void show(){
System.out.println("这是一个局部内部类");
System.out.println("访问这个方法中的x="+x);
}
}
forInner = new Inner();
Inner i=new Inner();
i.show();
}
// 在外部类中创建内部类的方法
public void createInner() {
Inner i = new Inner();
// 外部类访问内部类的私有方法
i.show2();
}
//静态内部类
static class staInner{
public void show(){
System.out.println("this is a static inner class");
}
}
//创建静态内部类方法和创建非静态内部类一样
public void getStaInner(){
staInner i=new staInner();
i.show();
}
}
public class innerClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建外部类对象
Outter o = new Outter();
// 调用外部类中的创建内部类方法,并调用了内部类的私有方法
o.createInner();
// 在外部类之外创建内部类 方法1
Outter.Inner i2 = o.new Inner();
i2.show();
// 在外部类之外创建内部类 方法2
Outter.Inner i = new Outter().new Inner();
i.show();
//使用局部方法创建局部内部类
o.defineInner();
//使用局部方法创建的对象依然存在
o.forInner.hello();
o.forInner.show();
//在外部创建静态内部类不用先构建外部类
Outter.staInner sInner=new Outter.staInner();
//在外部直接调用静态内部类的方法
new Outter.staInner().show();
}
}
静态/非静态内部类的区别:非静态内部类与外部类的对象存在对成员共享的关系,它是外部类组成的一部分,用来辅助外部类对象工作。静态内部类已经脱离了外部类的控制,其创建不需要外部类对象的存在,实质上只是一个放置在别的类中的普通类。static关键字只是说明其在创建对象时不依赖外部类对象的存在,并不是说这个类是静态的。
匿名内部类:创建一个内部类而没有类名就是匿名内部类,匿名内部类可以基于继承和基于实现接口来创建。
package com.example.lfz;
//定义父类
class father {
public void show() {
System.out.println("this is father");
}
}
//定义接口
interface MyInterface{
public void show();
}
//定义父类
abstract class FatherForInner
{
int count;
abstract void show();
}
public class noNameInner {
public static void main(String[] args) {
//创建一个匿名内部类继承父类
father f = new father() {
public void show() {
System.out.println("this is unNameInnerClass");
}
};
f.show();
//定义匿名内部类实现接口
MyInterface mi=new MyInterface(){
public void show(){
System.out.println("this is unNameInnerClass base on interface");
}
};
mi.show();
//创建一个匿名内部类并进行初始化
FatherForInner ffi=new FatherForInner(){
//定义非静态语句块进行初始化
{
count=(int)(100*Math.random());
}
public void show(){
System.out.println("初始化后count的值为"+count);
}
};
ffi.show();
}
}
匿名内部类可以直接创建一个类重写父类的方法或者实现一个接口,当某个类只需要使用一次,不需要为其多次创建对象的时候,就可以使用匿名内部类。
在事件处理中,如onClickLIstener,就可以大量使用匿名内部类。