java匿名内部类详解-java 类加载详解
前言
当我们描述事物的时候java匿名内部类详解,事物内部是有事物的,当内部事物需要访问外部事物中的内容时。 那么,这个内部的东西就可以用一个内部类来描述了。 内部类也称为内置类、嵌套类。
文本
一、内部类的形式和外部访问的方式
顾名思义,内部类是嵌套在另一个类中的一个类。 内部类可以在外部类的成员位置,也可以在外部类的局部位置,即成员函数中。
一般我们在定义内部类时,将其访问权限设置为private,在外部类中提供访问的方法。 让我们看一个例子:
package com.jimmy.basicInnerClass;
class OuterClass{ // 外部类
private int num = 5; // 外部类的成员变量
private class InnerClass{ // 私有的内部类,定义在外部类的成员位置
public void innerMethod() { // 内部类的成员方法
System.out.println("你好啊,我是内部类的方法.."+num); // 内部类可直接访问外部类的成员
}
}
public void outerMethos() { // 外部类方法,实例化内部类对象,并调用其方法
OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
innerClass.innerMethod();
}
}
public class InnerClassDemo1 {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.outerMethos(); // 通过外部类方法访问内部类成员,就像get方法访问私有成员变量一样。
}
}
以上代码的输出:
你好啊,我是内部类的方法..5
值得注意的是,外部类也是一个完整的类,编译时也会生成一个class文件。 上面的文件会生成3个类文件。 内部类的名字比较特殊,会标明自己所属的外部类的名字。
OuterClass.class
OuterClass$InnerClass.class
InnerClassDemo1.class
在上面的代码中,我们直接在外部类的方法中创建了内部类对象,并调用了内部类的方法,这样就显得有点大材小用了。 我们要获取内部类的对象来调用内部类中的方法。 但是,内部类是私有的,我们不能直接new出内部类对象。 虽然可以用“new Outer().new Inner()”来实例化内部类对象,但是没有可用的对象名来接收它(因为内部类对外界是不可见的)。 如何解决? 我们知道内部类也是类,它也具有类的继承特性,所以我们从外部类继承一个内部类,或者实现一个外部接口,然后通过多态接收内部类对象。 代码如下:
package com.jimmy.basicInnerClass;
interface Inter{ // 外部接口
public void innerMethod();
}
class Outer3{
private int num = 5;
private class Inner implements Inter{ // 内部类实现接口,并实现其中的方法。
@Override
public void innerMethod() {
System.out.println("你好啊,我是内部类的方法...."+num);
}
}
public Inner getInnerObject() { // 外部类函数只返回内部类对象,并不越俎代庖去调用方法
return new Inner();
}
}
public class InnerClassDemo5 {
public static void main(String[] args) {
Outer3 outer3 = new Outer3();
Inter innerObject = outer3.getInnerObject(); // 私有的内部类对象可以用多态性来接收
innerObject.innerMethod();
}
}
上述代码的输出如下:
你好啊,我是内部类的方法....5
这样私有化的内部类对象就可以通过多态的方式被外部持有,也符合java中“面向接口编程”的要求。
二、匿名内部类
从上面的代码可以看出,内部类在外部类内部java匿名内部类详解,可以实现外部接口,然后实现接口中的方法。 有时,对外接口中的某些实现只使用一次,因此无需编写类来实现该接口。 可以以匿名内部类的形式实现。 匿名内部类在外部类的本地位置,即方法中。
匿名内部类必须从父类继承或实现接口。 匿名内部类实际上是一个带有内容的子类对象,格式为:new interface/parent class(){subclass content}。 这种格式比较新。 一般来说,我们会以“;”结尾在“new Object();”之后。 现在new Object(){}后面跟着一对“{}”,说明这是一个子类结构,接口的实现写在里面。 看一个例子:
package com.jimmy.basicInnerClass;
interface InterInner{ // 外部接口以及方法
void innerMethod1();
void innerMethod2();
}
class Outer2{
private int num = 1;
public void outerMethod(){
new InterInner() { // 这就是匿名内部类,大括号里面是接口的实现
@Override
public void innerMethod1() { // 实现方法1
System.out.println("你好,我是匿名内部类的方法1..."+num);
}
@Override
public void innerMethod2() { // 实现方法2
// TODO Auto-generated method stub
System.out.println("你好,我是匿名内部类的方法2..."+num+1);
}
}.innerMethod1(); // new出对象,就能调用函数
}
}
public class InnerClassDemo4 {
public static void main(String[] args) {
Outer2 outer2 = new Outer2();
outer2.outerMethod();
}
}
上面的代码在匿名内部类的对象new之后直接调用实现的方法。 代码输出:
你好,我是匿名内部类的方法1...1
我们也可以提供一个匿名内部类的对象,对外调用匿名内部类的方法。 代码如下:
package com.jimmy.basicInnerClass;
interface InterInner2{ // 外部接口以及方法
void innerMethod1();
void innerMethod2();
}
class Outer4{
private int num = 1;
public InterInner2 outerMethod(){
InterInner2 inner2 = new InterInner2() { // 接收匿名内部类对象,大括号里面是接口的实现
@Override
public void innerMethod1() { // 实现方法1
System.out.println("你好,我是匿名内部类的方法1..."+num);
}
@Override
public void innerMethod2() { // 实现方法2
// TODO Auto-generated method stub
System.out.println("你好,我是匿名内部类的方法2..."+(num+1));
}
};
return inner2;
}
}
public class InnerClassDemo4_1 {
public static void main(String[] args) {
Outer4 outer4 = new Outer4();
InterInner2 inner2 = outer4.outerMethod();
inner2.innerMethod1();
inner2.innerMethod2();
}
}
代码输出为:
你好,我是匿名内部类的方法1...1
你好,我是匿名内部类的方法2...2
3.匿名内部类的常见用法
匿名内部类只是接口的一个实现和调用,用完了会被回收。 它的使用可以如上,将匿名内部类放在外部类的方法中,在外部调用外部类的方法,得到内部类对象再调用内部类的方法。 如果内部类不需要访问外部类的成员变量,可以直接放在main方法中。 例如:
package com.jimmy.niMingInnerClass;
interface movable{
public void run();
}
public class NimingInnerClassDemo1 {
public static void main(String[] args) {
new movable() {
@Override
public void run() {
System.out.println("i am running...");
}
}.run();
}
}
输出结果:
i am running...
实践中使用了很多匿名内部类。 常见的一种是在创建线程时使用匿名内部类,如下例所示:
package com.jimmy.niming;
public class NiMingNeibuleiTest {
public static void main(String[] args) {
new Thread(new Runnable() { // 线程1
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}).start();
new Thread(new Runnable() { // 线程2
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}).start();
}
}
输出结果:
2个线程交替执行
总结
只学习了内部类和外部调用方式的形式,以及匿名内部类如何简化代码。 内部类的好处我不是很了解,以后在编程学习的过程中慢慢体会。