Java内部类

Java  内部类  
分四种:成员 内部类 、局部 内部类 、静态 内部类 和匿名 内部类 。 
1、成员 内部类 : 即作为外部类的一个成员存在,与外部类的属性、方法并列。
注意:成员 内部类 中不能定义 静态 变量 ,但可以访问外部类的所有成员。
public class Outer{
private static int i = 1;
private int j=10;
private int k=20;
public static void outer_f1(){
//do more something
}
public void out_f2(){
//do more something
}

//成员 内部类
class Inner{
//static int inner_i =100; // 内部类 中不允许定义 静态 变量
int j=100;// 内部类 中外部类的实例 变量 可以共存
int inner_i=1;
void inner_f1(){
System.out.println(i);//外部类的 变量 如果和 内部类 变量 没有同名的,则可以直接用 变量 名访问外部类的 变量
System.out.println(j);//在 内部类 中访问 内部类 自己的 变量 直接用 变量
System.out.println(this.j);//也可以在 内部类 中用"this. 变量 名"来访问 内部类 变量
//访问外部类中与 内部类 同名的实例 变量 可用"外部类名.this. 变量 名"。
System.out.println(k);//外部类的 变量 如果和 内部类 变量 没有同名的,则可以直接用 变量 名访问外部类的 变量
outer_f1();
outer_f2();
}
}
//外部类的非 静态方法 访问成员 内部类
public void outer_f3(){
Inner inner = new Inner();
inner.inner_f1();
}

//外部类的 静态方法 访问成员 内部类 ,与在外部类外部访问成员 内部类 一样
public static void outer_f4(){
//step1 建立外部 类对象
Outer out = new Outer();
//***step2 根据外部 类对象 建立内部 类对象 ***
Inner inner=out.new Inner();
//step3 访问 内部类 的方法
inner.inner_f1();
}

public static void main(String[] args){
outer_f4();
}
}
成员 内部类 的优点:
⑴  内部类 作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的 内部类 还是可见的。)
⑵ 用 内部类 定义在外部类中不可访问的属性。这样就在外部类 中实 现了比外部类的private还要小的 访问权 限。
注意: 内部类 是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的 内部类 。编译完成后出现outer.class和outer$inner.class两类。
2、局部 内部类 : 即在方法中定义的 内部类 ,与局部 变量 类似,在局部 内部类 前不加修饰符public或private,其范围为定义它的 代码块
注意:局部 内部类 中不可定义 静态 变量 ,可以访问外部类的局部 变量 (即方法内的 变量 ),但是 变量 必须是final的。
public class Outer {
private int s = 100;
private int out_i = 1;
public void f(final int k){
final int s = 200;
int i = 1;
final int j = 10;
class Inner{ //定义在方法内部
int s = 300;//可以定义与外部类同名的 变量
//static int m = 20;//不可以定义 静态 变量
Inner(int k){
inner_f(k);
}
int inner_i = 100;
void inner_f(int k){
System.out.println(out_i);//如果 内部类 没有与外部类同名的 变量 ,在 内部类 中可以直接访问外部类的实例 变量
System.out.println(k);//*****可以访问外部类的局部 变量 (即方法内的 变量 ),但是 变量 必须是final的*****
// System.out.println(i);
System.out.println(s);//如果 内部类 中有与外部类同名的 变量 ,直接用 变量 名访问的是 内部类 变量
System.out.println(this.s);//用"this. 变量 名" 访问的也是 内部类 变量
System.out.println(Outer.this.s);//用外部"外部类类名.this. 变量 名" 访问的是外部 变量
}
}
new Inner(k);
}

public static void main(String[] args) {
//访问局部 内部类 必须先有外部 类对象
Outer out = new Outer();
out.f(3);
}

}

注意:
在类外不可直接生成局部 内部类 (保证局部 内部类 对外是不可见的)。要想使用局部 内部类 时需要生成对象,对象调用方法,在方法中才能调用其局部 内部类 。通过 内部类 和接口达到一个强制的弱 耦合 ,用局部 内部类 来实现接口,并在方法中返回 接口类型 ,使局部 内部类 不可见,屏蔽实现类的 可见性

3、静态 内部类 : 静态 内部类 定义在类中,任何方法外,用static定义。
注意:静态 内部类 中可以定义静态或者非静态的成员
public class Outer {
private static int i = 1;
private int j = 10;
public static void outer_f1(){

}
public void outer_f2(){

}
// 静态 内部类 可以用public,protected,private修饰
// 静态 内部类 中可以定义静态或者非静态的成员
static class Inner{
static int inner_i = 100;
int inner_j = 200;
static void inner_f1(){
System.out.println("Outer.i"+i);//静态 内部类 只能访问外部类的 静态成员
outer_f1();//包括 静态 变量 静态方法
}
void inner_f2(){
// System.out.println("Outer.i"+j);//静态 内部类 不能访问外部类的非 静态成员
// outer_f2();//包括非 静态 变量 和非 静态方法


}

public void outer_f3(){
// 外部类访问 内部类 静态成员 内部类 . 静态成员
System.out.println(Inner.inner_i);
Inner.inner_f1();
// 外部类访问 内部类 的非 静态成员 :实例化 内部类 即可
Inner inner = new Inner();
inner.inner_f2();

}
public static void main(String[] args) {
new Outer().outer_f3();
}

}


注意:*******生成(new)一个静态 内部类 不需要外部类成员:这是静态 内部类 和成员 内部类 的区别。静态 内部类 的对象可以直接生成:
Outer.Inner in=new Outer.Inner();
而不需要通过生成外部 类对象 来生成。这样实际上使静态 内部类 成为了一个顶级类。静态 内部类 不可用private来进行定义。*******

例子:
对于两个类,拥有相同的方法:
class People
{
run();
}
class Machine{
run();
}
此时有一个robot类:
class Robot extends People implement Machine.
此时run()不可直接实现。
注意:当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用 内部类 来实现。用接口不能完全地实现多 继承 ,用接口配合 内部类 才能实现真正的多 继承

4、匿名 内部类  
匿名 内部类 是一种特殊的局部 内部类 ,它是通过匿名类实现接口。
IA被定义为接口。
IA I=new IA(){};

匿名 内部类 的特点:

1,一个类用于 继承 其他类或是实现接口,并不需要增加额外的方法,只是对 继承 方法的事先或是覆盖。
2,只是为了获得一个对象实例,不需要知道其实际类型。
3,类名没有意义,也就是不需要使用到。

public class Outer {
private static int i = 1;
private int j = 10;
public static void outer_f1(){

}
public void outer_f2(){

}
// 静态 内部类 可以用public,protected,private修饰
// 静态 内部类 中可以定义静态或者非静态的成员
static class Inner{
static int inner_i = 100;
int inner_j = 200;
static void inner_f1(){
System.out.println("Outer.i"+i);//静态 内部类 只能访问外部类的 静态成员
outer_f1();//包括 静态 变量 静态方法
}
void inner_f2(){
// System.out.println("Outer.i"+j);//静态 内部类 不能访问外部类的非 静态成员
// outer_f2();//包括非 静态 变量 和非 静态方法
}
}

public void outer_f3(){
// 外部类访问 内部类 静态成员 内部类 . 静态成员
System.out.println(Inner.inner_i);
Inner.inner_f1();
// 外部类访问 内部类 的非 静态成员 :实例化 内部类 即可
Inner inner = new Inner();
inner.inner_f2();

}
public static void main(String[] args) {
new Outer().outer_f3();
}

}

注:一个匿名 内部类 一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据 多态 ,我们使用其父类名。因他是局部 内部类 ,那么局部 内部类 的所有限制都对其生效。匿名 内部类 是唯一一种无 构造方法 类。大部分匿名 内部类 是用于接口回调用的。匿名 内部类 在编译的时候由系统自动 起名 Out$1.class。如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。因匿名 内部类 构造方法 ,所以其 使用范围 非常的有限。当需要多个对象时使用局部 内部类 ,因此局部 内部类 的应用相对比较多。匿名 内部类 中不能定义 构造方法 。如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。



________________________________________________________________________________



内部类 总结:
1.首先,把 内部类 作为外部类的一个特殊的成员来看待,因此它有类成员的封闭等级:private ,protected,默认(friendly),public
它有类成员的修饰符: static,final,abstract
2.非静态 内部类 nested inner class, 内部类 隐含有一个外部类的指针this,因此,它可以访问外部类的一切资源(当然包括private)
外部类访问 内部类 的成员,先要取得 内部类 的对象,并且取决于 内部类 成员的封装等级。
非静态 内部类 不能包含任何static成员.
3.静态 内部类 :static inner class,不再包含外部类的 this指针 ,并且在外部类装载时初始化.
静态 内部类 能包含static或非static成员.
静态 内部类 只能访问外部类static成员.
外部类访问静态 内部类 的成员,循一般类 法规 。对于static成员,用类名.成员即可访问,对于非static成员,只能
用对象.成员进行访问

4.对于方法中的 内部类 或块中 内部类 只能访问块中或方法中的final 变量


类成员有两种static , non-static,同样 内部类 也有这两种
non-static  内部类 的实例,必须在外部类的方法中创建或通过外部类的实例来创建(OuterClassInstanceName.new innerClassName(ConstructorParameter)),并且可直接访问外部类的信息,外部 类对象 可通过OuterClassName.this来引用
static  内部类 的实例, 直接创建即可,没有对外部类实例的引用。
内部类 不管static还是non-static都有对外部类的引用
non-static  内部类 不允许有static成员

方法中的 内部类 只允许访问方法中的final局部 变量 和方法的final参 数列 表,所以说方法中的 内部类 内部类 没什麽区别。但方法中的 内部类 不能在方法以外访问,方法中不可以有static 内部类
匿名 内部类 如果 继承 自接口,必须实现指定接口的方法,且无参数 
匿名 内部类 如果 继承 自类,参数必须按父类的 构造函数 参数传递
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值