Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1310391
  • 博文数量: 213
  • 博客积分: 7590
  • 博客等级: 少将
  • 技术积分: 2185
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-31 17:31
个人简介

热爱开源,热爱linux

文章分类

全部博文(213)

文章存档

2018年(4)

2017年(1)

2015年(1)

2014年(5)

2013年(2)

2012年(2)

2011年(21)

2010年(82)

2009年(72)

2008年(23)

分类: LINUX

2008-10-24 21:29:33


JAVA的类和方法

文章作者:
责任编辑: 录入时间:2004-10-21 17:34:38 来源:第七频道
频道声明:本频道的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出出处和原始作者 文章版权归本频道与文章作者所有.对于被频道转载文章的个人和网站,我们表示深深的谢意. 

类是JAVA的核心。由于类定义了一个对象的形式与属性,因此整个JAVA语言建立在这个逻辑结构之上。同样,类构成了JAVA面向对象程序设计的基础。任何希望在JAVA程序中实现的想法都必须封装在类中。在一个类中,程序的作用体现在方法中。方法是JAVA创建一个有名字的子程序的方法。

类的基础
类是对象的模板,对象是类的实例。当你定义一个类时,就生命了该类确切的形式和属性。通过指定类中包含的数据和对这些数据进行操作的代码来定义一个类。最简单的类可以只包含代码或只有数据,大部分实际的类二者都有。我们使用关键字class来声明一个类。通常定义class的形式如下所示:


class classname {
   type instance-varable1;
   type instance-varable2;
   //...
   type instance-varableN;
   type metbodname1(parameter-list) {
   //body of method
   }
   type metbodname2(parameter-list) {
   //body of method
   }
   //...
   type metbodnameN(parameter-list) {
   //body of method
   }
}


在一个class中定义的数据或叫变量叫做实例变量。代码包含在方法中。总体来说,类中定义的方法和变量叫做该类的成员。在大部分类中,实例变量由该类所定义的方法调用和访问。
因此,这就决定了类中的数据如何被使用。所有的方法都在类中声明,并且通常都具有如下形式:
   type name(parameter-list) {
   //body of method
   }

在这里,type指定了由方法返回的数据类型。它可以是任意有效的类型,包括你创建的类类型。如果方法没有返回值,则其返回类型必须是void。方法的名字由name指定。这个名字可以是除了那些在当前作用域中已经使用的标识符之外的任意合法标识符。parameter-list是类型、标识符对组成的序列,每对之间用逗号分开。参数实际上是方法被调用时接收传递过来的参数值的变量。如果方法没有参数,则参数表就是空的。除了返回void方法外,那些具有返回类型的方法使用下面的返回语句形式对调用他们的程序返回一个值。
   return value;

value是返回值。下面是一个简单的类的例子:


class Sameple {
   int a,b;
   int sum() {
     return a+b;
   }
}




声明类的对象
每当创建一个类时,就是在创建一个新的数据类型,可以用这个数据类型去声明这种类型的对象。然而,获得一个类的对象一般分两步进行。首先,必须声明这个类型的一个变量,这个变量并没有定义对象本身,而仅仅是一个可以指向对象的变量。第二步,必须获得这个对象的一个实际的物理拷贝,并将其赋给已声明的那个变量。使用new运算完成这一步。
new运算符为对象动态分配(即在程序运行时分配)内存,并为其返回一个引用。该引用或多或少的是由new分配给对象的内存的地址。然后该引用被保存在变量中。因此,JAVA中所有类的对象一定是动态分配的。

下面是一个创建Sample类(前面定义的)对象的例子:
Sample ob = new Sample();

这条语句将刚才提到的两步合二为一了。可以重新写成下面这样一来,更清楚的表示出2步:
Sample ob;
ob = new Sample();

一旦得到一个类对象,就可以使用“.“运算符访问其成员。下面是通常的形式:
object-name.member-name

如,给ob的成员a赋值10,使用下面语句:
ob.a = 10;


构造函数
构造函数在创建对象时立即对其进行初始化。构造函数与它所在的类具有相同的名字,在语句构成上与方法类似。然而,构造函数没有返回值,甚至也不返回void。这是因为类的构造函数隐含的返回类型是类类型本身。初始化对象的内部状态,以便使代码创建实例时有一个完全初始化的、可用的对象是构造函数的任务。
构造函数可以有参数,这些参数接收创建对象时传递给构造的参数。典型情况下,包含在构造函数参数中的这些值用于初始化对象。当创建每个对象的时候,传递给构造函数的参数即被指定。例如,下面是一个加到Sample类中有参数的构造函数的例子。


class Sample {
   int a,b;
// constructor
Sample(int x,int y) {
   a = x;
   b = y;
}
int sum() {
   return a+b;
}
}



下面所示的类创建一个Sample类型的对象,传递给它的值为-99和88。这就是说a将接收值-99,b将接收值88。


class Example {
   public static void main(String args[]) {
     Sample ob = new Sample(-99,88);
     System.out.println(ob.sum());
   }
}



对于一个类,当没有明确定义构造函数时,JAVA创建一个默认的构造函数。默认构造函数自动将所有实例变量初始化为0 。对于简单的类来说,默认的构造函数已足够用,但对于复杂的程序而言通常不会这样做。一旦定义了自己的构造函数,默认的构造函数就不再使用了。


垃圾回收
有些语言,比如C++,动态分配对象必须使用delete运算符手工释放它。而JAVA则采用了不同的方法,自动的重新分配内存。完成这种功能的技术叫垃圾回收。垃圾回收是这样工作的:当一个对象的引用不存在时,这个对象就被认为不再需要的了,它所占用的内存就可以被回收。这时候不需要像C++那样明确的清楚对象。垃圾回收只是在程序执行过程中偶然发生。对于那些已不再使用但仍旧存在的一个或多个对象来说,垃圾回收不会因此而简单的发生。此外,不同的JAVA运行系统采用不同的垃圾回收方法,但对于大多数情况来说,编写程序时不用过多的考虑这些。


finalize()方法
在删除一个对象之前,有时需要确认某些动作已经完成。例如:如果一个对象已经获得了某些系统资源,比如一个文件句柄,那么在删除该对象之前需要确定该资源已经被释放。
JAVA提供了一种叫做终止的机制对这些情况进行处理。使用终止可以定义指定的动作,这个动作在一个对象刚好被垃圾回收器回收时发生。

为类增加一个终止,只需简单的定义finalize()方法。无论何时对那个类中的对象进行回收时,JAVA的运行系统都会调用这个方法。在finalize()方法中指定在一个对象被销毁前所必须要执行的那些动作。finalize()方法的通常形式如下:
protected void finalize()
{
// finalization code here
}

理解finalize()只在垃圾回收前被调用是非常重要的。例如,当对象超出作用域时,finalize()就不会被调用。这意味着不会知道finalize()将会在什么时候执行。因此,程序中应当提供由其它对象使用的释放系统资源的方法。对于一般的程序操作不必依赖finalize()。

方法重载
在JAVA程序中,只要所声明的参数不同,就可以在同一个类中定义两个或更多具有相同名字的方法。当这样做时这些方法就称为被重载,这个过程称为方法重载。当一个重载的方法被调用时,JAVA使用参数的类型和个数取决于实际调用哪一个被重载的方法。因此,重载的方法在参数类型和数量上肯定不会一样。重载的方法可以有不同的返回类型,仅单独使用返回类型不能辨别是哪个方法。当JAVA程序遇到调用重载方法时,它仅仅执行与调用参数相匹配的那个方法。

除一般的方法重载外,也可以重载构造函数。下面举一个方法重载的例子:


// Demonstrate method overload
class OverloadDemo {
   void test() {
   System.out.println("No parameters");
   }
   void test(int a) {
   System.out.println("a:" + a);
   }
   void test(int a,int b) {
   System.out.println("a and b:" + a + " " + b);
   }
   void test(double a) {
   System.out.println("double a: " + a);
   }
}

下面类说明了重载的test()方法。
class Overload {
   public static void main(String args[]) {
   OverloadDemo ob = new OverloadDemo();
   double result;
   // call all versions of test()
   ob.test();
   ob.test(10);
   ob.test(10,20);
   result = ob.test(123.4);
   }
}



参数传递
通常一种计算机语言有两种向子程序传递参数的方法。第一种方法叫做值调用(call-by-value)。
这种方法将一个参数的值复制到子程序的形式参数里。因此,子程序参数的变化并不会影响到用于调用的参数。第二种参数传递的方法叫做引用调用(call-by-reference)。在这种方法中,把一个参数(不是参数的值)的引用传递给形式参数。在子程序里,这个引用用于对调用中指定的实际参数进行访问。这就意味着形式参数的变化会影响到用于调用子程序的参数。JAVA根据传递的内容使用这两种方法。

在JAVA中,当向方法传递一个简单类型时,传递的是一个值。当传递的是一个对象时,则按引用传递。


递归
JAVA支持递归。
下面的例子是如何使用递归方法计算一个阶乘的程序代码:

//A simple exmaple of recursion
class Factorial {
   //this is a recursive method
   int fact(int n) {
   int result;
   if (n == 1) return 1;
   result = fact(n-1) * n;
   return result;
   }
}
class Recursion {
public static void main(String arg[]) {
   Factorial f = new Factorial();
   System.out.println("Factorial of 4 is " + f.fact(4);
   System.out.println("Factorial of 5 is " + f.fact(5);
   }
}




理解static(静态)
当一个类的成员被声明为static时,它可以在这个类的对象被创建之前且没有任何对象的引用存在时被访问。因此,static成员多数被用于全局目的。可以将方法和变量都声明为static。
static最常用的用法是声明main()方法。还可以使用static创建一个可以用来初始化static变量的块。当载入一个类时,一个又一个static块只执行一次。

在类的外部定义的静态方法和变量可以独立的由任何对象使用。使用方法类似于使用通过对象引用变量调用非static的方法。
classname.method()

static变量也可以用相同的方法访问:在类名上使用点运算符。


main()方法
JAVA中,程序从main()方法开始执行。典型的声明如下所示:
public static void main(String arg[])

main()方法被声明为public static以便由在类的外部声明的代码和类的任何对象建立之前调用。

有时,会希望向运行递归程序传递信息。这可以通过向main()传递命令行参数来实现。访问JAVA程序中的命令行参数非常容易,因为它们作为存储在String数组中的字符串被传递给main()。如下面的程序显示调用它时所使用的全部参数:


//Display all commad line arguments
class CommandLine {
   public static void main(String arg[]) [
   for (int i = 0;i < args.length; i++)
      System.out.println("args[" + i + "]: " + args[i]);
   }
}



相下面这样执行此程序:
java CommandLine this is a test 100 -1

当程序运行时,会看到下马的输出:

args[0]: this
args[1]: is
args[2]: a
args[3]: test
args[4]: 100
args[5]: -1

记住,参数是作为字符串传递的。必须手工将数字值转化成它们的内部形式。
阅读(989) | 评论(0) | 转发(0) |
0

上一篇:深入理解硬盘的Linux分区

下一篇:java 数组

给主人留下些什么吧!~~