A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Java中的内部类,匿名类,外部类的用法,关系,及什么时候用?求详解!

6 个回复

倒序浏览
李娟 黑马帝 2011-12-22 09:16:31
沙发
01.import javax.swing.*;   
02.import java.awt.*;   
03.import java.awt.event.*;   
04.         
05.public class ThisClassEvent extends JFrame implements ActionListener{      
06.    public ThisClassEvent(){         
07.        setLayout(new FlowLayout());            
08.        JButton btn=new JButton("ok");  
09.        add(btn);  
10.        btn.addActionListener(this);   
11.    }      
12.    public void actionPerformed (ActionEvent e){   
13.     System.out.println("The OK button is clicked");  
14.    }      
15.    public static void main(String args[]){  
16.     ThisClassEvent frame = new ThisClassEvent();  
17.        frame.setTitle("自身类作为事件监听器");  
18.        frame.setLocationRelativeTo(null); // Center the frame   
19.        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
20.        frame.setSize(280, 100);  
21.        frame.setVisible(true);  
22.        new ThisClassEvent();   
23.    }   
24.}  
25.  
26.import java.awt.*;   
27.import java.awt.event.*;   
28.import javax.swing.*;   
29.        
30.public class OuterClassEvent extends JFrame{      
31.    public OuterClassEvent(){   
32.     setLayout(new FlowLayout());            
33.        JButton btn=new JButton("ok");  
34.        add(btn);  
35.        OuterClass btListener=new OuterClass();  
36.        btn.addActionListener(btListener);   
37.    }      
38.    public static void main(String args[]){   
39.     OuterClassEvent frame = new OuterClassEvent();  
40.        frame.setTitle("外部类作为事件监听器");  
41.        frame.setLocationRelativeTo(null); // Center the frame   
42.        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
43.        frame.setSize(280, 100);  
44.        frame.setVisible(true);  
45.        new ThisClassEvent();   
46.    }   
47.}      
48.class OuterClass implements ActionListener{   
49.    public void actionPerformed(ActionEvent e){   
50.     System.out.println("The OK button is clicked");  
51.    }   
52.}   
53.  
54.import java.awt.*;   
55.import java.awt.event.*;   
56.import javax.swing.*;   
57.        
58.class InnerClassEvent extends JFrame{     
59.    public InnerClassEvent(){   
60.     setLayout(new FlowLayout());            
61.        JButton btn=new JButton("ok");  
62.        add(btn);  
63.        OuterClass btListener=new OuterClass();  
64.        btn.addActionListener(btListener);   
65.    }  
66.    class InnerClass implements ActionListener{   
67.        public void actionPerformed (ActionEvent e){   
68.         System.out.println("The OK button is clicked");  
69.        }   
70.    }   
71.    public static void main(String args[]){   
72.     InnerClassEvent frame = new InnerClassEvent();  
73.        frame.setTitle("内部类作为事件监听器");  
74.        frame.setLocationRelativeTo(null); // Center the frame   
75.        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
76.        frame.setSize(280, 100);  
77.        frame.setVisible(true);  
78.        new ThisClassEvent();   
79.    }   
80.   
81.}  
82.  
83.import java.awt.*;   
84.import java.awt.event.*;   
85.import javax.swing.*;   
86.           
87.class AnonymousEvent extends JFrame{     
88.    public AnonymousEvent(){   
89.     setLayout(new FlowLayout());            
90.        JButton btn=new JButton("ok");  
91.        add(btn);      
92.        btn.addActionListener(   
93.            new ActionListener(){   //匿名内部类作为参数,new 一个lisenter实际上是创建了一个实现了这个listener的类   
94.                public void actionPerformed(ActionEvent e){   
95.                 System.out.println("The OK button is clicked");  
96.                }   
97.            }   
98.        );     
99.    }   
100.    public static void main(String args[]){   
101.     AnonymousEvent frame = new AnonymousEvent();  
102.        frame.setTitle("匿名内部类作为事件监听器");  
103.        frame.setLocationRelativeTo(null); // Center the frame   
104.        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
105.        frame.setSize(280, 100);  
106.        frame.setVisible(true);  
107.        new ThisClassEvent();   
108.    }   
109.}     
回复 使用道具 举报
李楠 黑马帝 2011-12-22 09:58:16
藤椅
java里没有多重继承,所以为了解决多重继承的问题,你可以在外围类里面实现很多接口,但是程序看起来并不美观,
那么内部类可以独立的继承一个接口,并且实现它,使用内部类实现了多重继承。
并且外围类不能多重继承类和抽象类,但是使用内部类可以在一个类内部多次继承类和抽象类。
内部类还可以多次实现同一个接口或者继承同一个类,但是实现方法不同,这是外部类不能实现的。
匿名内部类我感觉只是一种简化形式,它能让你的程序看起来简单美观。

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

回复 使用道具 举报
外部类不可以多次继承,内部类可以多次继承,匿名类就是为了优化代码,但是匿名类有很多知识点,你去看视频多学学吧。

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

回复 使用道具 举报
曾运 黑马帝 2011-12-22 10:32:38
报纸
内部类是指在一个A的类里嵌套着一个B类, 那么B类叫内部类,A类叫外部类
内部类和外部类表示的是一种逻辑关系,内部类作为外部类的成员,可以访问外部类的其他成员;
如:身体和心脏,我们可以建立一个 身体类 (外部类)和心脏类(内部类) 心脏类是身体类的
成员,心脏类可以访问身体类内的成员。

使用内部类 外部类可以表示他们之间的逻辑关系,简化代码书写,弊端是破坏了面向对象的封装性。

匿名类也是一种内部类,顾名思义:匿名类就是没名字的类,表示的是一个对象,没有引用指向它,这个
对象只使用一次。可以简化代码书写。

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

回复 使用道具 举报
内部类: 类中嵌套一个类. 内部类可以直接使用外部类中的成员,而不需要再创建对象

匿名类: 其实是内部类的简写, 但区别是:匿名内部类必须继承或实现一个接口
回复 使用道具 举报
陈帅雷 黑马帝 2011-12-22 12:42:24
7#
块代码的定义:简单来说就是处于一对{}之间的代码。
内部类的定义:处于另外一个类中的具有类型名称定义块代码。
匿名类的定义:已知父类或者接口标准的内部类,且不具有具体的类型名称的块代码。匿名类的实例创建必须使用new 父类名|接口名 ()来创建。)

一、命名内部类——用于临时创建实例或者类型,且该类型或实例需要控制是否允许使用该类的人调用
1-1:命名局部内部类
public class OutClass{
   public int f()
   {
   private class InnerClass
   {
   int i=10;
   }
   return new InnerClass().i;
   }
   public static void main(String[] args)
   {
   OutClass o=new OutClass();
   System.out.println(o.f());
   }
}

此例中对于使用OutClass的人来说,无需关注于InnerClass类的存在,只关注于f()函数具体的返回值;使用者无法访问InnerClass类的成员.
1-2:命名成员内部类

public class OutClass{
   public class InnerClass{
   int i=10;
   }
   public int f()
   {
   return new InnerClass().i;
   }
   public static void main(String[] args)
   {
   OutClass o=new OutClass();
   System.out.println(o.f());
   }
}
此例将简单内部类提升至成员等级,在此等级中,我们可以自由设定该内部类是允许OutClass使用者实例化InnerClass实例,如果为public 类型,则允许实例化,如果为private 类型,则不允许实例化(除开OutClass的成员方法将InnerClass类型的实例作为返回值返回)
1-3:命名内部类的实例化方法
public class OutClass{
   public class InnerClass{
   public InnerClass()
   {
   System.out.println("InnerClass construction start");
   }
   }
   //public static void test()
   //{
   // InnerClass ic=new InnerClass();//错误的实例化内部类
   //}
   //public static InnerClass ic=new InnerClass();//错误的实例化内部类
   public InnerClass ic=new InnerClass();
   public InnerClass test()
   {
   return new InnerClass();
   }
   public static void main (String[] args)
   {
   OutClass oc=new OutClass();
   OutClass.InnerClass ic=oc.new InnerClass();
   }

}
注意:此处的输出结果为:
InnerClass construction start
InnerClass construction start
原因是外部类实例化时,需要产生一个内部类InnerClass成员,因此会调用内部类的构造函数,所以会有第一条
InnerClass construction start
而当在主方法中实例化内部类时,也需要调用内部类的构造函数,因此产生了第二条
InnerClass construction start


内部类实例化的前提条件:内部类实例的存在,必须依赖于外部类实例的存在,也就是说,在没有实例化外部类的情况下,不允许产生内部类实例,同样的,由于静态方法及静态成员的存在必须依赖于包含该静态方法或该静态成员的类型的实例,所以内部类的实例不能存在于外部类的静态方法或静态成员中,同理,非静态的内部类也不能包含静态的成员。

二、匿名内部类——用于临时创建实例,且该实例不希望类的使用者关注
匿名内部类的存在前提有两种:1、已知该类型的父类 或者 2、已知该类型的接口标准
通常对于一个临时的实例,我们并不希望他被使用者关注,比如一个人类Person,我们在处理一些他的特例的时候——比如BlindMan类型的人,而这种类型并不常见,所以我们可以不需要实体创建BlindMan这个类型,而直接使用它的具体实例:
1-1:已知父类的匿名内部类
public class Test
{
   public void see()
   {
   Person p=new Person()
   {
   name="I";
   void r(){
   System.out.println(this.name+" can see nothing.");
   }
   };
   p.r();
   }
}
注意:由于此处的匿名类是创建p指针的具体膜板,必须在{}外添加";"号,表示是创建Person 实例的语句结束。

1-2:已知接口标准的内部类
interface IFly{
   void fly();
}
class Plan{
   public void run()
   {
   IFly f=new IFly()//使用匿名类创建飞机实例
   {
   public void fly()
   {
   System.out.println("Plan is flying");
   }
   };
   f.fly();
   }
}

三、静态内部类

静态内部类的出现主要是为了解决内部类的重复实例化问题,对于一个经常调用的内部类,在我们不需要关注其具体内容的时候,重复的多次出现会消耗大量资源,因此利用了静态类的特性——只需要实例化一次,产生了静态内部类,静态内部类中可以声明静态成员也可以存在非静态成员,且静态内部类遵循静态规则既:静态的方法或者类型,不能直接调用其外部的非静态成员。
需要注意的是 静态内部类的存在并不依赖于其外部类的实例,原因是普通类的实例化顺序是先静态成员,再成员变量初始化,再构造;由于在外部类实例化之前就已经产生了静态内部类(将他作为静态成员),因此静态内部类并不具有对外部类的依赖性。

评分

参与人数 1技术分 +2 收起 理由
admin + 2 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马