一、 方法的重载
在JAVA面向对象编程中,方法的重载是应用非常广泛的技术。例如,在编程中,经常要用到把信息打印到控件台中,打印信息的函数是PrintStream类的方法println(),这个函数可以打印出基本数据类型变量和对象变量信息。
什么是重载函数?重载函数首先是方法名称相同,但参数个数不同、参数数据类型不同、参数数据类型顺序不同。所以,对象在调用方法重载时,判断调用哪个方法,是通过参数个数、参数数据类型、参数数据类型顺序来区分开来,而不是方法名。
在应用中,方法的重载主要应用在对象构造函数和成员函数。当定义一个对象变量时,要用到new运算符,这时要调用对象的构造函数。类的构造函数可能有多个,这时系统怎么判断调用的是哪个构造函数,就是以过参数个数、参数数据类型、参数数据类型顺序来区分。对象的成员函数也是这样。
现在来定义一个坐标Point类:
public class Point{ int x; int y; Point(int a, int b){ x = a; y = b; } Point(){} public void output(){ System.out.println(“x:”+x+”,y:”+y); } public void output(int a, int b){ x = a; y = b; System.out.println(“x:”+x+”,y:”+y); } public static void main(String args[]){ Point p1 = new Point(); Point p2 = new Point(1,1); p1.output(); p1.output(2,2); p2.output(); p2.output(3,3); } }
编译结果: x:0,y:0 x:2,y:2 x:1,y:1 x:3,y:3 |
二、 this变量
this变量如同对象变量、类实例一样,可调用自身的属性和函数,this变量表示对象本身。this变量普通作用于下列两种情况:
情况1:当类中有两个同名变量,一个属于类(类的成员属性),而另一个属于某个特定的方法(方法中的局部变量),使用this区分成员变量和局部变量。
现在来定义Point类,希望打印出x:3,y:3
public class Point{ int x; int y; Point(){ } public void output(){ System.out.println("x:"+x+",y:"+y); } public void output(int x, int y){ x = x; y = y; } public static void main(String args[]){ Point p2 = new Point(); p2.output(3,3); p2.output(); } } |
结果打印的消息:x:0,y:0,这显然不是希望得到的结果。剖析原因,可以发现在这个类中,出现了成员属性和成员函数局部变量同名现象,根据系统的规定,在这种情况下,成员属性被成员函数局部同名变量所隐藏所履盖,在成员函数是成员属性是不可见的,所以x = x其实是成员函数局部变量对自身的赋值。修改的方法可以把局部变量改名,(int x, int y)改成(int a, int b),但如果不想使用这种方法,这时this关键字可以派上用场,把x = x修改成this.x = x,把y = y修改成this.y = y。修改后打印的消息:x:3,y:3
情况2:使用this简化构造函数的调用。
当一个类中有多个构造函数,当其中一个构造函数想要调用另外一个构造函数时,就可以使用this变量来实现。
现在来定义一个Point类:
public class Point{ int x; int y; Point(int x, int y){ this.x = x; this.y =y; } Point(){ this(1,1); } public void output(){ System.out.println("x:"+x+",y:"+y); } public static void main(String args[]){ Point p = new Point(); p.output(); } } |
打印的结果:x:1,y:1
一个类所有的实例(对象)调用的成员方法在内存中只有一份拷贝,尽管在内存中可能有多个对象,而数据成员在类的每个对象所在内存中都存在着一份拷贝。this变量允许相同的实例方法为不同的对象工作。每当调用一个实例方法时,this变量将被设置成引用该实例方法的特定的类对象。方法的代码接着会与this所代表的对象的特定数据建立关联。
三、 实例变量、实例函数、静态变量、静态函数说明
现在定义这么一个类
public class TestClass{ int a; static int b; public void printA(){ System.out.println(a); } public static void printB(){ System.out.println(b); } } |
在TestClass类中,像a这样的变量就是实例变量,printA()是实例函数;b是静态变量,也称类变量,printB()是静态函数,也称类方法。
在JAVA面向对象编程有这样规定,实例变量和实例函数只有类实例(对象)才能调用,是属于类的对象,类是不能调用的。这是为什么?在程序运行中,不管是变量,还是函数,在运行前必须分配内存空间,不然程序将会出错。实例变量、实例函数其内存空间是随着类实例的创建而被分配的。所以类实例可以调用实例变量、实例函数。而类调用实例变量、实例函数时,实例变量、实例函数根本没有被分配内存空间,这显然是不可能的。
而静态变量、静态函数为什么可以被类调用呢?当存在静态变量、静态函数的类在程序中第一次被调用时,静态变量、静态函数就被分配了内存空间。条件满足了,静态变量、静态函数就可以被类调用,当然也可以被类实例所调用。
总之,类实例可以调用实例变量、实例函数、静态变量、静态函数;而类只能调用静态变量、静态函数。
现在来定义这么一个类:
public class Point{ int x; //实例变量 static int y; //静态变量 Point(){} public void output1(){ //实例函数 System.out.println("x:"+x+",y:"+y); } public static void output2(){ //静态函数 System.out.println("y:"+y); } public static void main(String args[]){ Point p = new Point(); p.x = 1; //类实例引用实例变量 p.y = 1; //类实例引用静态变量 p.output1(); //类实例调用实例函数 p.output2(); //类实例调用静态函数
Point.y = 5; //类调用静态变量 Point.output2(); //类调用静态函数 } }
编译结果: x:1,y:1 y:1 y:5 |
四、 常量定义
使用关键字final定义常量,例如:final double PI=3.1415926;
作为一种约定,在定义常量时,通常采用大写形式。
final常量可以在声明的同时赋初值,也可以在构造函数中赋初值。
为了节省内存,我们通常将常量声明为静态的(static)。