终于看到内部类了,感觉很乱,什么类的内部可以定义其它的类,函数内也可以定义类。感觉语法还可以理解,但不明白我们为什么需要内部类?
像类的继承,或类中引用其它类,这我能理解我们在工作中确实需要这些技巧,但在看内部类时,除了感觉到规则很麻烦外,没有觉得它的必要性,所以在这里向各位讨教,谁能给我举个例子,我们为什么需要内部类。
谢谢

解决方案 »

  1.   

       比如,如果你需要做一个链表的数据结构,你需要两个类,一个类是LinkedList,一个是LinkedNode,确实可以放在两个类文件中,但是这种关系密切的类,如果让LinkedNode放入LinkedList作为其内部类,不仅可以很方便的让用户去用,如果你将LinkedNode的声明成private,那么这个类只有LinkedList可以访问,别人不能访问,起到了保护作用,因为LinkedNode也每笔要被别访问。
      

  2.   

    主要有三个原因:
    a、内部类方法可以访问该类定义所在作用域中的数据,包括私有数据成员。
    b、内部类可以对同一包中的其他类隐藏起来;
    c、当想要定义一个回调函数而不想写太多代码时,使用内部类比较便捷。内部类是一种编译时概念,与虚拟机无关,编译器会将内部类翻译成用$分隔外部类名与内部类名的常规文件。而编译器将一无所知。
      

  3.   

    内部类的例子有很多如可以在实现一个线程的内部类import java.awt.Color;
    import java.awt.Font;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;/**
     * 这个类代表贪吃蛇的活动场所
     * @author bjsxt
     * @version 1.0
     */
    public class Yard extends Frame { PaintThread paintThread = new PaintThread();
    private boolean gameOver = false; //游戏是否结束

    /**
     * 行数
     */
    public static final int ROWS = 30;
    public static final int COLS = 30;
    public static final int BLOCK_SIZE = 15;

    private Font fontGameOver = new Font("宋体", Font.BOLD, 50);

    private int score = 0;

    Snake s = new Snake(this);
    Egg e = new Egg();

    Image offScreenImage = null;

    public void launch() {
    this.setLocation(200, 200);
    this.setSize(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
    this.addWindowListener(new WindowAdapter() { @Override
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }

    });
    this.setVisible(true);
    this.addKeyListener(new KeyMonitor());

    new Thread(paintThread).start();
    }

    public static void main(String[] args) {
    new Yard().launch();
    }

    public void stop() {
    gameOver = true;
    }

    @Override
    public void paint(Graphics g) {
    Color c = g.getColor();
    g.setColor(Color.GRAY);
    g.fillRect(0, 0, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
    g.setColor(Color.DARK_GRAY);
    //画出横线
    for(int i=1; i<ROWS; i++) {
    g.drawLine(0, BLOCK_SIZE * i, COLS * BLOCK_SIZE, BLOCK_SIZE * i);
    }
    for(int i=1; i<COLS; i++) {
    g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * ROWS);
    }

    g.setColor(Color.YELLOW);
    g.drawString("score:" + score, 10, 60);

    if(gameOver) {
    g.setFont(fontGameOver);
    g.drawString("游戏结束", 120, 180);

    paintThread.pause();
    }

    g.setColor(c);

    s.eat(e);
    e.draw(g);
    s.draw(g);


    }

    @Override
    public void update(Graphics g) {
    if(offScreenImage == null) {
    offScreenImage = this.createImage(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
    }
    Graphics gOff = offScreenImage.getGraphics();
    paint(gOff);
    g.drawImage(offScreenImage, 0, 0,  null);
    }

    private class PaintThread implements Runnable {
    private boolean running = true;
    private boolean pause = false;
    public void run() {
    while(running) {
    if(pause) continue; 
    else repaint();

    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    public void pause() {
    this.pause = true;
    }

    public void reStart() {
    this.pause = false;
    s = new Snake(Yard.this);
    gameOver = false;
    }

    public void gameOver() {
    running = false;
    }

    }

    private class KeyMonitor extends KeyAdapter { @Override
    public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    if(key == KeyEvent.VK_F2) {
    paintThread.reStart();
    }
    s.keyPressed(e);
    }

    }

    /**
     * 拿到所得的分数
     * @return 分数
     */

    public int getScore() {
    return score;
    }

    /**
     * 设置所得的分数
     * @param score 分数
     */

    public void setScore(int score) {
    this.score = score;
    }}
    这是贪吃蛇的背景类,里面用内部类来实现一个线程
    不过总的设计还是应该向2楼说的那样
      

  4.   

    1.内部类可以很好的实现隐藏
      一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
    2.内部类拥有外围类的所有元素的访问权限
    3.可是实现多重继承
    4.可以避免修改接口而实现同一个类中两种同名方法的调用。另外,还有匿名内部类,在事件监听中常用的
      

  5.   

    举个例子:使用swing或者AWT设计界面的时候,给按钮什么的增加监听器一般就使用内部类来实现
      

  6.   

    简单的说:内部类:可以方便的访问包装类的方法和它的成员变量。不便被别的类访问,只为包装类服务。写一个小例子希望对LZ有帮助import java.awt.Button;
    import java.awt.FlowLayout;
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.TextField;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowEvent;
    class TFFrame extends Frame{
    TextField num1,num2,num3;
    public void launchFrame()
    {
    num1=new TextField(10);
    num2=new TextField(10);
    num3=new TextField(10);
    Label lblPlus=new Label("+");
    Button btnEqual=new Button("=");
    btnEqual.addActionListener(new MyMonitor());
    this.setLayout(new FlowLayout());
    this.add(num1);
    this.add(lblPlus);
    this.add(num2);
    this.add(btnEqual);
    this.add(num3);

    this.pack();
    this.setVisible(true);

    }
    //内部类,(方便的)可以直接访问包装类的成员变量和方法.不准许不需要其他类访问。
    private class MyMonitor implements ActionListener
    {
    public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub
    int n1=Integer.parseInt(num1.getText());
    int n2=Integer.parseInt(num2.getText());
    num3.setText(""+(n1+n2));
    }

    }

    }public class Test {
    public static void main(String[] args) {
    new TFFrame().launchFrame();
    }
    }
    以上代码如果不用内部类 import java.awt.Frame;
    import java.awt.*;class TFFrame extends Frame{
    TextField num1,num2,num3;
    public void launchFrame()//把Frame运行以来
    {
    TextField num1=new TextField(10);
    TextField num2=new TextField(10);
    TextField num3=new TextField(15);
    Label lblPlus=new Label("+");
    Button btnEqual=new Button("=");
    btnEqual.addActionListener(new MyMonitor(this));
    this.setLayout(new FlowLayout());
    this.add(num1);
    this.add(lblPlus);
    this.add(num2);
    this.add(btnEqual);

    this.add(num3);
    this.pack();
    this.setVisible(true);

    }
    public static void main(String[] args) {
    new TFFrame().launchFrame();
    }
    }
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.*;
    class MyMonitor implements ActionListener{ TFFrame tff=null;
    public MyMonitor(TFFrame tff)
    {
    this.tff=tff;
    }
    public void actionPerformed(ActionEvent e) {

    int n1=Integer.parseInt(tff.num1.getText());
    int n2=Integer.parseInt(tff.num2.getText());
    tff.num3.setText(" "+(n1+n2));

    }}
    可以看出MyMonitor这个类完全是为TFFrame服务的
      

  7.   

    内部类,是一种保护对象,和对可信任对象公开本对象的一种方法。
    如果我们想方便访问某个类中的信息,我们可以选择:
    1持有对方引用
    2内部类
    很常见的就说说2方法:
    常见的就是做GUI时,我们某个窗体Frame添加监听器时,我们对不同的窗体的监听器是不同的,没有必要共享,只要这个Frame能用就可以了,这时经常将监听器
    Listener定义成内部类,结构如下:class WindowFrame extends Frame {
            public void launchFrame(){
                     this.set
                     this.addWindowListener(new WListener());
            }        private class WListener implements WindowListener {        }
    }
      

  8.   

    java中内部类用的比较频繁
    比如我们编写Applet小应用程序的时候,需要用到监听器,而有时候我们不需要实现特定接口中所有的方法,只要继承某个实现类,重写其中需要用到的方法即可,这时可以用内部类的方式
    例如:
    Frame f=new Frame("accp");
    f.addWindowListener(new WindowAdapter()
                        {
    public void windowClosing(WindowEvent arg0) {
    // TODO Auto-generated method stub
    System.exit(0);
    }
                         });