Java 内部类种类及使用解析

为何要内部类?
    a、内部类提供了某种进入外围类的窗户。

b、也是最吸引人的原因,每个内部类都能独立地继承一个接口,而无论外围类是否已经继承了某个接口。

因此,内部类使多重继承的解决方案变得更加完整。

在项目中,需要多重继承,如果是两个接口,那么好办,接口支持多重继承。

如果是两个类呢?这时只有使用内部类了。

内部类Inner Class

  将相关的类组织在一起,从而降低了命名空间的混乱。

  一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。

  Java中的内部类共分为四种

  静态内部类static inner class (also called nested class)

  成员内部类member inner class

  局部内部类local inner class

  匿名内部类anonymous inner class

静态内部类Static Inner Class

  最简单的内部类形式。

  类定义时加上static关键字。

  不能和外部类有相同的名字。

  被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。

  只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。

  生成静态内部类对象的方式为:

  OuterClass.InnerClass inner = new OuterClass.InnerClass();

  静态内部类使用代码:

静态内部类使用测试

package com.learnjava.innerclass;

class StaticInner
{
    private static int a = 4;

    // 静态内部类
    public static class Inner
    {
        public void test()
        {
            // 静态内部类可以访问外部类的静态成员
            // 并且它只能访问静态的
            System.out.println(a);
        }

    }
}

public class StaticInnerClassTest
{

    public static void main(String[] args)
    {
        StaticInner.Inner inner = new StaticInner.Inner();
        inner.test();
    }
}

成员内部类Member Inner Class

  成员内部类也是定义在另一个类中,但是定义时不用static修饰。

  成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。

  成员内部类就像一个实例变量。

  它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以

  在外部类里面创建成员内部类的实例:

  this.new Innerclass();

  在外部类之外创建内部类的实例:

  (new Outerclass()).new Innerclass();

  在内部类里访问外部类的成员:

  Outerclass.this.member

  详情见代码例子:

class MemberInner
{
    private int d = 1;
    private int a = 2;

    // 定义一个成员内部类
    public class Inner2
    {
        private int a = 8;

        public void doSomething()
        {
            // 直接访问外部类对象
            System.out.println(d);
            System.out.println(a);// 直接访问a,则访问的是内部类里的a

            // 如何访问到外部类里的a呢?
            System.out.println(MemberInner.this.a);
        }

    }

}

public class MemberInnerClassTest
{

    public static void main(String[] args)
    {

        // 创建成员内部类的对象
        // 需要先创建外部类的实例
        MemberInner.Inner2 inner = new MemberInner().new Inner2();

        inner.doSomething();
    }
}

局部内部类Local Inner Class

  局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。

  像局部变量一样,不能被public, protected, private和static修饰。

  只能访问方法中定义的final类型的局部变量。

  局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。

class LocalInner
{
    int a = 1;

    public void doSomething()
    {
        int b = 2;
        final int c = 3;
        // 定义一个局部内部类
        class Inner3
        {
            public void test()
            {
                System.out.println("Hello World");
                System.out.println(a);

                // 不可以访问非final的局部变量
                // error: Cannot refer to a non-final variable b inside an inner
                // class defined in a different method
                // System.out.println(b);

                // 可以访问final变量
                System.out.println(c);
            }
        }

        // 创建局部内部类的实例并调用方法
        new Inner3().test();
    }
}

public class LocalInnerClassTest
{
    public static void main(String[] args)
    {
        // 创建外部类对象
        LocalInner inner = new LocalInner();
        // 调用外部类的方法
        inner.doSomething();
    }

}

匿名内部类Anonymous Inner Class

  匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。

  匿名内部类隐式地继承了一个父类或者实现了一个接口

  匿名内部类使用得比较多,通常是作为一个方法参数。

import java.util.Date;

public class AnonymouseInnerClass
{

    @SuppressWarnings("deprecation")
    public String getDate(Date date)
    {
        return date.toLocaleString();

    }

    public static void main(String[] args)
    {
        AnonymouseInnerClass test = new AnonymouseInnerClass();

        // 打印日期:
        String str = test.getDate(new Date());
        System.out.println(str);
        System.out.println("----------------");

        // 使用匿名内部类
        String str2 = test.getDate(new Date()
        {
        });// 使用了花括号,但是不填入内容,执行结果和上面的完全一致
            // 生成了一个继承了Date类的子类的对象
        System.out.println(str2);
        System.out.println("----------------");

        // 使用匿名内部类,并且重写父类中的方法
        String str3 = test.getDate(new Date()
        {

            // 重写父类中的方法
            @Override
            @Deprecated
            public String toLocaleString()
            {
                return "Hello: " + super.toLocaleString();
            }

        });

        System.out.println(str3);
    }
}

生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。

  Swing中使用内部类的例子如下:生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。

  Swing中使用内部类的例子如下:

package com.learnjava.innerclass;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;

public class SwingTest
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("JFrame");
        JButton button = new JButton("JButton");

        button.addActionListener(new ActionListener()
        {
            // new出来一个实现了ActionListener接口的类的实例

            @Override
            public void actionPerformed(ActionEvent arg0)
            {
                System.out.println("Hello World");

            }
        });

        //加入按钮
        frame.getContentPane().add(button);

        //设置关闭行为
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setSize(200, 200);

        frame.addWindowListener(new WindowAdapter()
        {
            //也可以使用继承了适配器类的匿名内部类
            @Override
            public void windowClosing(WindowEvent e)
            {

                System.out.println("Closing");
                System.exit(0);
            }
        });
        frame.setVisible(true);
    }

}

Java 内部类种类及使用解析

时间: 2024-11-05 04:08:51

Java 内部类种类及使用解析的相关文章

【转】Java 内部类种类及使用解析

Java 内部类种类及使用解析 内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Java中的内部类共分为四种: 静态内部类static inner class (also called nested class) 成员内部类member inner class 局部内部类local inner class 匿名内部类anonymous inner class 静态内部类Static

Java内部类的基本解析

内部类 内部类的基本概念 所谓的内部类也就是在一个类的内部进行其他类结构的嵌套操作. 为什么要使用内部类? 这就要引用一句十分著名的一本书叫<Think in java>中的一句名言了——每个内部类都能独立的继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都是没有影响的. 因为内部类拥着类的一些基本特征,所以在实际问题中我们会遇到一些接口无法解决或者难以解决的问题,此时我们可以使用内部类继承某个具体的或者抽象的类,间接解决类无法多继承引起的一系列问题. 内部类

Java内部类

本文是<Java核心技术 卷1>中第六章接口与内部类中关于内部类的阅读总结. Java中的内部类(inner class)是定义在另一个类内部的类.那么内部类有什么用呢?这里主要由三个内部类存在的原因: 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据.即,如果类A中定义了类B,那么类B可以访问类A中的数据,甚至是私有数据,但类A不能访问类B中的私有数据: 内部类可以对同一个包中的其他类隐藏起来.在一个包中,定义一个类时,即使不加上访问权限关键词,这个类也是包内其他类可访问的,不

【Java】Servlet 工作原理解析

Web 技术成为当今主流的互联网 Web 应用技术之一,而 Servlet 是 Java Web 技术的核心基础.因而掌握 Servlet 的工作原理是成为一名合格的 Java Web 技术开发人员的基本要求.本文将带你认识 Java Web 技术是如何基于 Servlet 工作,你将知道:以 Tomcat 为例了解 Servlet 容器是如何工作的?一个 Web 工程在 Servlet 容器中是如何启动的? Servlet 容器如何解析你在 web.xml 中定义的 Servlet ?用户的请

使用java自带的xml解析器解析xml

使用java自带的xml解析器解析xml,其实我不推荐,可以用Dom解析,或其他的方式,因为Java自带的解析器使用不但麻烦,且还有bug出现. 它要求,针对不同的xml(结构不同),必须写对应的handler处理类,而Dom解析可以写通用的方法(前提是要写出通用逻辑)来处理,开发比较快.下面上代码 1 //------------------ main point --------------------- 2 javax.xml.parsers.SAXParserFactory 3 publ

Java 内部类综述

摘要: 多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承.但有时候,我们确实是需要实现多重继承,而且现实生活中也真正地存在这样的情况,比如遗传:我们即继承了父亲的行为和特征也继承了母亲的行为和特征.可幸的是,Java 提供了两种方式让我们曲折地来实现多重继承:接口和内部类.事实上,实现多重继承是内部类的一个极其重要的应用.除此之外,内部类还可以很好的实现隐藏(例如,私有成员内部类).内部类共有四种类型,即成员内部类.静态内部类.

Java内部类:局部内部类(三)

Java内部类分为4个部分进行阐述,分别为概览.成员内部类.局部内部类和匿名内部类. 在本文中是Java内部类的局部内部类,主要讲局部内部类的概念和在使用局部内部的过程中,需要注意的一个细节. 1.局部内部类的概念 在一个类的方法内部定义另外一个类,那么另外一个类就称作为局部内部类. class OutterClass { void test() { class InnerClass//局部内部类 { } } } 在上述代码中,InnerClass定义在OutterClass的test方法的内部

Java内部类:匿名内部类(四)

Java内部类分为4个部分进行阐述,分别为概览.成员内部类.局部内部类和匿名内部类. 在本文中是Java内部类的匿名内部类,主要讲述匿名内部类的概念.匿名内部类的好处.匿名内部类的使用前提.和匿名内部类的应用场景. 1.匿名内部类的概念 没有类名的类就称作为匿名内部类 2.匿名内部类的好处 简化书写 3.匿名内部类的使用前提 必须存在继承或者实现关系才能使用 4.匿名内部类的应用场景 匿名内部类一般是用于实参 示例代码: package com.rk.innerclass; public cla

Java内部类小程序(成员内部类,静态内部类,匿名内部类)

1 /** 2 * 测试java内部类(成员内部类,静态内部类,匿名内部类) 3 * 局部内部类不常用,就不写了. 4 * @package :java05 5 * @author shaobn 6 * @Describe : 7 * @Time: 2015-9-6 下午8:32:38 8 */ 9 public class TestInner { 10 11 /** 12 * @author shaobn 13 * @Describe : 14 * @param args 15 * @Time