2008-08-19

Java中的类

  同C++比起来,在Java中,类的应用更加的灵活多变,这篇文章简要的介绍一下整体的情况。

  类的集合在Java中被定义为包,它最容易实现的一种形式就是文件夹名作为包名,文件则是类。当然,实际不限于此。
  通过使用包,java中排除了麻烦的名字冲突问题。
  在java的类成员前的访问限定符就与包有关。java中的访问限制由宽松到严格(从母集到子集)的列举:
  • public:所有人都可以访问
  • protected:只有当前包中,或者当前包的子包和子类可以访问。
  • 默认情况,就是没有写访问限定符,也称包访问方式,只有当前包中的类能够访问。
  • private:只有当前类能访问。
  因此有以下规则。假设有A,B两个包,EXA,EXB两个类分别属于两个包。不论两个类之间是否存在继承关系,它们只能互访对方的public成员。
  而当两个类都属于A包的时候,不论两个类是否有联系,它们都能互访彼此的public,protected和未标明访问限定符的成员。
----------------------------------------
  了解了访问限定后,我们可以了解一下Java的嵌套类:
  

  如上图所示,它们的逻辑结构关系就是这样。
  类分为两种,我们最熟悉的就是顶级类了,也就是我们平时写的只能属于java包的成员的类。除此之外的另外一种就是所谓的嵌套类了,所谓嵌套类就是定义在另外一个类的内部的类。总的来说,很多时候使用嵌套类能够简化不少代码。
  嵌套类还能够细分为静态类和内部类。
  一般来说,内部类不是java包的一部分,在外嵌类之外是不可见的。
  静态类是一个声明为static的嵌套类,它不同于内部类,基本来说和顶级类的作用一样。正是因为声明为static,所以它是属于所嵌的类,而非该类的任何实例。
  声明的话用:

class top{
  static class test1{}
}

  成员类是一个内部类,其实和静态类比起来就是没有staitc而已。因此它和外嵌类的每个实例都有关系。因为是作为外嵌类的成员,所以它可以操作这个外嵌类的所有其他成员。当然,要使用成员类,这个外嵌类也必须先声明这个成员类的实例。
  声明的格式:
class top{
  class test2 {}
}


  本地类是一般声明在代码块内部,基本上是在方法中声明的,因此它不是外嵌类的成员。所以,这里么关键的地方在于,本地类只能访问final变量或参数。原因在于java编译内部类的方式。
  声明的格式:
class top{
  void examp()
    { class test3 {} }
}


  最后就是传说中的匿名类了,不知道为什么我上次参加的某个涉及java的考试特别爱考它,匿名类之所以匿名,就是因为它没有该死的类名声明的那一行。它直接跟在声明这个匿名类的实例的语句背后,以常用的WindowAdapter来作例子:
public class Demo
{
public static void main(String[] args)
{
final Frame f=new Frame("testtt");
f.setSize(600,400);
f.setLocation(100,100);
final TextArea tf=new TextArea();
f.add(tf);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

  这就是一个相当漂亮的匿名内部类。的声明法。

-----------------------------------------
  前面提到的内部类的编译方法,在我看的书上是这样解释的:
源代码:
public class orange
{
  int i = 0 ;
  void foo() { }

  class pips
  {
    int seeds=2;
    void bar() {}
  }
}

编译时会被分离成:
public class orange
{
  int i = 0 ;
  void foo() { }
}

class orange$pips
{
  int seeds=2;
  void bar() {}
}

  然后,编译程序为内部类提供一个私有的字段用来存储对外嵌类的对象的引用。
pips类就变成了:
class orange$pips
{
  private orange this$0;
  
  orange$pips(orange o)
  {
    this$0 = o ;
  }
  int seeds=2;
  void bar() {}
}


  因此,这个this$0字段就保存了一个orange类的实例的引用,它就可以访问orange类的这个实例的所有成员。
  这个分离的处理方法,也使得本地类和匿名类无法访问嵌套它们的方法中的变量。显然分离之后,方法内的变量无法从外面访问。而final化的变量可以的原因是编译程序会把它作为一个附加的参数传递给内部类的构造函数。

没有评论: