对象的行为—方法操作实例变量
状态影响行为,行为影响状态。
1.对象由状态和行为
1)类所描述的是对象知道什么与执行什么?
类是对象的蓝图。在编写类时,你是在描述Java虚拟机应该如何制造该类型的对象。你已经知道每个对象有独立的实例变量值。
2)同一类型的每个对象能够由不同的方法和行为吗?
任一类的每个实例都带有相同的方法,但是方法可以根据实例变量的值来表现不同的行为。
2.方法的参数
1)你可以传值给方法
方法会运用参数。调用的一方会传入实参。
实参是传给方法的值。它传入方法后就成了形参。参数跟局部(local)变量是一样的。它有类型与名称,可以在方法内运用。
重点是:如果某个方法需要参数,你就一定得传东西给它。那个东西是适当类型的值。
2)你可以从方法中取返回值
方法可以有返回值。每个方法都声明返回的类型,但目前我们都是把方法设成返回void类型,这代表并没有返回任何东西。
eg:void go(){}
但我们可以声明一个方法,回传给调用方指定的类型值。
eg:int giveScret(){
return 42;
}
3)你可以向方法中传入一个以上的参数
方法可以有多个参数。在声明的时候要用逗号分开,传入的时候也要用逗号分开。最重要的是,如果方法有参数,一定要以正确数量、
类型和顺序来传递参数。
(1)调用需要两个参数的方法,并传入两个参数:
void go(){
TestStuff t = new TestStuff();
t.takeTwo(12,34);
}
void takeTwo(int x,int y){
int z=x+y;
System.out.println("Total is"+z);
}
(2)你可以将变量当作参数传入,只要类型相符就可以:
void go(){
int foo = 7;
int bar = 3;
t.takeTwo(foo,bar);
}
4)Java是通过值传递的,也就是说通过拷贝传递
//声明一个int类型的变量并赋值为7。代表7的字节组合会放进称为x的变量中。
int x = 7;
//声明一个有int参数的方法,参数名称为z
void go(int z){}
//以x为参数传入go()这个方法中。x的字节组合会被拷贝并装进z中。
foo.go(x);
//在方法中改变z的值。此时x的值不会改变!传给z的只是个拷贝。
//方法无法改变调用方法所传入的参数
void go(int z){
z=0;
}
3.要点
1)类定义对象所知及所为
2)对象所知者是实例变量
3)对象所为者是方法
4)方法可依据实例变量来展现不同的行为
5)方法可使用参数,这代表你可以传入一个或多个值给方法
6)传给方法的参数必须符合声明时的数量、顺序和类型
7)传入与传出方法的值类型可以隐含地、放大或是明确地缩小
8)传给方法的参数值可以是直接指定的文字或数字(2或’c’)或者是与所声明参数相同类型的变量
9)方法必须声明返回类型。使用void类型代表方法不返回任何东西
10)如果声明了非void的返回类型,那就一定要返回与声明类型相同的值
4.运用参数与返回类型
Getter与Setter可让你执行get与set.Getter的目的只有一个,就是返回实例变量的值。Setter的目的,就是要取用一个参数来设定实例变量的值。
public class ElectricGuitar {
String brand;
int numOfPickups;
boolean rockStarUsesIt;
String getBrand(){
return brand;
}
void setBrand(String aBrand){
brand = aBrand;
}
int getNumOfPickups(){
return numOfPickups;
}
void setNumOfPickups(int num){
numOfPickups = num;
}
boolean getRockStarUsesIt(){
return rockStarUsesIt;
}
void setRockStarUsesIt(boolean yesOrNo){
rockStarUsesIt = yesOrNo;
}
}
5.封装(Encapsulation)
1)可以防止变量值被修改。
eg:tehCat.height = 27;有可能被修改成tehCat.height = 0;
所以我们需要创建Setter这个方法强制其他程序都必须通过Setter来设定变量而不是直接的存取。
eg:public void setHeight(int ht){
//这个检查可以确保高度不会低于9
if(ht>9){
height = ht;
}
}
2)数据隐藏
如何隐藏数据?可以使用公有与私有这两个存取修饰符(access modifier)
public class GoodDog {
//将实例变量设定private的
private int size;
//将getter与setter设定为public
public int getSize(){
return size;
}
public void setSize(int s){
size = s;
}
void bark(){
if(size>60){
System.out.println("Wooof! Wooof!");
}else if(size>14){
System.out.println("Ruff! Ruff!");
}else{
System.out.println("Yip! Yip!");
}
}
}
public class GoodDogTestDrive {
public static void main(String[] args) {
GoodDog one = new GoodDog();
one.setSize(70);
GoodDog two = new GoodDog();
two.setSize(8);
System.out.println("Dog one:"+one.getSize());
System.out.println("Dog two:"+two.getSize());
one.bark();
two.bark();
}
}
3)封装的基本原则
将你的实例变量标记为私有的,并提供公有的getter与setter来控制存取动作。
将实例变量标记为private。
将getter与setter标记为public。
任何有值可以被运用到的地方,都可用调用方法的方式来取得该类型的值。
eg:int x = 3 + 24;
可以这样写:
eg:int x = 3 + one.getSize();
6.初始化实例变量
实例变量永远都会有默认值。如果你没有明确的赋值给实例变量,或者没有调用setter,实例变量还是会有值!
integers(整型) 0
floating points(浮点数) 0.0
booleans(布尔值) false
references(引用) null(代表没有操作对象的远程控制,它是个引用而不是对象)
public class PoorDog {
//声明实例变量但是不给值
private int size;
private String name;
public int getSize() {
return size;
}
public String getName() {
return name;
}
}
public class PoorDogTestDrive {
public static void main(String[] args) {
PoorDog one = new PoorDog();
System.out.println("Dog size is "+one.getSize());
System.out.println("Dog name is "+one.getName());
}
}
7.实例变量与局部变量之间的差别
1)实例变量是声明在类内而不是方法中
class Horse{
private double height=15.2;
private String breed;
}
2)局部变量是声明在方法中的
class AddThing{
int a;
int b=12;
public int add(){
int total=a+b;
return total;
}
}
3)局部变量在使用前必须初始化
class Foo{
public void go(){
int x;
//无法编译!你可以声明没有值的x,但若要使用时编译器就会给出警示
int z=x+3;
}
}
局部变量没有默认值!如果在变量被初始化前就要使用的话,编译器会显示错误。
8.对象的相等
变量的比较(primitive主数据类型或引用)
1)使用==来比较两个primitive主数据类型,或者判断两个引用是否引用同一个对象。
2)使用equals()来判断两个对象是否在意义上相等。