面向对象的程序设计过程中有两个重要概念:类(class)和对象(object 也被称为实例),其中类是某一批对象的抽象,可以把类理解成某种概念;对象才是一个具体存在的实体,从这个意义上来看,我们日常所说的人,其实都是人的实例,而不是人类。
Java 是面向对象的程序设计语言,类(class)是面向对象的重要内容,我们可以把类当成一种自定义数据类型,可以使用类来定义变量,这种类型的变量统称为引用变量。
类是同一类事物的统称,如果将现实世界中的一个事物抽象成对象,类就是这类对象的统称,如鸟类、家禽类、人类等。
类是构造对象时所依赖的规范,例如,一只鸟具有一对翅膀,而它可以通过这对翅膀飞行,而基本上所有的鸟都具有翅膀这个特性和飞行的技能,这样的具有相同特性和行为的一类事物就称为类,类的思想就是这样产生的。
类是世间事物的抽象称呼,而对象则是这个事物相对应的实体。如果面临实际问题,通常需要实例化类对象来解决。例如解决大雁南飞的问题,这里只能拿这只大雁来处理这个问题,不能拿大雁类或鸟类来解决。
类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。例如一个鸟类,鸟类封装了所有鸟的共同属性和应具有的行为。
类和对象是 Java 语言面向对象的核心,Java 语言提供了对创建类和创建对象简单的语法支持。定义类的简单语法如下:
[修饰符] class 类名 { 零到多个成员定义 零到多个构造器定义 零到多个方法定义 }
在上面的语法格式中:
(1)修饰符可以是 public、final、abstract,或者完全省略这三个修饰符。例如:public class 类名 {} 或者 public final class 类名 {}
(2)类名只要是一个合法的 Java 标识符即可,从程序的可读性来看,Java 类名必须是由一个或多个有意义的单词连接而成,每个单词的首字母大写,其他字母全部小写,并且单词之间不要使用任何分割符。例如:UserManager(用户管理)、OrderManager(订单管理)
(3)成员、构造器和方法定义见后续小结。
成员用于定义该类或该类的实例所包含的状态数据,定义成员的语法格式如下:
[修饰符] 成员类型 成员名[=默认值];
说明如下:
修饰符:修饰符可选值为 public、protected、private 和默认包级别之一,还可以和 static、final 组合,例如:public static;
成员类型:成员类型可以是基础类型(short、int、long、double等)和引用类型(Date、String、自定义类等);
成员名:成员名可以任何有效的 Java 标识符;
构造器用于构造该类的实例,Java 语言通过 new 关键字来调用构造器,从而返回该类的实例。
构造器是一个类创建对象的根本途径,如果一个类没有构造器,这个类通常无法创建实例。因此,Java 语言提供了一个功能:如果程序员没有为一个类编写构造器,则系统会为该类提供一个默认的构造器。一旦程序员为一个类提供了构造器,系统将不再为该类提供构造器。定义构造器的语法如下:
[修饰符] 类名([参数列表]) [throws 异常列表] { //... }
说明如下:
修饰符:修饰符可选值为 public、protected、private 和默认包级别,如:public 类名(){};
参数列表:参数列表是可选的,如:public 类名(int age) {};
异常列表:异常列表用来指定构造器可能会抛出的异常列表,如:public 类名() throws IOException, NullPointerException {};
注意:构造器的名称必须和类名一致。
方法则用于定义该类或该类的实例的行为特征或者功能实现,如:人的吃饭、睡觉等动作。方法定义语法如下:
[修饰符] 方法返回值类型 方法名([形参列表]) { //由零条到多条可执行性语句组成的方法体 // 可选的返回语句 return }
说明如下:
修饰符:修饰符可以省略,也可以是 public、protected、private、static、final、abstract,其中 public、protected、private 三个最多只能出现其中之一;abstract 和 final 最多只能出现其中之一,它们可以与 static 组合起来修饰方法。例如:public static String 方法名() {}
方法返回值类型:返回值类型可以是 Java 语言允许的任何数据类型,包括基本类型和引用类型;如果声明了方法返回值类型,则方法体内必须有一个有效的 return 语句,该语句返回一个变量或一个表达式,这个变量或者表达式的类型必须与此处声明的类型匹配。除此之外,如果一个方法没有返回值,则必须使用 void 来声明没有返回值。
方法名:方法名的命名规则与成员命名规则基本相同,但通常建议方法名以英文中的动词开头。
形参列表:形参列表用于定义该方法可以接受的参数,形参列表由零组到多组 “参数类型形参名" 组合而成,多组参数之间以英文逗号 (,) 隔开,形参类型和形参名之间以英文空格隔开。一旦在定义方法时指定了形参列表,则调用该方法时必须传入对应的参数值 —— 谁调用方法,谁负责为形参赋值。
方法体:方法体里多条可执行性语句之间有严格的执行顺序,排在方法体前面的语句总是先执行,排在方法体后面的语句总是后执行。
注意:
(1)static 是一个特殊的关键字,它可用于修饰方法、成员等。static 修饰的成员表明它属于这个类本身,而不属于该类的单个实例,因为通常把 static 修饰的成员和方法也称为类成员、类方法。不使用 static 修饰的普通方法、成员则属于该类的单个实例,而不属于该类。因为通常把不使用 static 修饰的成员和方法也称为实例成员、实例方法。
(2)类里各成员之间的定义顺序没有任何影响,各成员之间可以相互调用,但需要指出的是,static 修饰的成员不能访问没有 static 修饰的成员。例如:
public class A { private String name; // 不能访问非静态成员属性 name public static void setName(String name) { // 静态方法没有 this this.name = name; } }
定义一个关于“人”的类,该类包含了人的基本信息,身高、体重、年龄,以及日常功能,如:吃饭、睡觉、工作等,代码如下:
package com.hxstrive; // 定义一个类 Person,表示 “人” public class Person { // 定义 “人” 的属性 // 姓名 private String name; // 年龄 private int age; // 身高 private float height; // 体重 private float weight; // 定义创建 “人” 的构造器 public Person(String name, int age, float height, float weight) { this.name = name; this.age = age; this.height = height; this.weight = weight; } // 定义 “人” 的动作 // 吃饭 public void eat() { System.out.println("吃饭"); } // 睡觉 public void sleep(int time) throws IllegalArgumentException { if(time <= 0) { // 抛出一个异常,后续章节介绍 throw new IllegalArgumentException("睡觉时间必须大于0"); } System.out.println("睡觉,睡 " + time + " 小时"); } // 工作 public void work() { // 向控制台打印字符串 System.out.println("工作"); } // 主方法,入口方法 public static void main(String[] args) { // 创建实例 Person p = new Person("Tom", 30, 178.5f, 75.4f); // 调用实例方法 p.eat(); p.sleep(8); p.work(); } }
运行示例,输出如下:
吃饭 睡觉,睡 8 小时 工作