Java内部类有几种
发布时间:2025-05-19 15:05:51 发布人:远客网络
一、Java内部类有几种
1、成员内部类:作为外部类的一个成员存在,与外部类的属性、方法并列。当某个类除了他的外部类,不会被其他类使用时应该选择使用成员内部类。
2、局部内部类:局部内部类定义在外部类的某个代码块或方法块中。如果只会在某个方法或块中创建这个类的对象,就可以使用局部内部类。
3、匿名内部类:匿名内部类一般定义在需要传递接口或回调的的地方,一个匿名内部类一定是在new的后面,用其隐含实现一个接口或继承一个类。假如只需要创建这个类的一个对象不需要知道其实际类型(不需要使用到类名),那么就可以使用匿名内部类。
4、静态内部类:和成员内部类一样,作为外部类的一个成员存在,与外部类的属性、方法并列,只不过在声明类的时候加入了static关键字。有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象。这时可以使用静态内部类,以便取消产生对外部类的引用。
二、java内部类,匿名内部类这些是什么求详细用法,还有语法。
内部类是定义在另一个类中的类,使用它的原因主要有3个:
内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据;
内部类可以对同一个包中的其他类隐藏以来;
当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
【举例:《Java核心技术(卷I)》,6.4节——内部类,程序清单6-6】
*Thisprogramdemonstratesanonymousinnerclasses.
publicstaticvoidmain(String[]args)
TalkingClockclock=newTalkingClock(1000,true);
//keepprogramrunninguntiluserselects"Ok"
JOptionPane.showMessageDialog(null,"Quitprogram?");
*Aclockthatprintsthetimeinregularintervals.
*@paramintervaltheintervalbetweenmessages(inmilliseconds)
*@parambeeptrueiftheclockshouldbeep
publicTalkingClock(intinterval,booleanbeep)
ActionListenerlistener=newTimePrinter();
Timert=newTimer(interval,listener);
publicclassTimePrinterimplementsActionListener
publicvoidactionPerformed(ActionEventevent)
System.out.println("Atthetone,thetimeis"+now);
if(beep)Toolkit.getDefaultToolkit().beep();
}
上述代码中,TimePrinter就是在TalkingClock类的内部定义的一个内部类,因此它可以访问外围类的数据域,包括interval和beep这种私有域。
上述代码中,TimePrinter就是在TalkingClock类的内部定义的一个内部类,因此它可以访问外围类的数据域,包括interval和beep这种私有域。
讨论匿名内部类之前,先看看局部内部类,它是在一个方法中定义的类。代码示例如下,这里将上例中的TimePrinter类放到了start()方法中进行定义:
publicvoidstart(intinterval,finalbooleanbeep)
classTimePrinterimplementsActionListener
publicvoidactionPerformed(ActionEventevent)
System.out.println("Atthetone,thetimeis"+now);
if(beep)Toolkit.getDefaultToolkit().beep();
ActionListenerlistener=newTimePrinter();
Timert=newTimer(interval,listener);
}
局部内部类不能用public或private访问说明符来声明,它的作用域被限定在声明这个局部内部类的块中。局部内部类可以对外部世界完全地隐藏起来。
局部内部类不能用public或private访问说明符来声明,它的作用域被限定在声明这个局部内部类的块中。局部内部类可以对外部世界完全地隐藏起来。
局部内部类不仅能访问其外围类,还可以访问局部变量,不过这些局部变量必须被声明为final,如上述代码中start()方法的参数beep所示。
将上面的局部内部类的代码修改一下,就可以定义一个匿名内部类,这种类没有类名。
publicvoidstart(intinterval,finalbooleanbeep)
ActionListenerlistener=newActionListener()
publicvoidactionPerformed(ActionEventevent)
System.out.println("Atthetone,thetimeis"+now);
if(beep)Toolkit.getDefaultToolkit().beep();
Timert=newTimer(interval,listener);
}
请参照局部内部类的代码,比较不同之处。TimePrinter这个类名被省略了,定义listener这个局部内部类时,在其后的new ActionListener()后面跟了一个大括号括起的语句块,也就是此匿名内部类的定义语句。匿名内部类除了具有内部类的优点外,还可以减少代码量。
请参照局部内部类的代码,比较不同之处。TimePrinter这个类名被省略了,定义listener这个局部内部类时,在其后的new ActionListener()后面跟了一个大括号括起的语句块,也就是此匿名内部类的定义语句。匿名内部类除了具有内部类的优点外,还可以减少代码量。
【内容有些多,但愿能帮到你^_^】
三、Java:关于外部类访问内部类成员的问题
1、\\外部类对象可以直接访问内部类对象的成员变量和方法
2、你使用的这个方法的旨意是用非静态的外部类实例化一个内部类对象,外部类能够访问成员内部类的成员变量和方法的唯一途径就是通过实例化一个外部类的对象,然后这个对象通过对象.makeInner()来new一个Inner in,此过程调用了Inner()这个内部类的构造函数。
3、其实你只是把顺序搞错了,编译时不回去运行你的函数方法,也就是代码中:
4、这个越权的函数并未去执行访问其所在类的内部类的成员函数:Inner();
5、且Outer并不是static,所以其只能实例化一个对象,然后对象.makeInner();这时处于运行时,此类的对象可以调用此类的内部类的成员方法和成员变量,自然可以调用Inner();
6、说的简单点:你使用makeInner()时一定是实例化一个Outer的对象了,不然你无法调用makeInner,对吧,运行makeInner时他一定是在Outer这个类的对象下运行的,Outer的对象是可以访问其内部类Inner的变量和方法的。所以说:makeInner()运行时你绝对已经创建了一个Outer的对象了。是这个对象的makeInner()在运行,而这个Outer的这个对象是可以访问Outer的内部类Inner的变量和方法的。编译并非运行,编译时Outer没有实例化对象,但makeInner()也没被调用运行,所以他编译时没有去访问内部类Inner的东东,等你运行时自然你已经实例化一个对象了,自然也就可以访问了~~~