6.1 类和对象概述
面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。早期的计算机编程是面向过程的,解决的都是一些相对简单的问题。随着IT行业不断发展,计算机被用于解决越来越复杂的问题。通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成关联、继承、实现、依赖等关系,从而帮助人们实现对现实世界的抽象与建模。通过面向对象的方法,更利于用人容易理解的方式,对复杂系统进行分析、设计与开发。同时,面向对象也能有效提高编程的效率,通过封装技术和消息机制可以像搭积木一样快速开发出一个全新的系统。
Java是一种面向对象的语言,因此Java开发人员要学会用面向对象的思想考虑问题和编写程序。从现实世界中客观存在的事物出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式,这是面向对象设计思想的核心。面向对象更加强调运用人类在日常的思维逻辑中经常采用的思想方法与原则,如封装、抽象、继承和多态等。
现实世界中,万物皆对象,一辆汽车、一间房子、一张支票、一个桌子也是对象,甚至一项计划、一个思想都是对象。
在Java面向对象编程中,将这些对象的属性仍然称为属性,将对象具有的行为称为方法。
类是对具有相同属性和相同行为的对象的抽象。通过类,可以创建出一个一个的对象,通常也称为实例化出一个一个对象。
6.2 Java类
Java API提供了一些现有的类,程序员可以使用这些类来创建对象,例如String类。除了使用现有的Java类,程序员还可以自定义Java类。
Java类的定义
类是Java程序的基本单元。Java是面向对象的程序设计语言,所有程序都是由类组织起来的。下面是类定义的语法形式。
public class 类名{
//定义类属性
属性1类型:属性1名;
属性2类型:属性2名;
…
//定义方法
方法1定义
方法2定义
…
}
在Java中,class是用来定义类的关键字,class关键字后面是要定义的类的名称,然后有一对大括号,大括号里写的是类的主要内容。
类的主要内容也分两部分,第一部分是类的属性定义,在类内部、方法外部定义的变量称为成员变量,这里类的属性就是类的成员变量,这两个概念是相同的。第二部分是类的方法定义,通过方法的定义,描述类具有的行为,这些方法也可以称为成员方法。
Java类的创建和使用
定义好类后,就可以根据这个类创建(实例化)对象了。类就相当于一个模板,可以创建多个对象。创建对象的语法形式如下。
类名 对象名 = new 类名();
创建对象时,要使用new关键字,后面要跟着类名。通常在创建对象后给对象的属性赋值。在Java语言中,通过“.”操作符来引用对象的属性和方法,具体的语法形式如下。
对象名.属性;
对象名.方法;
在未给对象属性赋值前使用属性时,如果该属性为引用数据类型,其初始默认值为null,如果该属性是int型,其初始默认值为0。
封装
封装就是将抽象得到的属性和行为结合起来,形成一个有机的整体,就是类。类里面的一些属性和方法(尤其是属性),需要隐藏起来,不希望直接对外公开,但同时提供供外部访问的方法来访问这些需要隐藏的属性和方法。
封装的目的是增强安全性和简化编程,使用者不必了解具体类的内部实现细节,而只是要通过提供给外部访问的方法,来有限制地访问类需要隐藏的属性和方法。
所谓良好的封装,就是使用private对属性进行封装,从而保护信息的安全。使用public修饰方法时,外界可以调用该方法,通常将设置私有属性的值和获取私有属性值的方法称为setter和getter方法。
6.3 构造方法
构造方法(也称为构造函数)是一种特殊的方法,它具有以下特点。
- 构造方法的方法名必须与类名相同。
- 构造方法没有返回类型,也不能定义为void,在方法名前不声明返回类型。
其实构造方法是有返回值的,返回的是刚刚被初始化完成的当前对象的引用。既然构造方法返回被初始化对象的引用,为什么不写返回值类型呢?例如Student类构造方法为什么不写成 public Student Student(参数列表){…}呢?
因为Java设计人员把这种方法名(类名)和返回类型的类名相同的方法看成一个普通方法,只是名称“碰巧”相同罢了,编译器识别时也会认为它是一个方法。为了和普通方法进行区别,Java设计人员规定构造方法不写返回值,编译器通过这一规定识别构造方法,而不是说构造方法真的没有返回值。
构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象。一个类可以定义多个构造方法,根据参数的个数、类型或排列顺序来区分不同的构造方法。
public class Student {
private String stuName;
private int stuAge;
private int stuSex;
private int stuGrade;
//构造方法,用户初始化对象的属性
public Student(String name,int age,int sex,int grade){
this.stuName = name;
this.stuAge = age;
this.stuSex = sex;
this.stuGrade = grade;
}
//构造方法,用户初始化对象的属性(不带年级参数,设置年级默认值为4)
public Student(String name,int age,int sex){
this.stuName = name;
this.stuAge = age;
this.stuSex = sex;
this.stuGrade = 4;
}
//构造方法,用户初始化对象的属性
//不带年龄、年级参数,设置年龄默认值为22,年级默认值为4
public Student(String name,int sex){
this.stuName = name;
this.stuAge = 22;
this.stuSex = sex;
this.stuGrade = 4;
}
}
如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造方法,这个构造方法不执行任何代码。如果在定义类时定义了有参的构造方法,没有显式地定义无参的构造方法,那么在使用构造方法创建类对象时,则不能使用默认的无参构造方法。