您的位置:首页 > 其它

内部类

2014-05-06 11:56 85 查看
内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类

 

A:成员内部类
作为外部类的一个成员存在,与外部类的属性、方法并列。

 // 成员内部类中,不能定义静态成员

// 成员内部类中,可以访问外部类的所有成员

 

注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。

 

B:局部内部类
在方法中定义的内部类称为局部内部类。与局部变量类似,局部内部类不能有访问说明符(public,private,protected),因为它不是外围类的一部分,但是它可以访问当前代码块内的常量,和此外围类所有的成员。

// 可以定义与外部类同名的变量

//不可以定义静态变量

 

C:静态内部类(嵌套类):(注意:前两种内部类与变量类似,所以可以对照参考变量)
如果你不需要内部类对象与其外围类对象之间有联系,那你可以将内部类声明为static。这通常称为嵌套类(nested
class)。想要理解static应用于内部类时的含义,你就必须记住,普通的内部类对象隐含地保存了一个引用,指向创建它的外围类对象。然而,当内部类是static的时,就不是这样了。嵌套类意味着:

1. 要创建嵌套类的对象,并不需要其外围类的对象。

2. 不能从嵌套类的对象中访问非静态的外围类对象。

 

// 静态内部类可以用public,protected,private修饰
// 静态内部类中可以定义静态或者非静态的成员

//静态内部类只能访问外部类的静态成员(包括静态变量和静态方法)

 

生成一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:Outer.Inner
in = new Outer.Inner();而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类(正常情况下,你不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分,因为它是static 的。只是将嵌套类置于接口的命名空间内,这并不违反接口的规则)

 

D:匿名内部类(from
thinking in java 3th)


简单地说:匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:
  ·只用到类的一个实例。 
  ·类在定义后马上用到。 
  ·类非常小(SUN推荐是在4行代码以下) 
  ·给类命名并不会导致你的代码更容易被理解。
  在使用匿名内部类时,要记住以下几个原则:
  ·匿名内部类不能有构造方法。 
  ·匿名内部类不能定义任何静态成员、方法和类。 
  ·匿名内部类不能是public,protected,private,static。 
  ·只能创建匿名内部类的一个实例。
·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。 
  ·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。 

如果你有一个匿名内部类,它要使用一个在它的外部定义的对象,编译器会要求其参数引用是final 型的

 

 

内部类的重载问题
 
如果你创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被重载吗?这看起来似乎是个很有用的点子,但是“重载”内部类就好像它是外围类的一个方法,其实并不起什么作用
 

内部类的继承问题

因为内部类的构造器要用到其外围类对象的引用,所以在你继承一个内部类的时候,事情变得有点复杂。问题在于,那个“秘密的”外围类对象的引用必须被初始化,而在被继承的类中并不存在要联接的缺省对象。要解决这个问题,需使用专门的语法来明确说清它们之间的关联

 

 

 

 

 

 


实例内部类中为什么不能定义static成员

因为静态的要编译期确定  而非静态的是运行期确定的  不同步了 

静态方法是可以直接调用的,既不创建对象也可以直接调用。而非静态的内部类,它属于外部类的一个成员类。需要先创建它的实例以后才能调用它的方法,当你创建了外部类以后,它的内部类是不存在的,所以你不能在那个对象没有之前就调用它的,就好想,是一个实际存在的东西和一个虚拟存在的东西一样,实际存在的 东西是不能被虚拟存在的东西所具有的。我可能说的不太明白,你也可以用java的类的定义的要求去推证它的不成立,你会发现那是矛盾的。如果你在非静态的内部类里包含静态的方法。

 

为什么匿名内部类和局部内部类只能访问final变量

一、匿名内部类为什么只能用final.
   是变量的作用域的问题,因为匿名内部类是出现在一个方法的内部的,如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final。因为虽然匿名内部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用。 


 

二、为什么局部内部类只能访问final变量

简单的来说是作用域的问题。就好像方法外面做的事情并不能改变方法内才定义的变量,因为你并不知道方法里面这个时候已经存在了这个局部变量了没有。在这个内部类中方法里面的本地变量是失效的,也就是不在作用域内,所以是不能够访问的 

但是为什么这里用final却又可以访问呢? 

因为Java采用了一种copy   local   variable的方式来实现,也就是说把定义为final的局部变量拷贝过来用,而引用的也可以拿过来用,只是不能重新赋值。从而造成了可以access   local   variable的假象,而这个时候由于不能重新赋值,所以一般不会造成不可预料的事情发生 


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: