java内部类,匿名内部类这些是什么求详细用法,还有语法。
发布时间:2025-05-21 20:24:59 发布人:远客网络
一、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、局部内部类:局部内部类定义在外部类的某个代码块或方法块中。如果只会在某个方法或块中创建这个类的对象,就可以使用局部内部类。
3、匿名内部类:匿名内部类一般定义在需要传递接口或回调的的地方,一个匿名内部类一定是在new的后面,用其隐含实现一个接口或继承一个类。假如只需要创建这个类的一个对象不需要知道其实际类型(不需要使用到类名),那么就可以使用匿名内部类。
4、静态内部类:和成员内部类一样,作为外部类的一个成员存在,与外部类的属性、方法并列,只不过在声明类的时候加入了static关键字。有时候,使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象。这时可以使用静态内部类,以便取消产生对外部类的引用。
三、什么是内部类
1、内部类分为:成员内部类、静态嵌套类、方法内部类、匿名内部类。(1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。(2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。(3)、内部类声明成静态的,就不能随便的访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。
2、class Outer{ class Inner{}}编译上述代码会产生两个文件:Outer.class和Outer$Inner.class。
3、把类放在方法内 class Outer{ public void doSomething(){ class Inner{ public void seeOuter(){}}}}(1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。(2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。下面是完整的例子: class Outer{ public void doSomething(){ final int a=10; class Inner{ public void seeOuter(){ System.out.println(a);}} Inner in= new Inner(); in.seeOuter();} public static void main(String[] args){ Outer out= new Outer(); out.doSomething();}}
4、顾名思义,没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字。匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:·只用到类的一个实例。·类在定义后马上用到。·类非常小(SUN推荐是在4行代码以下)·给类命名并不会导致你的代码更容易被理解。在使用匿名内部类时,要记住以下几个原则:·匿名内部类不能有构造方法。·匿名内部类不能定义任何静态成员、方法和类。·匿名内部类不能是public,protected,private,static。·只能创建匿名内部类的一个实例。·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。 A、继承式的匿名内部类 public class Car{ public void drive(){ System.out.println("Driving a car!");} public static void main(String[] args){ Car car= new Car(){ public void drive(){ System.out.println("Driving anther car!");}}; car.drive();}}结果输出了:Driving another car! Car引用变量不是引用Car对象,而是Car匿名子类的对象。 B、接口式的匿名内部类。 interface Vehicle{ public void drive();} class Test{ public static void main(String[] args){ Vehicle v= new Vehicle(){ public void drive(){ System.out.println("Driving a car!");}}; v.drive();}}上面的代码很怪,好像是在实例化一个接口。事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类。而且只能实现一个接口。 C、参数式的匿名内部类。 class Bar{ void doStuff(Foo f){}} interface Foo{ void foo();} class Test{ static void go(){ Bar b= new Bar(); b.doStuff(new Foo(){ public void foo(){ System.out.println("foofy");}});}}
5、静态内部类中可以定义静态或者非静态的成员。从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部,因此也被称为顶级嵌套类。静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类不能访问外部类的成员和方法。 class Outer{ static class Inner{}} class Test{ public static void main(String[] args){ Outer.Inner n= new Outer.Inner();}}
6、典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。