您的位置:首页 > 编程语言 > Java开发

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

2016-03-28 17:48 701 查看
<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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: