对象有状态和行为
类所描述的是对象知道什么(实例变量/属性)和执行什么(方法)。
方法操作实例变量
1、方法的参数
既然说到参数,那么肯定要涉及到形参和实参。
方法运用形参,调用的一方会传入实参。
按照我自己的理解:
形参是一种形式上的参数(变量),并不具体。
实参是指有实实在在的值传给方法。
比如事例中的bark()方法:
void bark(int numOfBarks)
{
while(numOfBarks > 0)
{
System.out.println("ruff");
numOfBarks--;
}
}
变量numOfBarks就是形参,在调用前它只起到形式上的作用代表叫几声,但是并不能确定要叫几声。
Dog dog = new Dog();
int num = 3;
dog.bark(3);
dog.bark(num);
上述传给Dog对象中bark()方法的3和num都可以称之为实参。
2、可以从方法中返回值
说好了要返回,最好就得返回。
请看下面的的几个例子:
case 1:无返回值
public class ReturnTest{
public static void main(String[] args)
{
int value = 3;
int ret = 0;
ReturnTest test = new ReturnTest();
ret = test.ReturnCase(value);
System.out.printf("I get return value:%d from ReturnCase1 in main\n", ret);
}
int ReturnCase(int value)
{
System.out.printf("I get value:%d In ReturnCase1\n", value);
//return value+1;
//return;
}
}
在case1中,ReturnTest类中的方法ReturnCase1(),定义有返回值,但在该方法中并没有没有明确的指定返回值(被屏蔽了)。
因此编译的时候会报错提示没有返回指。
注:此处是指没有返回值而不是返回语句。如果只有return语句而没有指,那么是编译不通过的,可见,Java对于类型的匹配要求相当之严格。如图:
那么我们再来说说C语言对于返回值的问题。同样一个code用C写的,如下:
#include <stdio.h>
int ReturnCase(int value)
{
printf("I get value:%d In ReturnCase1\n", value);
//return value+1;
return;
}
void main(void)
{
int value = 3;
int ret = 0;
ret = ReturnCase(value);
printf("I get return value:%d from ReturnCase1 in main\n", ret);
getchar();
}
同样只有return语句,但并不返回值。这段code是可以编译通过的,但编译器给出了警告:
D:\VC++6.0\MSDev98\MyProjects\ReturnTest\ReturnTest.c(7) : warning C4033: ‘ReturnCase’ must return a value
D:\VC++6.0\MSDev98\MyProjects\ReturnTest\ReturnTest.c(8) : warning C4716: ‘ReturnCase’ : must return a value
提示你一定要返回一个值。
我不管那么多还是照常点击运行,运行结果如图:
傻了眼,竟然有返回且返回的结果是29。那么问题来了,为什么C要这样设计呢?规定一个返回值但却可以什么都没返回。
case2:调用方法的一方舍弃返回值
public class ReturnTest{
public static void main(String[] args)
{
int value = 3;
int ret = 0;
ReturnTest test = new ReturnTest();
test.ReturnCase(value);
//ret = test.ReturnCase(value);
System.out.printf("I get return value:%d from ReturnCase1 in main\n", ret);
}
int ReturnCase(int value)
{
System.out.printf("I get value:%d In ReturnCase1\n", value);
return value+1;
}
}
在case2中,调用ReturnCase1()方法但并没有去接收其返回值。这样子是可以的。输出如下:
case3:返回数组类型
public class ReturnTest{
public static void main(String[] args)
{
int[] value = new int[3]; // 传给ReturnCase()方法的对象引用变量(实参)
int[] ret = new int[3]; // 存放从ReturnCase()方法返回的对象引用变量(返回值)
value[0] = 1; // 对象实例化
value[1] = 2;
value[2] = 3;
ReturnTest test = new ReturnTest();
ret = test.ReturnCase(value);
System.out.printf("I get return value:%d, %d, %d from ReturnCase in main\n", ret[0], ret[1], ret[2]);
System.out.printf("The current value:%d, %d, %d in main\n", value[0], value[1], value[2]);
}
int[] ReturnCase(int[] LocalValue)
{
int i = 0;
System.out.printf("I get value:%d , %d, %d In ReturnCase\n", LocalValue[0], LocalValue[1], LocalValue[2]);
for(i=0; i<LocalValue.length; i++)
LocalValue[i] += 1;
return LocalValue;
}
}
输出如下:
注意传入方法的value所指向的对象也变化了。下面会讲为什么。
采用此方法可以返回多个返回值。
3、多个参数
你可以向方法中传入一个以上的参数。最重要的是:如果方法有参数,你一定要以正确的数量、类型和顺序来传递参数。这一点打死都不能变。
4、Java是通过值传递的
书中给出了值传递的详细过程。但是为什么上面的case3中value所指向的对象的值被修改了呢?
因为在调用ReturnCase()的时传递给他的不是整个对象,而是指向引用对象变量,通俗点就是前面章节指的遥控器的一份拷贝。也就是说有两个遥控器同时控制同一个对象。那么一个遥控器修改了对象的值,那么从另一个遥控器读取对象的值肯定也是修改之后的。
封装
说得简单点就是:将类中的实例变量标记为私有的,并提供共有的getter和setter方法来控制存取动作。