首页 > 编程语言 >java内部类

java内部类

时间:2023-07-19 18:07:38浏览次数:64  
标签:java 内部 void public new println Outer class


Java内部类总结


 


Java内部类其实在J2EE编程中使用较少,不过在窗口应用编程中特别常见,主要用来事件的处理。其实,做非GUI编程,内部类完全可以不用。


 


内部类的声明、访问控制等于外部类有所不同,要灵活使用内部类来编写程序,还是有相当难度的,Java发明了这种难懂的玩意儿,在其他语言中是没有的,但是在Java中,内部类也相当的重要,尤其做GUI开发时候,事件的响应处理全靠内部类了。


 


内部类所做的功能使用外部类也同样可以实现,只是有时候内部类做的更巧妙些。


 


内部类按照其所在位置不同,可分为以下几种:


1、(普通的)内部类(最常见的内部类,内部类的定义与类成员平级,)
2、方法内部类
3、匿名类
4、静态内部类
5、接口内部类


 


一、内部类声明与访问


 


1、内部类直接在类的内部进行声明。可以声明为private、protected、public或者默认访问权限,这个访问权限约定和外部类完全一样。


 


外部类名.this.外部成员名,例如Outer.this.i++;  (看例子)


 


3、必须使用外部类对象来创建内部类对象,而不是直接去new一个。


外部对象名.new 内部类构造方法


 


比如要创建一个内部类iner对象,需要这么做:

Outer outer = new Outer(); 
 
        Outer.Inner iner = outer.new Inner(); 
 

    

 
/** 
* 内部类创建与初始化 
* 
* @author leizhimin 2009-7-17 13:51:52 
*/ 
   
public 
   class Outer { 
   
         
   private 
   int i = 10; 
   
         
   private 
   int y = 8; 
   

        Outer() { 
   
                System.out.println( 
   "调用Outer构造方法:outer"); 
   
        } 
   

         
   public 
   void sayMsg() { 
   
                System.out.println( 
   "Outer class!"); 
   
        } 
   

         
   class Inner { 
   
                 
   int i = 1000; 
   

                Inner() { 
   
                        System.out.println( 
   "调用Inner构造方法:inner"); 
   
                } 
   

                 
   void innerMsg() { 
   
                        System.out.println( 
   ">>>>>Inner class!"); 
   
                        sayMsg(); 
   
                         
   //访问内部类自己的成员i,也可以写成 this.i++  
   
                         
   this.i++; 
   
                         
   //访问外部类的成员 i和y  
   
                        Outer. 
   this.i++; 
   
                        y--; 
   
                } 
   

                 
   int getI() { 
   
                         
   return i; 
   
                } 
   
        } 
   

         
   public 
   void test() { 
   
                Inner in = 
   new Inner(); 
   
                in.innerMsg(); 
   
        } 
   

         
   public 
   int getI() { 
   
                 
   return i; 
   
        } 
   

         
   public 
   void setI( 
   int i) { 
   
                 
   this.i = i; 
   
        } 
   
} 
   

class Test1 { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer outer = 
   new Outer(); 
   
                outer.test(); 
   
                System.out.println(outer.getI()); 
   
                System.out.println( 
   "-------1--------"); 
   

                Outer.Inner iner = outer. 
   new Inner(); 
   
                iner.innerMsg(); 
   
                System.out.println(iner.getI()); 
   
                System.out.println( 
   "-------2--------"); 
   

                System.out.println(outer.getI()); 
   
        } 
   
}

 


运行结果:


调用Outer构造方法:outer
调用Inner构造方法:inner
>>>>>Inner class!
Outer class!
11
-------1--------
调用Inner构造方法:inner
>>>>>Inner class!
Outer class!
1001
-------2--------
12

Process finished with exit code 0


 


二、内部类与接口


 


1、内部类可以实现接口。


2、内部类之间相互可见,但并非内部类之间方法都可见。

public 
   interface Foo{ 
   
         
   void say(); 
   
} 
   

    

 
public 
   interface Bar { 
   
         
   void readme(); 
   
} 
   

    

 
/** 
* 内部类实现接口 
* 
* @author leizhimin 2009-7-17 14:57:50 
*/ 
   
public 
   class Test2 { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer outer = 
   new Outer(); 
   
                Foo f = outer.genFoo(); 
   
                Bar b = outer.genBar(); 
   
                f.say(); 
   
                b.readme(); 
   
        } 
   
} 
   

class Outer { 
   
         
   private 
   class FooImpl 
   implements Foo { 
   
                 
   public 
   void say() { 
   
                        System.out.println( 
   "say foo!"); 
   
                } 
   
        } 
   

         
   private 
   class BarImpl 
   implements Bar { 
   
                 
   public 
   void readme() { 
   
                        System.out.println( 
   "say bar!"); 
   
                } 
   
        } 
   

         
   public Foo genFoo() { 
   
                 
   return 
   new FooImpl(); 
   
        } 
   

         
   public Bar genBar() { 
   
                 
   return 
   new BarImpl(); 
   
        } 
   
}

 


输入结果:


say foo!
say bar!

Process finished with exit code 0


 


三、访问权限


 


外部类分两种:
一种嵌入了内部类声明代码外部类,称为直接外部类。
另一种是与内部类没有任何关系的外部类,称为外部类。


 


在同一个直接外部类中,内部类之间所有的方法都是相互可见的,包含在直接外部类的main()中可见。



在外部类中,要看到一个类的内部类成员,则至少要求这个内部类的class和成员权限大于或等于protected。


/** 
* 内部类实现接口 
* 
* @author leizhimin 2009-7-17 14:57:50 
*/ 
   
public 
   class Test2 { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer o = 
   new Outer(); 
   
                Outer.Bar b = o.genBar(); 
   
                b.readme(); 
   
        } 
   
} 
   

class Outer { 
   

         
   protected 
   class Foo { 
   
                 
   protected 
   void say() { 
   
                        System.out.println( 
   "say foo!"); 
   
                } 
   

                 
   private 
   void test() { 
   
                        System.out.println( 
   "----test------"); 
   
                } 
   
        } 
   

         
   protected 
   class Bar { 
   
                 
   protected 
   void readme() { 
   
                        System.out.println( 
   "say bar!"); 
   
                         
   new Foo().test(); 
   
                } 
   
        } 
   

         
   public Foo genFoo() { 
   
                 
   return 
   new Foo(); 
   
        } 
   

         
   public Bar genBar() { 
   
                 
   return 
   new Bar(); 
   
        } 
   
}

 


四、方法内部类


 


方法内部类只在该方法内部可见,方法内部类可以定义在方法中的任何位置。

/** 
* 内部类实现接口 
* 
* @author leizhimin 2009-7-17 14:57:50 
*/ 
   
public 
   class Test2 { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer outer = 
   new Outer(); 
   
                Foo f = outer.genFoo(); 
   
                Bar b = outer.genBar(); 
   
                f.say(); 
   
                b.readme(); 
   
        } 
   
} 
   

class Outer { 
   
         
   public Foo genFoo() { 
   
                 
   //方法内的内部类  
   
                 
   class FooImpl 
   implements Foo { 
   
                         
   public 
   void say() { 
   
                                System.out.println( 
   "say foo!"); 
   
                        } 
   
                } 
   
                 
   return 
   new FooImpl(); 
   
        } 
   

         
   public Bar genBar() { 
   
                Bar b = 
   null; 
   
                 
   if ( 
   true) { 
   
                         
   //任意位置的内部类  
   
                         
   class BarImpl 
   implements Bar { 
   
                                 
   public 
   void readme() { 
   
                                        System.out.println( 
   "say bar!"); 
   
                                } 
   
                        } 
   
                        b = 
   new BarImpl(); 
   
                } 
   
                 
   return b; 
   
        } 
   
}

 


运行结果:


say foo!
say bar!

Process finished with exit code 0


 


五、匿名类


 


匿名类不给出类名,直接定义一个类,通常这个类实现了某种接口或者抽象。匿名类的访问权限更没有讨论价值了,看个例子就行了。


 


在一些多线程程序中比较常见,有点变态,呵呵。

/** 
* 匿名类. 
* 
* @author leizhimin 2009-7-17 15:56:17 
*/ 
   
public 
   class Test3 { 
   
         
   public Foo f = 
   new Foo() { 
   
                 
   public 
   void say() { 
   
                        System.out.println( 
   "O(∩_∩)O哈哈~!"); 
   
                } 
   
        }; 
   

         
   public Foo test() { 
   
                 
   return 
   new Foo() { 
   
                         
   public 
   void say() { 
   
                                System.out.println( 
   "say foo!"); 
   
                        } 
   
                }; 
   
        } 
   

         
   public 
   static 
   void main(String[] args) { 
   
                Test3 t = 
   new Test3(); 
   
                t.f.say(); 
   
                t.test().say(); 
   
        } 
   
} 
   

interface Foo { 
   
         
   void say(); 
   
}

 


运行结果:


O(∩_∩)O哈哈~!
say foo!

Process finished with exit code 0


/** 
* 普通类的匿名初始化 
* 
* @author leizhimin 2009-7-17 16:13:31 
*/ 
   
public 
   class Fk { 
   
         
   private String x; 
   

         
   public Fk(String x) { 
   
                 
   this.x = x; 
   
        } 
   

        @Override 
   
         
   public String toString() { 
   
                 
   return 
   "Fk{" + 
   
                                 
   "x='" + x + '\'' + 
   
                                '}'; 
   
        } 
   
} 
   

class Test4 { 
   
         
   public Fk hehe() { 
   
                 
   //把后面的一对大括号去掉呢,呵呵  
   
                 
   return 
   new Fk( 
   "fk") { 
   
                }; 
   
        } 
   

         
   public 
   static 
   void main(String[] args) { 
   
                Test4 t = 
   new Test4(); 
   
                Fk f = t.hehe(); 
   
                System.out.println(f); 
   
        } 
   
}

 


运行结果:


Fk{x='fk'}

Process finished with exit code 0


 


还有一个不得不提的经典实例,来自thining in java,有改动:


interface Service { 
   
     
   void method1(); 
   
     
   void method2(); 
   
} 
   

interface ServiceFactory { 
   
    Service getService(); 
   
} 
   

class Implementation1 
   implements Service { 
   
     
   private Implementation1() {} 
   
     
   public 
   void method1() {System.out.println( 
   "Implementation1 method1");} 
   
     
   public 
   void method2() {System.out.println( 
   "Implementation1 method2");} 
   
     
   public 
   static ServiceFactory factory = 
   new ServiceFactory() { 
   
             
   public Service getService() { 
   
                 
   return 
   new Implementation1(); 
   
            } 
   
        }; 
   
} 
   

class Implementation2 
   implements Service { 
   
     
   private Implementation2() {} 
   
     
   public 
   void method1() {System.out.println( 
   "Implementation2 method1");} 
   
     
   public 
   void method2() {System.out.println( 
   "Implementation2 method2");} 
   
     
   public 
   static ServiceFactory factory = 
   new ServiceFactory() { 
   
             
   public Service getService() { 
   
                 
   return 
   new Implementation2(); 
   
            } 
   
        }; 
   
} 
   

public 
   class Factories { 
   
     
   public 
   static 
   void serviceConsumer(ServiceFactory fact) { 
   
        Service s = fact.getService(); 
   
        s.method1(); 
   
        s.method2(); 
   
    } 
   
     
   public 
   static 
   void main(String[] args) { 
   
        serviceConsumer(Implementation1.factory); 
   
        serviceConsumer(Implementation2.factory); 
   
    } 
   
}


这个应用给了我们很多思考,我就不说了,不同人看了会有不同的感受。


 


内部类的巧妙使用会让你的代码很牛,如果要形容下,那就是:没看懂的时候感觉神出鬼没,看懂后感觉鬼斧神工。不过这些代码多了,别人想看懂都难,想看懂你思路就难上加难了。呵呵!


 


六、静态内部类


 


静态内部类是static class型的内部类,这种内部类特点是:它不能访问外部类的非静态成员。要创建静态内部类对象时候,也不需要外部类对象了,直接可以:


new 外部类名.内部类构造方法


来创建,给个例子:


/** 
* 静态内部类 
* 
* @author leizhimin 2009-7-17 16:53:05 
*/ 
   
public 
   class Outer { 
   
         
   public 
   static 
   int i =500; 
   
         
   protected 
   static 
   class Inner { 
   
                 
   int i =100; 
   
                String name; 
   

                Inner(String name) { 
   
                         
   this.name = name; 
   
                } 
   

                 
   void sayHello() { 
   
                        System.out.println( 
   "Hello " + name); 
   
                        Outer.i++; 
   
                } 
   
        } 
   

         
   public Inner genInner(String name) { 
   
                 
   return 
   new Inner(name); 
   
        } 
   
} 
   

class Test { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer.Inner in1 = 
   new Outer.Inner( 
   "1111"); 
   
                in1.sayHello(); 
   
                System.out.println(Outer.i); 
   

                Outer.Inner in2 = 
   new Outer().genInner( 
   "2222"); 
   
                in2.sayHello(); 
   
                System.out.println(Outer.i); 
   
        } 
   
}


 


运行结果:


Hello 1111
501
Hello 2222
502

Process finished with exit code 0

 


七、接口内部类


 


接口内部类自动都是public static的,相当于为接口定义了一种变量类型,这在java的设计中就有使用,比如在HashMap中,就有:

static class Entry<K,V> implements Map.Entry<K,V>

 


下面我给个例子,

/** 
* 接口内部类 
* 
* @author leizhimin 2009-7-17 17:20:28 
*/ 
   
public 
   interface AInterface { 
   
         
   void readme(); 
   

         
   class Inner1 
   implements AInterface { 
   
                 
   public 
   void readme() { 
   
                        System.out.println( 
   "我是一个接口内部类"); 
   
                } 
   
        } 
   
} 
   

class Main { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                AInterface.Inner1 in1 = 
   new AInterface.Inner1(); 
   
                in1.readme(); 
   
        } 
   
}

 


八、内部的类的嵌套


 


所谓内部类嵌套,就是内部类里面再定义内部类。其实这种用法还真没见过,试试写个简单例子看看吧:


/** 
* 嵌套内部类 
* 
* @author leizhimin 2009-7-17 17:33:48 
*/ 
   
public 
   class Outer { 
   
         
   private 
   void f0() { 
   
                System.out.println( 
   "f0"); 
   
        } 
   

         
   class A { 
   
                 
   private 
   void a() { 
   
                        f0(); 
   
                        System.out.println( 
   "a"); 
   
                } 
   

                 
   class B { 
   
                         
   protected 
   void b() { 
   
                                a(); 
   
                                System.out.println( 
   "b"); 
   
                        } 
   
                } 
   
        } 
   
} 
   
class Test{ 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer o = 
   new Outer(); 
   
                Outer.A    a =     o. 
   new A(); 
   
                Outer.A.B b = a. 
   new B(); 
   
                b.b(); 
   
        } 
   
}


运行结果:


f0
a
b

Process finished with exit code 0

 


八、内部类的继承


 


内部类的继承,可以继承内部类,也可以继承外部类。


/** 
* 内部类的继承,可以继承内部类,也可以继承外部类 
* 
* @author leizhimin 2009-7-22 13:50:01 
*/ 
   
public 
   class Outer { 
   
         
   class Inner { 
   
                 
   void doSomething() { 
   
                        System.out.println( 
   "Inner doing ..."); 
   
                } 
   
        } 
   

         
   class Inner2 
   extends Inner { 
   
                 
   void doSomething() { 
   
                        System.out.println( 
   "Inner2 doing ..."); 
   
                } 
   

                 
   void readme() { 
   
                        System.out.println( 
   "HeHe!"); 
   
                } 
   
        } 
   
} 
   

class Test { 
   
         
   public 
   static 
   void main(String[] args) { 
   
                Outer outer = 
   new Outer(); 
   
                Outer.Inner in = outer. 
   new Inner(); 
   
                Outer.Inner2 in2 = outer. 
   new Inner2(); 
   
                in.doSomething(); 
   
                in2.doSomething(); 
   
                in2.readme(); 
   
        } 
   
}


运行结果:


Inner doing ...
Inner2 doing ...
HeHe!

Process finished with exit code 0


 


 


总结:


 


内部类是Java中最复杂深奥的概念之一,而且内部类在访问控制,修饰符,继承,实现,抽象,序列化等等很多方面都是一个很让人迷惑的问题,在实际中,这些问题也许永远没机会没时间搞清,但是一般说来,懂得以上的内部类的知识就足够用了。


 


内部类的设计也许是弥补Java语言本身的先天不足吧,作为语言来说,这个特性太变态了点,难道就没别的法了?


 


以上的总结完全是建立在实践基础上的,所列举的例子也许偏颇,不能全面反映问题的本质,希望有兴趣的博友多多发表自己的看法与观点。

标签:java,内部,void,public,new,println,Outer,class
From: https://blog.51cto.com/u_16193056/6778755

相关文章

  • 建java存储过程
    作者:iihero一、如何创建java存储过程?通常有三种方法来创建java存储过程。1.使用oracle的sql语句来创建:e.g.使用createorreplaceandcompilejavasourcenamed"<name>"as      后边跟上java源程序。要求类的方法必须是publicstatic的,才能用于存储过程。SQL>create......
  • @JavascriptInterface传过来键值对,Android这边用什么类型接收
    传输键值对给Android的JavascriptInterface概述在Android开发中,我们经常需要在JavaScript和Java之间传输数据。一种常见的方式是通过使用@JavascriptInterface注解将Java方法暴露给JavaScript调用。这种方式可以实现双向通信,并且非常灵活。本文将介绍如何使用@JavascriptInterfac......
  • java书籍
    看见大家这多大家的踊跃发言,我这里澄清一下,这里给出的书籍主要侧重于软件设计和管理方面,特别是软件设计,说句废话,看完这些书并不代表懂得软件设计,而在于应用,那你将和里面很多观点产生共鸣,理解其中的一些奥妙。这里所选的书籍不敢说是最好的,但是保证这些书籍的书写都是严谨的,理论都是......
  • <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEnc
    实现<%@pagelanguage="java"contentType="text/html;charset=ISO-8859-1"pageEnc的步骤为了帮助这位刚入行的小白实现<%@pagelanguage="java"contentType="text/html;charset=ISO-8859-1"pageEnc,我们需要按照以下步骤进行操作:步骤操作1创建一个......
  • .Net 对RSA加密结果跟JAVA加密结果不一致问题处理
    stringpublicRsaKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6UCsvO/M/Q51ydlxvuvwy8W9yXkAWLLiG5eA2Duha9cr/XoWrQcETf7PRMNYaQs616PGhj0tnPfxfDltmeqTJQf8rHNxevIZ9nQ0N0/8PIlVszubpMyAHnEis2OLMnLENGyepAlabFGDMDPzRpf0ibL0Q/R15BuTzII5gunzAbwIDAQAB";stri......
  • Android开发RXJava
    Android开发RXJava实现流程下面是实现"Android开发RXJava"的流程表格:步骤描述1导入RxJava库2创建Observable对象3创建Observer对象4使用subscribe()方法订阅Observable和Observer下面将详细介绍每个步骤需要做的事情以及对应的代码和注释。步骤1:导入R......
  • JAVA 内部类
    Java类中不仅可以定义变量和方法,还可以定义类,这样定义在类内部的类就被称为内部类。根据定义的方式不同,内部类分为静态内部类,成员内部类,局部内部类,匿名内部类四种。 静态内部类定义在类内部的静态类,就是静态内部类。1publicclassOut{2privatestaticinta;3......
  • Java 默认构造
    Java默认构造方法的实现作为一名经验丰富的开发者,你将帮助一位刚入行的小白了解如何实现Java中的默认构造方法。在本篇文章中,我们将按照以下步骤来进行讲解:创建一个Java类添加默认构造方法编写构造方法的代码逻辑让我们一步一步地来实现这些步骤。1.创建一个Java类首先,......
  • Java 两个字符串相加
    Java两个字符串相加作为一名经验丰富的开发者,我很乐意教你如何实现“Java两个字符串相加”。下面我将详细介绍这个过程,并提供每个步骤所需的代码和注释。过程概述下面是实现“Java两个字符串相加”的步骤概览:步骤描述1创建两个字符串变量2输入两个待相加的字......
  • Java 静态初始化创建
    Java静态初始化创建简介静态初始化是一种在声明变量时直接初始化的方式,它可以在不创建对象的情况下对变量进行初始化。本文将介绍如何使用Java静态初始化创建变量的步骤和相应的代码示例。步骤下面是创建Java静态初始化变量的步骤。步骤描述1声明一个静态变量。2......