① 概念:在一个类的内部定义了完整的一个类。
//外部类
class MyClass{
//内部类
class ClassA{}
}
② 内部类编译之后,会生成独立的.class文件
例如:文件名: MyClass$ClassA.class
③ 内部类可以直接访问外部类的私有成员,从而不破坏类的封装。
④ 内部类的分类:成员内部类、静态内部类、局部内部类、匿名内部类【面试重点】
a. 成员内部类:(类比于成员变量)【了解 1%】
I. 位置:类以内,方法以外
II.创建成员内部类的对象,必须依赖于外部类的对象来创建:
Outer o=new Outer();//外部类的对象
Outer.Inner i=o.new Inner();
III. 成员内部类可以直接访问外部类的私有成员,从而不破坏外部类的封装性。
IV. 外部类类名.this 指向外部类的当前对象
外部类类名.this.属性名 :访问外部类的属性
V. 成员内部类中不能定义静态的成员(静态属性和静态方法)
package demo2017114;
/*
* 成员内部类
*/
public class TestChengYuanInnerClass {
public static void main(String[] args) {
Outer ou = new Outer();
Outer.Inner in=ou.new Inner(); //创建内部类对象要借助外部类对象
in.inner();
}
}
class Outer{
int a=10;
private int b=11; //外部类的私有属性
class Inner{
int a=12; //声明了一个与外部类相同的属性
//static int c=666; //成员内部类不能有静态成员
public void inner(){
System.out.println(this.a); //就近访问
System.out.println(Outer.this.b); //访问外部类的属性,不破坏封装性
System.out.println(Outer.this.a); //访问外部类的与内部类命名冲突的属性
}
}
}
I. 位置:类以内,方法以外,被static修饰
II. 创建静态内部类的对象,需要依赖于外部类类名来创建:
Outer.Inner inner=new Outer.Inner();
III.静态内部类中静态成员可以直接通过类名访问:
Outer.Inner.静态属性名
Outer.Inner.静态方法名(实际参数);
IV. 静态内部类只能直接访问外部类的静态成员(静态属性和静态方法)
package demo2017114;
/*
* 静态内部类
*/
public class TestJingTaiNeiBuclass {
public static void main(String[] args) {
OuterStatic.InnerStatic in = new OuterStatic.InnerStatic();
System.out.println(OuterStatic.InnerStatic.b); // 访问静态内部类静态成员可以直接:外部类类名.内部类类名.静态成员名
in.innerStatic();
}
}
class OuterStatic {
static int a = 10;
static class InnerStatic {
int a = 11;
static int b = 12;
public void innerStatic() {
System.out.println(a);
System.out.println(OuterStatic.a); // 静态内部类只能访问外部类的静态成员
}
}
}
I. 位置:定义在方法以内
II.创建局部内部类的对象:必须在定义它的方法内部创建。
III. 局部内部类可以直接访问外部类的私有属性
Iv. 局部内部类可以访问定义它的方法中的局部变量,但是要求局部变量必须加 final(java语法规定)。
解释:局部变量的生命周期和对象的生命周期不一致,为了让对象访问
的内容生命周期和自身一致,所以要求局部变量加final,存储在
常量池中。
V. 接口公开,接口的实现类定义为局部内部类隐藏,实现强制弱耦合。
package demo2017114;
/*
* 局部内部类(类比局部变量)
*/
public class TestJuBuInnerClass {
public static void main(String[] args) {
OuterJuBu ou = new OuterJuBu();
ou.juBu();
}
}
class OuterJuBu {
private static int a = 1;
int b = 55;
public void juBu() {
final int b = 5; // 局部变量
class InnerJuBu { // 局部内部类
int a = 100;
public void inner() {
System.out.println(OuterJuBu.this.a); // 局部内部类可以直接访问外部类的私有属性
System.out.println(OuterJuBu.this.b); // 访问外部类的属性
System.out.println(b); // 访问外部类的的局部变量要被final修饰
}
}
InnerJuBu in = new InnerJuBu();
in.inner();
}
}
I. 匿名内部类是一个特殊的局部内部类
II. 匿名内部类必须实现一个接口或是继承一个类。
III.只能创建该类的一个对象。
interface IA{
void m1();
}
匿名内部类:
IA ia=new IA(){
public void m1(){}
};
IV. 匿名内部类的缺点:可读性低
匿名内部类的优点:减少代码量。
package demo2017114;
/*
* 匿名内部类
*/
public class TestNiMingNeiBuClass{
public static void main(String[] args) {
Jiekou jj=new Jiekou(){
public void method(){
System.out.println("666");
}
};
jj. method();
}
}
interface Jiekou{
public abstract void method();
}