(1)成员内部类的实例化:
外部类名.内部类名 变量名=外部类对象.new 内部类名();
class Person{ class Test{ } } Person p=new Person(); Person.Test t=p.new Test();
(2)在内部类中访问外部类属性或方法。
外部类名.this.属性名
Person.this.name
(3)成员内部类声明的注意事项
①内部类不能与外部类重名。
②成员内部类中不能出现静态属性,静态方法和静态内部类。
但是静态常量例外。
private static final String name="1";//此情况可以使用
class Test{//成员内部类 private String name; private int age; public void say(){ System.out.println(Person.this.name);//访问外部类的 System.out.println("Person中的Test的say方法"); } }
2.静态内部类。
(1)使用static修饰的内部类,叫做静态内部类。
(2)实例化:外部类名.内部名 变量=new 外部类名.内部类名();
class Person{ public String name="1"; public Static int age="12"; static class Test{ } } Person.Test t=new Person.Test();
注意与成员内部类实例化的区别。
(3)静态内部类中不能访问外部类的非静态属性和方法。
但可以访问外部类中的静态属性和方法,使用外部类名.属性名;
Person.age;
(4)外部类不能访问静态内部类的非静态属性和方法,但可以访问静态内部类的的静态属性和方法,外部类名.属性名。
Test.age;
(5)【静态内部类和成员内部类的区别】
1.声明方式和实例化方式不同。成员内部类不带static
静态内部类实例化: Person.Test t=new Person.Test();
成员内部类实例化: Person.Test t=p.new Test();
2.成员内部类中不能出现静态属性和方法,但静态内部类可以。
3.外部类和内部类的互相访问权限不同:
①静态内部类中不能访问外部类的非静态属性和方法。
但可以访问外部类中的静态属性和方法,使用外部类名.属性名;
②成员内部类中不能出现静态属性,静态方法和静态内部类。
但是静态常量例外。
static class Test1{ public static String test="111"; public void say(){ System.out.println("Test1"); } }
3.【局部内部类】(一般不用)。
(1)定义在某个类中的方法中的内部类,称为局部内部类。
(2)局部内部类是对外部完全隐藏的,只能在其作用域范围内被实例化。
(3)局部内部类可以访问外部类的属性和方法,使用外部类.this.属性名;
Person.this.name;
(4)局部内部类:不能访问其所在方法中的变量,只能访问常量。
(5)注意:局部内部类不能使用访问修饰符修饰,因为它不属于类的成员,它属于方法中的局部变量。
public void eat(){ // final String name1="123"; class Test2{ public String name="123"; public void test(){ System.out.println(Person.this.name); // System.out.println(name1); } } Test2 t=new Test2(); System.out.println(t.name); } }
4.匿名内部类。
new Test1(){
};
(1)写法
(2)含义:相当于一个匿名类继承了Test1类,使用匿名内部类将直接返回当前子类的对象。
Test1 t=new Test1(){};
(3)相当于:①一个匿名内部类,继承了Test1类。
②匿名内部类返回一个子类对象,并付给父类引用。
因此这一行代码用于向上转型。
(4)匿名内部类通常用于直接实例化抽象类或接口。
Test1 t=new Test1(){
//重写抽象类Test1中的所有的抽象方法
//相当于一个匿名内部类,继承了Test1类,然后返回这个匿名内部类的对象。
};
Test1 t2=new Test1(){ public int age=12; public void eat(){ System.out.println(age); System.out.println("eat"); } public void say(){ System.out.println("匿名重写Test1类的say方法"); } }; //向上转型,会丢失掉子类特有的属性和方法,new Test1(){}.eat(); t2.say();
5.使用内部类模拟多继承 。
class A{ public void a() { System.out.println("a"); } } class B{ public void b(){ System.out.println("b"); } } class C{ class A1 extends A{ } class B1 extends B{ } public void a(){ new A1().a();//不管A类是不是抽象类都可以,如果是A则要考虑是不是抽象类 } public void b(){ new B1().b(); } }
C c=new C(); //结果a,b c.a(); c.b();