当前位置: 主页 > JAVA语言

java匿名内部类详解-java 类加载详解

发布时间:2023-02-09 11:19   浏览次数:次   作者:佚名

前言

当我们描述事物的时候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个线程交替执行

总结

只学习了内部类和外部调用方式的形式,以及匿名内部类如何简化代码。 内部类的好处我不是很了解,以后在编程学习的过程中慢慢体会。