JAVA中的内部类
Java的四种内部类包括如下:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
成员内部类:
- 定义在另一个类(外部类)的内部,而且与成员方法和属性平级叫成员内部类,…相当于外部类的非静态方法,如果被static修饰,就变成静态内部类了。
- 1.内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)
- 2.用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。
对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。 - 3.成员内部类不能定义静态成员,只能定义对象成员。
建立内部类对象时应注意:
在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)
而在外部类的外部,要生成(new)一个内部类对象,需要首先建立一个外部类对象(外部类可用),然后在生成一个内部类对象。
Outer o=new Outer();
Outer.Inner in=o.new.Inner()。 - 4、创建成员内部类实例时,外部类的实例必须已经存在。
- 5、当内部类和外部类有同名的成员时,内部类可通过 外部类名.this.变量名 访问外部类成员
package one;
public class Outer{
private static int outer_i = 1;
private int k=20;
public static void outer1(){
//...
}
//成员内部类
class Inner{
int j=100;//内部类中外部类的实例变量可以共存
int inner_i=1;
void inner1(){
System.out.println(outer_i);//外部类的变量如果和内部类的变量没有同名的,则可以直接用变量名访问外部类的变量
System.out.println(j);//在内部类中访问内部类自己的变量直接用变量名
System.out.println(this.j);//也可以在内部类中用"this.变量名"来访问内部类变量
//访问外部类中与内部类同名的实例变量可用"外部类名.this.变量名"。
System.out.println(k);//外部类的变量如果和内部类的变量没有同名的,则可以直接用变量名访问外部类的变量
outer1();
}
}
//外部类的非静态方法访问成员内部类
public void outer2(){
Inner inner = new Inner();
inner.inner1();
}
//外部类的静态方法访问成员内部类,与在外部类外部访问成员内部类一样
public static void outer3(){
Outer out = new Outer();//step1 建立外部类对象
Inner inner=out.new Inner();//step2 根据外部类对象建立内部类对象
inner.inner1();//step3 访问内部类的方法
}
public static void main(String[] args){
outer3();
}
}
静态内部类
使用static修饰的成员内部类叫静态内部类。
- 静态内部类定义在类中,任何方法外,用static定义。
- 静态内部类只能访问外部类的静态成员。
- 生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:
Outer.Inner in=new Outer.Inner();
- 而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。可以定义私有静态内部类。
局部内部类
定义在代码块、方法体内、作用域(使用花括号“{}”括起来的一段代码)内的类叫局部内部类。
局部内部类只能在代码代码块、方法体内和作用域中使用(如创建对象和使用类对象等)
局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰。
可以使用abstract修饰,声明为抽象类
public class Outer {
public void say(){
System.out.println("关门说真话!");
}
}
public class Test {
public void ting(){
class MiMi extends Outer{//定义一个局部的内部类,继承Outer方法
//……
}
new MiMi().say();//调用局部内部类中继承的say方法
System.out.println("别人都不知道");
}
public static void main(String[] args) {
new Test().ting();
}
匿名内部类
- 匿名内部类是在抽象类和接口的基础之上发展起来的。匿名内部类如果继承自接口,必须实现指定接口的方法,且无参数 。匿名内部类如果继承自类,参数必须按父类的构造函数的参数传递
- 匿名内部类的特点:
- 1),一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的事先或是覆盖。
- 2),只是为了获得一个对象实例,不需要知道其实际类型。
- 3),类名没有意义,也就是不需要使用到。
package three;
abstract class parent {
public abstract void like();
}
public class Demo {
public static void main(String[] args) {
parent pt = new parent(){
public void like(){
System.out.println("吃饭睡觉打豆豆。。。");
}
};
pt.like();
}
}
内部类总结:
- 1.内部类作为外部类的一个特殊的成员来看待,因此它有类成员的封闭等级:private ,protected,默认(friendly),public 它有类成员的修饰符: static,final,abstract
- 2.非静态内部类nested inner class,内部类隐含有一个外部类的指针this,因此,它可以访问外部类的一切资源(当然包括private)外部类访问内部类的成员,先要取得内部类的对象,并且取决于内部类成员的封装等级。非静态内部类不能包含任何static成员.
- 3.静态内部类:static inner class,不再包含外部类的this指针,并且在外部类装载时初始化. 静态内部类只能访问外部类static成员. 外部类访问静态内部类的成员:static成员:类名.成员;非static成员:对象.成员
- 4.对于方法中的内部类或块中内部类只能访问块中或方法中的final变量。