类与对象
面向对象的编程思想力图在程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出了两个概念,即类与对象。其中,类是对某一类事物的抽象描述,而对象用于表示现实中该事物的个体。
- 对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
- 类:类是一个模板,它描述一类对象的行为和状态。
下图中男孩(boy)、女孩(girl)为类(class),而具体的每个人为该类的对象(object):
一、类的定义
在面向对象的思想中最核心的就是对象,为了在程序中创建对象,首先需要定义一个类。类是对象的抽象,它用于描述一组对象的共同特征和行为。类中可以定义成员变量和成员方法,其中成员变量用于描述对象的特征,也被称为属性,成员方法用于描述对象的行为,可简称为方法。
范例:Person类
1 public class Person { 2 //定义int类型的变量age 3 int age; 4 //定义speak方法 5 void speak(){ 6 System.out.println("大家好,我今年" + age +"岁!"); 7 } 8 }
Person是类名,age是成员变量,speak()是成员方法。在成员方法speak()中可以直接访问成员变量age。
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
- 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
- 类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。
在speak()方法中有一条打印语句,访问了变量age,此时访问的是局部变量。
二、对象的创建与使用
应用程序想要完成具体的功能,仅有类是远远不够的,还需要根据类创建实例对象,
对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:
- 声明:声明一个对象,包括对象名称和对象类型。
- 实例化:使用关键字 new 来创建一个对象。
- 初始化:使用 new 创建对象时,会调用构造方法初始化对象。
对象的定义:
一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:
访问类中的属性:对象.属性 ;
调用类中的方法:对象.方法();
1 public class Example { 2 public static void main(String[] args) { 3 Person p1 = new Person(); //创建第一个Person对象 4 Person p2 = new Person(); //创建第二个Person对象 5 p1.age = 18; //为age属性赋值 6 //调用对象的speak()方法 7 p1.speak(); 8 p2.speak(); 9 } 10 }
运行结果:
通过p1.age =18将p1对象的age属性赋值为18,但并没有对p2对象的age属性赋值,所以会按成员变量类型的初始值进行赋值。
注意:局部变量必须初始化,即赋值,才能使用(它没有默认值)
三、类的设计
在Java中,对象都是通过类创建出来的。因此,在程序设计时,最重要的就是类的设计。
假设在程序中描述一个学校所有学生的信息,可以先设计一个学生类(Student),在这个类中定义两个属性name和age分别表示学生的姓名和年龄,定义一个方法introduce()表示学生做自我介绍。
1 public class Student { 2 String name; 3 int age; 4 public void introduce(){ 5 //打印属性name和age的值 6 System.out.println("大家好,我叫" + name +",我今年"+age +"岁!"); 7 } 8 }
针对设计的Student类创建对象,并访问该对象的成员
1 public class Example { 2 public static void main(String[] args) { 3 Student stu = new Student(); //创建学生对象 4 stu.name ="张三";//为name属性赋值 5 stu.age = -18; //为age属性赋值 6 //调用对象的introduce()方法 7 stu.introduce(); 8 } 9 }
运行结果:
将年龄赋值为一个负数-18,这在程序中不会有任何问题,但在现实生活中明显是不合理的。为了解决年龄不能为负的问题,在设计一个类时,应该对成员变量的访问做出一些限定,不允许外界随意访问,这就需要实现类的封装。
四、类的封装
所谓类的封装是指在定义一个类时,将类中的属性私有化,即用private关键字来修饰,有属性只能在它所在类中被访问。为了能让外界访问私有属性,需要提供一些public修饰的公共方法,其中包括用于获取属性值的getXxx()方法和设置属性值的setXxx()方法。
1 public class Student { 2 private String name; 3 private int age; 4 5 //下面是公有的getXxx()和setXxx()方法 6 public String getName() { 7 return name; 8 } 9 10 public void setName(String name) { 11 this.name = name; 12 } 13 14 public int getAge() { 15 return age; 16 } 17 18 public void setAge(int age) { 19 //下面是对传入的参数进行检查 20 if (age <= 0){ 21 System.out.println("年龄不合法!"); 22 }else { 23 this.age = age; 24 } 25 } 26 27 public void introduce(){ 28 //打印属性name和age的值 29 System.out.println("大家好,我叫" + name +",我今年"+age +"岁!"); 30 } 31 } 32 33 class Example { 34 public static void main(String[] args) { 35 Student stu = new Student(); //创建学生对象 36 stu.setName("张三"); //为name属性赋值 37 stu.setAge(-18); //为age属性赋值 38 //调用对象的introduce()方法 39 stu.introduce(); 40 } 41 }
运行结果:
在上面的Student类中,使用private关键字将属性name和age声明为私有,对外界提供了几个公有的方法,其中getName()方法用于获取name属性的值,setName()用于设置name属性的值;同理,getAge()和setAge()用于获取和设置age属性的值。在main()方法中创建Student对象,并调用setAge()方法传入一个负数-18,在setAge()方法中会对参数setAge的值进行检查,由于当前传入的值小于0,因此会打印“年龄不合法!”的 信息,age的属性没有被赋值,仍为默认值0。