第四章 方法操作实例变量
对象有状态(实例变量)和行为(方法)
类是对象的蓝图。在编写类时,你是在描述Java虚拟机应该如何制作该类型的对象。你已经知道每个对象有独立的实例变量值,但方法呢?
同一类型的每个对象可以有不同的方法。任一类的每个实例都带有相同的方法,但是方法可以根据实例变量的值来表现不同的行为。比如通过Dog类创建的Dog对象可能是大型犬对象,也可能是小型犬对象,那么他们的叫声就会不一样:
class Dog{ //Dog类
int size; //dog的大小
String name; //dog的名字
void bark(){ //让dog叫的方法
if(size>60){ //如果dog大于60 就Wooof!Wooof!的叫
System.out.println("Wooof!Wooof!");
}else if(size>14){ //如果dog大于14 就Ruff!Ruff!的叫
System.out.println("Ruff!Ruff!");
}else{ //如果小于14 就Yip!Yip!的叫
System.out.println("Yip! Yip!");
}
}
}
带参数的方法
你可以传值给方法。举例来说,你可能会要告诉dog对象叫几声:d.bark(3);
由于不同的程序设计背景和个人喜好,你可能会用实参或形参来调用传给方法的参数。我们可以这样区分:
方法会运用形参,调用的一方会传入实参。实参是传给方法的值。方法上声明的值是形参。
参数跟局部变量是一样的。它有类型与名称,可以在方法内调用。
重点是:如果,某个方法需要参数,你就一定得传东西给他,不然就会编译失败。
void bark(int x){ //括号里面的就是形参,这里接收一个int型的参数
while(x>0){
System.out.println("ruff");
x = x-1;
}
}
//当创建对象并调用方法的时候
Dog d = new Dog();
d.bark(3);//这里括号内传入的就是实参,把3传给所调用的方法后,方法就会将接收到的变量当做自己的临时变量来用
当有多个形参时,实参的类型和顺序要与形参相同。参数之间由逗号隔开:
void bark(int x,int y){
}
bark(3,5);
带有返回值的方法
方法可以有返回值。每个方法都声明返回的类型,但目前我们都是把方法设为返回void类型,这代表没有返回任何东西。
void go(){
}
但我们可以声明一个方法,回传给调用方指定的类型值,如:
int giveSecret(){
return 42;//使用return返回
}
如果你讲一个方法声明有返回值,你就必须返回所声明的类型的值。调用带返回值的方法时,就可以接受其返回值:
int x = giveSecret(); //接收返回的42这个值
封装
我们之前一直在翻一个错误,就是将实例变量暴露出来。暴露的意思是可以通过圆点运算符来存取,像是:
tehCat.height = 27;
如果这样的话,别人在使用你的变量时,就可以随意更改数值,例如将身高改为0cm之类的。
我们需要做的就是将实例变量标记为private(私有的),然后通过public(公有的)setter和getter方法存取这个变量,这样我们就可以在别人存取变量是增加一些限制条件。比如封装一个Dog对象:
class Dog{
private int size;
public void setSize(int s){
size = s;
} //setter方法
public int getSize(){
return size;
} //getter方法
}
class GetDog{
public static void main(String[] args){
Dog d = new Dog();
d.setSize(20); //调用setter方法
int s =d.getSize(); //调用getter方法
}
}
数据的默认值
基本数据类型和引用数据类型都有默认值:int的默认值是0,double的默认值是0.0,float的默认值为0.0f,boolean的默认值是false,String的默认值是null;
实例变量与局部变量之间的区别
1. 实例变量是声明在类内而不是方法中。
class Horse{
private double height = 15.2;
private String breed;
//.....
}
2. 局部变量是声明在方法中的
class AddTing{
int a;
int b=12;
public int add(){
int total = a+b; //这里是局部变量
return total;
}
}
3. 局部变量在使用前必须初始化
class Foo{
public void go(){
int x;
int z = x+3;//这里无法通过编译,你可以声明没有值的x,但想要使用时编译器就会给出警示
}
}