Java 内部类

要用到内部类:

在java开发学习中我们经常会碰到内部类。定义:内部类是定义在一个类中的类。

优点:

  1. 内部类方法可以访问该类定义所在的作用域中的数据。
  2. 内部类对同一个包中的其他类隐藏起来。
  3. 想要定义一个回调函数时,使用匿名内部类 比较便捷。

内部类又有很多的优势:首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法名称参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。不过你可能要质疑,更改一下方法的不就行了吗?的确,以此作为设计内部类的理由,实在没有说服力。

真正的原因是这样的,java中的内部类和接口加在一起,从而java 通过内部类加上接口,可以很好的实现多继承的效果。
 

内部类的分类和使用

1、成员内部类: 即作为外部类的一个成员存在,与外部类的属性、方法并列。注意:成员内部类中不能定义静态变量,但可以访问外部类的所有成员。

值得注意的是成员内部类编译成功后会生成的两个不同的类(.class)

成员内部类的优点:

  1. 内部类作为外部类的成员,可以访问外部类的私有成员或属性。(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的。)
  2. 用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class InnerClassTest
{
    public static void main(String[] args)
    {
        TalkingClock clock = new TalkingClock(1000, true);
        clock.start();

        // keep program running until user selects "Ok"
        JOptionPane.showMessageDialog(null, "Quit program?");
        System.exit(0);
    }
}

/**
 * A clock that prints the time in regular intervals.
 */
class TalkingClock
{
    private int interval;
    private boolean beep;

    /**
     * Constructs a talking clock
     * @param interval the interval between messages (in milliseconds)
     * @param beep true if the clock should beep
     */
    public TalkingClock(int interval, boolean beep)
    {
        this.interval = interval;
        this.beep = beep;
    }

    /**
     * Starts the clock.
     */
    public void start()
    {
        ActionListener listener = new TimePrinter();
        Timer t = new Timer(interval, listener);
        t.start();
    }

    public class TimePrinter implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            Date now = new Date();
            System.out.println("At the tone, the time is " + now);
            if (beep) Toolkit.getDefaultToolkit().beep();
        }
    }
}

 

2、局部内部类: 即在方法中定义的内部类,与局部变量类似,在局部内部类前不加修饰符public或private,其范围为定义它的代码块。

优点:对外部世界可以完全隐藏起来!只有start方法知道它的存在。

上面的例子中,TimePrinter这个类只在start中用了一次。这种情况,我们可以定义局部类。

    public void start()
    {
	     class TimePrinter implements ActionListener
	    {
		        public void actionPerformed(ActionEvent event)
		        {
		            Date now = new Date();
		            System.out.println("At the tone, the time is " + now);
		            if (beep) Toolkit.getDefaultToolkit().beep();
		        }
	    }
	     ActionListener listener = new TimePrinter();
	     Timer t = new Timer(interval, listener);
	     t.start();
    }

 

3、静态内部类: 有时只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类的对象。此时,声明为static ,以便取消产生的引用。注意:静态内部类中可以定义静态或者非静态的成员

public class StaticInnerClassTest
{
    public static void main(String[] args)
    {
        double[] d = new double[20];
        for (int i = 0; i < d.length; i++)
            d[i] = 100 * Math.random();
        ArrayAlg.Pair p = ArrayAlg.minmax(d);
        System.out.println("min = " + p.getFirst());
        System.out.println("max = " + p.getSecond());
    }
}

class ArrayAlg
{
    public static class Pair
    {
        private double first;
        private double second;
        
        public Pair(double f, double s)
        {
            first = f;
            second = s;
        }

        public double getFirst()
        {
            return first;
        }
        
        public double getSecond()
        {
            return second;
        }
    }

    public static Pair minmax(double[] values)
    {
        double min = Double.MAX_VALUE;
        double max = Double.MIN_VALUE;
        for (double v : values)
        {
            if (min > v) min = v;
            if (max < v) max = v;
        }
        return new Pair(min, max);
    }
}

 

4、匿名内部类: 匿名内部类是在抽象类和接口的基础之上发展起来的。

匿名内部类如果继承自接口,必须实现指定接口的方法,且无参数 。匿名内部类如果继承自类,参数必须按父类的构造函数的参数传递

匿名内部类的特点:

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

匿名类与内部的联系与区别:

按所在位置可以分为两大类:
1、在类的方法中
特点:
a、可以访问宿主类的所有元素 ;
b、保存宿主类对象的引用,创建对象时必须有宿主类对象;
c、 不能有静态数据;
继续划分:
A、本地内部类;
B、匿名内部类
两者的区别在于本地内部类有构造方法,而匿名内部类只能实例初始化;
2、在类或接口作用域中;
A、普通内部类
B、静态内部类

内部类总结:
1.内部类作为外部类的一个特殊的成员来看待,因此它有类成员的封闭等级:private ,protected,默认(friendly),public 它有类成员的修饰符: static,final,abstract
2.非静态内部类nested inner class,内部类隐含有一个外部类的指针this,因此,它可以访问外部类的一切资源(当然包括private)外部类访问内部类的成员,先要取得内部类的对象,并且取决于内部类成员的封装等级。非静态内部类不能包含任何static成员.
3.静态内部类:static inner class,不再包含外部类的this指针,并且在外部类装载时初始化. 静态内部类只能访问外部类static成员. 外部类访问静态内部类的成员:static成员:类名.成员;非static成员:对象.成员
4.对于方法中的内部类或块中内部类只能访问块中或方法中的final变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值