黑马程序员-java内部类
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
概念:
java中将一个类定义在另一个类的里面,对于里面的那个类我们就成为内部类,也叫做内置类或嵌套类。
此外注意Java中的接口也可以被定义成内部形式。
理解:
其实java内部类和普通的类没有什么区别,只是它定义的位置发生了改变,它的出现是为了能够更具体的描述事物,更加形象的去描述事物之间的关系。也正是因为它可以定义在类的内部,它才具备了与普通类相比没有的修饰符。比如private可以修饰一个内部类,当内部类在局部位置时,还可以被static修饰。
内部类访问特点:
1.内部类可以直接访问外部类的member(成员),包括私有成员。
2.外部类要访问内部类成员,必须先建立内部类对象。
代码示例:
1.内部类访问特点
<span style="font-size:14px;">package junit.test;
class Outer {
private int num;
class Inner{
public void show(){
//内部类可以直接访问外部类中的所有成员。因为在num前面省略了 外部类.this 关键字。
System.out.println(num);
}
}
public void method(){
//外部类访问内部类成员时,需要建立内部类对象。
Inner inner=new Inner();
inner.show();
}
}</span>
2.内部类的修饰符
<span style="font-size:14px;">package junit.test;
class Outer {
private static int num;
//内部类可以被static、private 等一切可以修饰成员的关键字修饰,前提是内部类在成员位置。
class Inner{
public void show(){
System.out.println(num);
}
/*
* 如果内部类中存在静态成员,那么该内部类也必须被static修饰。
* public static void method(){
}*/
}
public void method(){
Inner inner=new Inner();
inner.show();
}
}
class OuterTest{
public static void main(String[] args){
//如何创建内部类实例,内部类没有被static修饰。
Outer.Inner inner=new Outer().new Inner();
inner.show();
//当内部类在局部位置且被static修饰时
//Outer.Inner inner=new Outer.Inner();
//inner.show();
//当内部类被静态修饰,且要调用的方法也是静态时。
// Outer.Inner.show();
}
}</span>
3. 局部内部类访问局部变量
<span style="font-size:14px;">package junit.test;
class Outer {
private int num;
public void method(){
//当局部内部类访问了外部类中的局部变量时,该变量必须被final修饰。这是java中的规定。
final int x=0;
//局部内部类
class Inner{
public void show(){
System.out.println(x);
}
}
}
}</span>
为什么局部内部类在访问外部局部变量时,该变量需要被final修饰?
我们首先分析一下,设方法f被调用,从而在它的调用栈中生成了变量x,此时产生了一个局部内部类对象inner_object,它访问了该局部变量x .当方法f()运行结束后,局部变量i就已死亡了,不存在了.但局部内部类对象inner_object还可能一直存在(只能没有人再引用该对象时,它才会死亡),它不会随着方法f()运行结束死亡.这时:出现了一个"荒唐"结果:局部内部类对象inner_object要访问一个已不存在的局部变量x!所以设计者为了避免上述情况发生,就将局部变量定义成final类型。如果不加final还会造成当外面的方法重新给局部变量赋值的时候,不影响内部类的局部变量指向的值,即外部的局部变量x值是A而匿名类的变量的值是B了,这才是不能接受的结果。因为从源程序上看它们是同一变量。(借鉴别人的)
4.匿名内部类(匿名内部类通常用在传入某些参数时,该参数是接口类型,并且该接口中方法不超过三个)
package junit.test;
//匿名内部类:内部类的简写格式。其实就是一个匿名子类。
//前提:内部类必须继承或实现一个外部类或接口。
abstract class Inter{
abstract void show();
}
class Outer {
private int num;
/* class Inner extends Inter{
@Override
void show() {
System.out.println(num);
}
}*/
public void method(){
//new Inner().show();
//采用匿名内部类格式
new Inter() {
@Override
void show() {
System.out.println(num);
}
}.show();
}
}
package junit.test;
//匿名内部类:内部类的简写格式。其实就是一个匿名子类。
//前提:内部类必须继承或实现一个外部类或接口。
interface Inter{
void show();
void show1();
}
class Outer {
private int num;
/* class Inner implements Inter{
@Override
void show() {
System.out.println(num);
}
void show1(){
}
}*/
public void method(){
//采用匿名内部类格式
new Inter() {
@Override
public void show() {
System.out.println(num);
}
@Override
public void show1() {
}
}.show();
}
}
总结:
1.内部类中有静态成员时,该内部类也要被static修饰。
2.局部内部类在访问局部变量时,该变量要被final修饰。
3.被static修饰的内部类不能访问外部类中的非静态成员。
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------