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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄玉昆 黑马帝   /  2013-2-11 11:08  /  1193 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

先来看一段简单的代码:
  1. //情况一:创建两个常规类A和B
  2. class A{
  3.         int a = 5;
  4.         void  fun(){
  5.                 C c = new C();
  6.                 c.method();
  7.                 System.out.println("A:" + a);
  8.         }
  9.         //情况二:将C类放入A类中
  10.         class C{
  11.                 void method(){
  12.                         System.out.println("C访问A:" + a);//可直接访问
  13.                 }
  14.         }
  15. }
  16. class B{
  17.         void fu(){
  18.                 int a = 6;
  19.                 A me = new A();
  20.                 System.out.println("访问A中a:" + me.a);//必须建立对象后才能访问
  21.         }
  22. }
  23. class  Demo
  24. {
  25.         public static void main(String[] args)
  26.         {
  27.                 A x = new A();
  28.                 B y = new B();
  29.                 x.fun();
  30.                 y.fu();
  31.         }
  32. }
复制代码
从代码中就可以看出,内部类的好处。
内部类:将一个类定义在另一个类之中。
一、访问规则(即使用内部类的好处):
1、内部类方法可以访问该类所在的类中作用域的成员,包括私有成员变量。
2、内部类可以对同一个包中的其他类隐藏起来,从而不被访问
3、使用匿名内部类是比较便捷简单的,这种情况较多的用于AWT设计中。
注:为何内部类可直接访问外部类:
由于成员可被对象访问,内部类中持有了一个外部类的引用,,因此就可以直接用:外部类名.this.成员
二、访问格式:
1当内部类定义在外部类的成员位置上,而且非私有,可在外部其他类中直接建立内部类对象
格式:外部类名.内部类名  变量名 = 外部类对象.内部类对象
2、当内部类在成员变量的位置上,可被成员修饰符修饰
·private:将内部类在外部类中进行封装
·static:内部类具备了static的特性,当内部类被static修饰(下面说到的静态内部类),只可访问外部类中的static的成员,访问则受限。
注:(Outer为外部类名,Inner为内部类名,function为非静态成员)
在其他类中,如何访问静态内部类中非静态成员:new Outer.Inner.function();(建立对象访问)
在其他类中,如何访问静态内部类中的静态成员:Outer.Inner.function();(可直接访问)
注意:
1、当内部类中定义了静态成员,该内部类必须为静态的
2、当外部类中静态方法访问内部类时,内部类必须为静态的
3、内部类一般定义为private的,而很少定义为public的。
三、内部类定义原则:------->多在程序设计中使用
1、当描述事物时,事物的内部还有事物,则该事物使用内部类来描述,因为内部事物要使用外部事物内容
举例来说:楼房内部还有家庭住户,家庭住户中还有房间,这就可以用内部类描述。(总不能访问一个住户,就建立一个楼房对象吧,那就可真是有钱人的风范了。)
2、何时定义内部类:
当一个类需要直接访问另一个类中的成员时,则当这个类放入另一个类中,并将内部类封装。
3、内部类生成文件:
我们在编译一个源文件是,如果代码中有内部类,你会发现,生成的class文件中含有例如这样的文件:A$C.class。这是为什么呢?因为内部类是一种编译现象,与虚拟机无关。编译器将会把内部类翻译成用$(美元符号)分隔外部类名和内部类名的常规类文件,而虚拟机对此却一无所知。


评分

参与人数 1技术分 +1 收起 理由
杨志 + 1 新年新气象,加油!

查看全部评分

3 个回复

倒序浏览
四、局部内部类(也称局部类)
看下面一段代码:
  1. class A{
  2.         private int a = 5;
  3.         void  fun(){
  4.                 class B{//在方法中创建一个内部类
  5.                         void method(){
  6.                                 System.out.println("C访问A:" + a);//可直接访问
  7.                         }
  8.                 }
  9.                 B c = new B();//建立一个对象
  10.                 c.method();
  11.         }
  12. }
  13. class  Demo
  14. {
  15.         public static void main(String[] args)
  16.         {
  17.                 A x = new A();
  18.                 x.fun();
  19.         }
  20. }
复制代码
局部内部类:当内部类只在外部类中的某个方法中,创建了这个类型的对象时,且仅使用了一次,那么可在这个方法中定义局部类。
注:
1、局部内部类不可用public或者private访问修饰符声明,它的作用域被限定在了声明这个局部类的代码块中
2、局部类的优势:
a.对外界完全隐藏,即使此方法所在的类也不可访问,也就是说,除此方法外,无任何方法知道它的存在。
b.可访问包含他们的外部类,因还持有外部类的引用;还可访问局部变量,但是局部变量必须被声明为final
需要注意:局部内部类不可悲成员修饰符修饰,如static。代码如下:
  1. class Outer//类不能用private,但是内部类是可以的
  2. {
  3.         int x = 3;
  4.         private static class InnerOuter//可在外部类的任意有效的地方,可以用private和static
  5.         {                //......
  6.         }
  7.         //含局部变量时
  8.         void method(final int a)//需访问加final
  9.         {
  10.                 final int y = 4;//y需要被声明为最终类型,即final才可被局部内部类中的成员访问
  11.                 class Inner//在方法中,相当于局部成员,不能为static或private
  12.                 {
  13.                         void fun()//不能定义静态成员(变量和方法)
  14.                         {
  15.                                 System.out.println("访问外部类成员变量:+ Outer.this :" + Outer.this.x);
  16.                                 System.out.println("局部内部类访问本地变量定义为final:" + y);
  17.                                 System.out.println("方法中的参数需定义为final:" + a);
  18.                         }
  19.                 }
  20.                 new Inner().fun();
  21.         }
  22. }
  23. class InnerClassDemo0
  24. {
  25.         public static void main(String[] args)
  26.         {
  27.                 Outer ou = new Outer();
  28.                 ou.method(7);//打印3、4、7
  29.                 ou.method(5);//打印3、4、8
  30.         }
  31. }
复制代码
说明:为什么定义为final了,还可以改变值78;这是因为在传入7后,运行method方法结束后,在栈内存中就会随即消亡,然后就可以再传入8,运行下一个method方法。
五、匿名内部类:
1、匿名内部类:就是内部类的一种简写格式。
当只创建该类的一个对象,可不用再为其命名。所以称之为匿名内部类。代码示例:
  1. class Outer2
  2. {
  3.         int x = 3;
  4.         public  void fun()
  5.         {
  6.                 /*
  7.                 其中Inner()被改写为AbsDemo(){}  (其实就是对父类的复写)
  8.                 */
  9.                 new AbsDemo()//看这里
  10.                 {
  11.                         void show()
  12.                         {
  13.                                 System.out.println("匿名show:" + x);
  14.                         }
  15.                 }.show();//new Inner().show();的简写
  16.         }
  17. }
复制代码
2、定义前提:
内部类必须继承一个类或实现接口。
但是有一种很特殊,可以不直接继承一个父类,仍可定义一个匿名内部类。因为任何类都是Object的子类。如:
  1. new Object()
  2. {
  3.          类中的内容
  4.          fun()方法
  5. }.fun();
复制代码
3、格式:
new    父类或接口(参数){定义子类的内容};
4、要点说明:
      A.其实匿名内部类就是一个匿名子类对象,可以理解为带有内容的对象。
     B.匿名内部类中的方法最好少于3个,方法少,比较方便简单,匿名内部类一定要简化,否则就违背了初衷
回复 使用道具 举报
六、静态内部类
1、概述:
上面提到当内部类在成员变量的位置上,可被成员修饰符static修饰,这就是静态内部类
2、使用前提:
某些情况下,会把内部类作为一个隐藏的类,不需要使用内部类引用外部类的对象。因此,可以将外部类声明为static,就可以消除产生的引用。在内部类不需要访问外部类对象的时候,应该使用静态内部类。
下面是示例:
  1. /*
  2. 静态内部类测试:最大值最小值
  3. */

  4. class ArrayAlg
  5. {
  6.         public static class Pair
  7.         {
  8.                 private double first;
  9.                 private double second;
  10.                 //构造函数获得两个值
  11.                 public Pair(double first,double second)
  12.                 {
  13.                         this.first = first;
  14.                         this.second = second;
  15.                 }
  16.                
  17.                 //访问器:访问私有变量first和second
  18.                 public double getFirst()
  19.                 {
  20.                         return first;
  21.                 }
  22.                 public double getSecond()
  23.                 {
  24.                         return second;
  25.                 }
  26.         }
  27.         //定义一个获得最大值和最小值的功能
  28.         public static Pair minmax(double[] arr)
  29.         {
  30.                 //min和max要分别设置最大和最小,然后才能和数组中的数比较
  31.                 double min = Double.MAX_VALUE;
  32.                 double max = Double.MIN_VALUE;

  33.                 for (int i=0;i<arr.length;i++)
  34.                 {
  35.                         if (min > arr[i])
  36.                                 min = arr[i];
  37.                         if (max < arr[i])
  38.                                 max = arr[i];
  39.                 }
  40.                 return new Pair(min,max);
  41.         }
  42. }

  43. class ArrayZDemo
  44. {
  45.         public static void main(String[] args)
  46.         {
  47.                 double[] d = new double[20];
  48.                 for (int i=0;i<d.length;i++)
  49.                         d[i] = 100*Math.random();
  50.                 ArrayAlg.Pair p = ArrayAlg.minmax(d);
  51.                 System.out.println("min = " + p.getFirst());
  52.                 System.out.println("max = " + p.getSecond());
  53.         }
  54. }
复制代码
练习:
  1. interface Inter
  2. {
  3.         void method();
  4. }
  5. class Test
  6. {
  7.         //补足代码,用匿名内部类
  8. }
  9. class NInnerClassTest
  10. {
  11.         public static void main(String[] args)
  12.         {
  13.                 Test.function().method();
  14.         }
  15. }
复制代码
对于Test.function().method();的理解:
Test.function():类中有一个静态的方法function
method()function这个方法运算后的结果是一个对象,而且是一个Inter类型的对象。
--->因为只有是Inter类型的对象,才可以调用method方法。
结果:
  1. interface Inter
  2. {
  3.         void method();
  4. }

  5. class Test
  6. {
  7.         public static Inter function()
  8.         {
  9.                 return new Inter()
  10.                 {
  11.                         public void method()
  12.                         {
  13.                                 System.out.println("使用静态");
  14.                         }
  15.                 };
  16.         }
  17. }
  18. //测试结果
  19. class NInnerClassTest
  20. {
  21.         public static void main(String[] args)
  22.         {
  23.                 Test.function().method();
  24.         }
  25. }
复制代码
匿名内部类的应用:
  1. class NInnerClassTest
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 show(new Inter()
  6.                 {
  7.                         public void method()
  8.                         {
  9.                                 System.out.println("method show run");
  10.                         }
  11.                 });

  12.         }
  13.         public static void show(Inter a)
  14.         {
  15.                 a.method();
  16.         }
  17. }
复制代码
回复 使用道具 举报
顶一个...{:soso_e100:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马