Java中的四种内部类

内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。
(注意,这里的外部类就是最常见的普通类,只是为了对应于内部类,才说成是“内部类”)
内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。

一、成员内部类

成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
在成员内部类要引用外部类对象时,使用outer.this来表示外部类对象;
创建内部类对象,可以使用outer.inner obj = outerobj.new inner();

public class Outer { 
    public class Inner { 
        public void print(String str) { 
            System.out.println(str); 
        } 
    } 
 
    public Inner getInner() { 
        return new Inner(); 
    } 
  
    public static void main(String[] args) { 
        Outer outer = new Outer(); 
        Outer.Inner inner = outer.new Inner(); 
        inner.print("Outer.new"); 
 
        inner = outer.getInner(); 
        inner.print("Outer.get"); 
    } 
}

运行结果:
Outer.new
Outer.get

二、局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

class People{
    public People() {
         
    }
}
 
class Man{
    public Man(){
         
    }
     
    public People getWoman(){
        class Woman extends People{   //局部内部类
            int age =0;
        }
        return new Woman();
    }
}

注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

三、静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

class Outter {
    public Outter() {
         System.out.println("Outter constructor.");
    }
     
    static class Inner {
        public Inner() {
            System.out.println("Inner constructor.");             
        }
    }
}

public class Test {
    public static void main(String[] args)  {
        Outter.Inner inner = new Outter.Inner();
    }
}

运行结果:
Inner constructor.

四、匿名内部类

(一)定义

顾名思义,匿名内部类是没有名字的内部类。
因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。
使用匿名内部类有个前提条件:必须继承一个父类或实现一个接口。

(二)例子

例1:不使用匿名内部类来实现抽象方法

abstract class Person {
    public abstract void eat();
}
 
class Child extends Person {
    public void eat() {
        System.out.println("eat something");
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Child();
        p.eat();
    }
}

运行结果:eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用。
但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?
这个时候就可以考虑引入匿名内部类。

例2:匿名内部类的基本实现

abstract class Person {
    public abstract void eat();
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

运行结果:eat something

可以看到,我们直接将抽象类Person中的方法在大括号中实现了。这样便可以省略一个类的书写。
匿名内部类还能用于接口上。

例3:在接口上使用匿名内部类

interface Person {
    public void eat();
}
 
public class Demo {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

运行结果:eat something

匿名内部类最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或者实现Runnable接口。

例4:Thread类的匿名内部类实现

public class Demo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        t.start();
    }
}

运行结果:1 2 3 4 5

例5:Runnable接口的匿名内部类实现

public class Demo {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}

运行结果:1 2 3 4 5

(三)作用

1)一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是覆盖。
2)只是为了获得一个对象实例,不需要知道其实际类型。
3)类名没有意义,也就是不需要使用到。




更多内容请关注微信公众号


wechat.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java 内部类 分四种:成员内部类、局部内部类、静态内部类和匿名内部类。 1、成员内部类: 即作为外部类的一个成...
    ikaroskun阅读 1,253评论 0 13
  • 成员内部类 成员内部类作为外部类的成员,能够无条件访问外部类的变量,即使是private的,但是外部类不能直接访问...
    刘岳森阅读 436评论 0 0
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,779评论 18 399
  • 一、介绍 内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。内部类可以是静态static的,也可用...
    一只好奇的茂阅读 1,010评论 4 21
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,267评论 0 2