Java基础------知识点整理(八)-----内部类

来源:互联网 发布:mysql 截断 编辑:程序博客网 时间:2024/06/11 22:01

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:14px;">1.内部类:将一个类定义到另一个类里面,里面的类叫内部类</span></span>


2.内部类特点

(1)内部类可以访问外部类中的成员(内部类相当于外部类的一个成员,所以可以直接访问,尤其是private变量),如果不用内部类访问private成员还得先创建一个对象,然后             通过set,get方法才能访问private成员,所以此时为了方便创建内部类

(2)外部类要访问内部类,需要创建一个内部类的对象


3.格式

class  Outer{       coding1 ...........       class  Inner{               coding2 ...........       }}

会生成一个Outer.class  ,也会生成一个Outer$Inner.class 


4.一般什么时候用?

在分析类A时,发现A的描述需要类B,而且类B还在访问类A中的内容,此时将B放到A中,这样访问起来比较方便

你实现了某类型的接口,于是可以创建并返回对其的引用

你要解决一个复杂的问题,想创建一个类来辅助你的解决方案,但是又不希望这个类是公共可用的


5.访问方式

(1)在类外(此处指的类外是在Outer类的类外)直接访问外部类里的内部类成员(假设内部类没有私有化)

           Outer.Inner    in    =    new   Outer().new  Inner()//把Inner当成Outer的一个成员,并且把Inner当成一个类

(2)假如内部类是静态的,相当于内部类是外部类的静态成员,直接用类名.内部类名调用即可

          Outer.Inner    in     =   new   Outer.Inner();    //静态的内部类岁外部类加载而加载,因此不需要创建内部类的对象

(3)如果内部类是静态的,内部类里的函数也是静态的,调用不需要创建对象

           OUt.Inner.函数名();

(4)如果内部类里有静态成员,内部类必须也是静态的,这是因为静态成员随类的加载就加载,就不需要创建对象,如果内部类不是静态的,还得创建对象,矛盾

(5)如果内部类在方法的作用域里,称为局部内部类;此时内部类是方法里的部分,而不是外部类的一部分。因此在方法之外不能访问内部类,如果内部类访问了方法里的局  部变量,需要将局部变量定义为final,因为内部类在局部的位置上,只能访问局部中被final修饰的变量,否则局部变量会随着方法的弹栈而消失,此时内部类就可能访问  不到这些局部变量


6.使用 .this(点this)    和    .new(点new)

如果想要在内部类中生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。

<pre name="code" class="java">public   class   DotThis{    void   f(){  Syso("DotThis.f")}    public   class  Inner  {        public  DotThis  outer(){        return   DoThis.this;   //                  如果只写this,将会返回Inner的this        }    }}


有时可能想要告知某些其他对象,创建某个内部类的对象,此时用.new语法

<pre name="code" class="java">public   class   DotNew{    public  class  Inner{}    public   static   void   main(String[]   args){        DotNew   dn   =   new   DotNew();        DotNew.Inner   dni   =   dn.new   Inner();   //相当于   DotNew.Inner   dni   =   nwe  Outer().new   Inner();     }}


7.匿名内部类

前提:内部类必须继承或实现一个类或接口,匿名内部类其实就是一个匿名的子类对象


格式:

<pre name="code" class="java"><pre name="code" class="java">class  Fu{    public  void  show(){}}class Outer{    return new Fu(){        public void show2(){}    };}


匿名内部类实际上使用了父类的默认的构造器生成Fu;

如果基类需要一个有参数的构造器时,只需要简单的传递合适的参数给积累的构造器即可

class  Fu{    public  void  show(){}}class Outer{    public Wrapping wrapping(int x){        return new Fu(x){            public void show2(){}        };}


在匿名内部类的末尾分号,并不是标记内部类的结束,实际上,它标记的是表达式的结束。

如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的。

匿名内部类中不可能有命名构造器(因为它根本就没名字),但是可以通过在匿名内部类中加入构造代码块,达到为匿名内部类创建一个构造器的效果

例如:

class Outer{    return new Base(){        {syso("Inside instance initializer")}         public void f(){syso("In anonymous f()")}    }}

此时构造代码快的效果就是构造器,当然它有一个限制,你不能重载它,所以仅有这样一个构造器。


8.调用匿名内部类的函数

(1)直接在匿名内部类的右大括号加点方法名

<pre name="code" class="java">class Outer{    public int  num = 4;    public void method(){        new Fu(){            public void show(){                syso("show..." + num);            }        }.show();    }}


由于相当于创建了一个子类,但引用指向了父类,所以调用的必须是父类中的方法。

由上可以想到,这样只能调用一个方法,如果想调用多个方法,格式如下:

class Outer{    public int  num = 4;    public void method(){        Fu f =new Fu(){            public void show(){                syso("show..." + num);            }        };        f.show1();        f.show2();    }}




0 0
原创粉丝点击