类与对象

1. 类和对象的基本概念

类的概念是方便设计程序是描述日常生活中的事物。

  • 是对一类事物概念上的描述(定义);
  • 对象是该类事物的具体个体;
  • 比如:学生就是一个(一个类别),Wang * Kai就是一个学生的对象(一个具体的个体)。

例. 程序中需要用到“猫”,那么我们可以定义一个Cat类,我们需要用到猫的年龄名字owner,并且需要猫做一个动作:发出声音。 定义了猫(Cat类)后,我们就可以根据实际情况实例化猫(创建一个一个具体的猫),比如

  • XU, Xiaoyan养了一只猫:叫Ame,3岁;
  • YE, Yang养了另一只猫:叫Tommy, 4岁;
  • LIU, Xiaoyan养了另一只猫:叫汤圆, 5岁;

我们先假定猫猫都能发出“Meow Meow”的声音,上面定义的猫的类,以及三只具体的猫可用下图表示:

Fig.1. 类和对象的例子

2. Java定义类及创建对象

2.1 创建一个Cat类

  • (1) 创建一个新的project: cs_course_oop
  • (2) 创建一个新的package: animal
  • (3) 在animal包里创建一个类Cat

创建好后,我们得到如下一个Java类,其中 class 关键字表明这是一个Cat类名

Cat.java

package animal;

public class Cat {

}

然后我们给Cat类添加上我们需要的属性:年龄,名称,和owner:

package animal;

public class Cat {

	// Cat的属性(成员变量)
	public int age = 0;
	public String name = "";
	public String owner = "";
	
}

这里,变量age, name, owner是定义在Cat类的代码块里的,所以它们是属于Cat类的变量,叫做Cat成员变量,或者叫做Cat属性,英文名Field.

我们再给Cat添加一个行为makeNoise(),使得猫猫可以发出声音:
(一般我们称呼类的行为为成员方法

package animal;

public class Cat {

    // Cat的属性(成员变量),并初始化
	public int age = 0;
	public String name = "";
	public String owner = "";

    // Cat的行为(成员方法),使用了name属性
	public void makeNoise() {
		System.out.println(name + " says: Meow Meow");
	}
	
}

2.2 通过上面定义的Cat类创建具体的猫猫

animal包里创建类CatExample, 并为它添加main方法;

  • (1) 我们用Cat cat1 = new Cat(); 创建一只猫的实例(对象):
    • 这个对象叫cat1, 其类型是Cat。其遵循 类型 变量名 的范式,Cat cat1;int a;, String str;是一样的范式;
  • (2) cat1.age = 3;cat1的age设置为3cat1.age可以简单理解为 cat1age
  • (3) cat1.name = "Ame"; cat1name设置为"Ame"cat1.owner类似;
  • (4) 通过cat1.makeNoise()调用cat1makeNoise()方法。

CatExample.java

package animal;

public class CatExample {

	public static void main(String[] args) {
		
		// Create the first Cat object: cat1
		Cat cat1 = new Cat();
		
		//设置 cat1这只猫的属性
		cat1.age = 3;
		cat1.name = "Ame";
		cat1.owner = "Xiaoyan Xu";
		
		// 调用cat1的方法,让她发出声音
		cat1.makeNoise();
	}

}

运行结果:Ame says: Meow Meow

我们可以用Cat类创建任意多只我们想要的猫,比如,在上面的例子中,添加第二只猫:

import animal.Cat;

public class CatExample {

	public static void main(String[] args) {
		
		// Create the first Cat object: cat1
		Cat cat1 = new Cat();
		
		//设置 cat1这只猫的属性
		cat1.age = 3;
		cat1.name = "Ame";
		cat1.owner = "XU, Xiaoyan";
		
		// 调用cat1的方法,让她发出声音
		cat1.makeNoise();
		
		// Create the second Cat object: cat1
		Cat cat2 = new Cat();
		
		//设置 cat2这只猫的属性
		cat2.age = 4;
		cat2.name = "Tommy";
		cat2.owner = "YE, Yang";
		
		// 调用cat2的方法,让她发出声音
		cat2.makeNoise();
		
	}

}

运行结果:

Ame says: Meow Meow Tommy says: Meow Meow

练习. 创建第三只猫,并调用她的makeNoise()方法。

注.

    1. 上面的例子中,Cat类的makeNoise()方法使用了它的name属性。而在创建cat1后,我们通过cat1.name = "Ame"cat1name属性设置为"Ame",所以cat1发出声音时是:Ame says: Meow Meow。而创建cat2后,他的name属性被设置为Tommy,所以调用cat2makeNoise()方法时,他make Noise时是"Tommy says: Meow Meow"
    1. 对象cat1/cat2的成员变量和成员方法,与我们之前讨论中出现的变量和方法没有区别,只是他们属于那个对象,而不是属于CatExamplemain方法。
    • 所以我们想要使用猫cat1name属性,需要用cat1.name,想要使用猫cat2name属性,用cat2.name
    • 例如:我们可以通过如下方式,打印cat1的综合信息
      System.out.printf("The first cat named %s is %d years old, "
              + "and owned by %s", cat1.name, cat1.age, cat1.owner);
    

2.3 向对象的方法传递参数并获得返回值

如上所述,如果对象的方法和以前讨论的方法没有区别,那么我们应该也可以向对象的方法传递参数,并获得返回值。

例.

  • 在上面的例子中,我们给猫增加一个学习说话的方法,猫会随机地模仿让她说的话。
  • 需要将要她学习的话作为参数传递给方法;
  • 她执行完后返回一个是否说正确的值。
package animal;

public class Cat {

    // Cat的属性(成员变量),并初始化
	public int age = 0;
	public String name = "";
	public String owner = "";

    // Cat的行为(成员方法),使用了name属性
	public void makeNoise() {
		System.out.println(name + " says: Meow Meow");
	}
    
    // 学习说话的方法
    public boolean learnToSay(String somethingToSay){
    	Random rand = new Random();
    	double prob = rand.nextDouble();
    	if(prob > 0.5) {
    		System.out.println(name + " says: " + somethingToSay);
    		return true;
    	}else {
    		System.out.println(name + " says: " + "Meow Meow");
    		return false;
    	}
    }
	
}

然后在CatExamplemain方法里调用这个方法。(前面的代码已省略)

// flag1 用来捕获cat1.learnToSay返回值:true代表模仿对了,false代表模仿错了
    boolean flag1 = cat1.learnToSay("快去给我挣猫粮!");
    if (flag1) {
        System.out.println(cat1.owner + ": brilliant!");
    } else {
        System.out.println(cat1.owner + ": Oops!");
    }

//flag2 捕获cat2 learnToSay的返回值
    boolean flag2 = cat2.learnToSay("世界的秩序将由我们建立!");
    if (flag2) {
        System.out.println(cat2.owner + ": brilliant!");
    } else {
        System.out.println(cat2.owner + ": Oops!");
    }

附录:创建第三只猫猫,并调用其方法(这里我们没有捕获learnToSay的返回值)

    Cat cat3 = new Cat();
    cat3.age = 5;
    cat3.name = "汤圆";
    cat3.owner = "LIU, Xiaoyan";
    
    cat3.learnToSay("Stay away from me!");