您当前的位置:首页 > 互联网教程

java内部类,匿名内部类这些是什么求详细用法,还有语法。

发布时间:2025-05-21 20:24:59    发布人:远客网络

java内部类,匿名内部类这些是什么求详细用法,还有语法。

一、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、典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。