2 类的定义
2.1 编写一个类
在一个 Java 源文件中,可以定义多个类,但是只能定义一个公开类。
公开类的类名必须和文件名相同。
class Student{ }
2.2 定义类的属性
class Student{ int age; String name; }
实例变量和局部变量不同,局部变量必须先赋值后使用,而对于实例变量,系统会为其分配一个默认值。
实例变量的默认值规则与数组元素默认值一样,对于对象类型的属性,默认值为 null值,对于数值类型的属性,默认值为 0,而对于 boolean 类型属性,默认值为 false。
局部变量和实例变量命名冲突是允许的。
当实例变量和局部变量发生命名冲突时,以局部变量优先。
2.3 定义类的方法
2.3.1 方法声明和方法实现
方法声明分为五个部分:
修饰符 返回值类型 方法名 参数表 抛出的异常
在方法声明之后,紧跟一个代码块,这个代码块称之为方法的实现。
class Student{#类 int age; String name;#实例变量 public void study(){#方法声明 System.out.println(“Student study for 8 hours”);#方法实现 } }
2.3.2 方法的重载
在一个类中,我们可以定义一系列方法,这些方法的方法名相同,参数表不同,这种语法被称为“方法的重载”。
class Student{ public void study(){ System.out.println(“study()”); } public void study(int n){ System.out.println(“study(int)”); } }
上面这段代码中,在 Student 类中定义了两个 study 方法,一个无参,另一个带一个字符串参数。程序运行时,根据不同的参数,会调用不同的方法。
public class TestStudent{ public static void main(String args[]){ Student stu = new Student(); stu.study(); //调用无参的 study 方法,打印 study() stu.study(10); //调用 int 参数的 study 方法,打印 study(int) } }
当程序被编译时,如果出现方法的重载,Java 编译器会根据实参的类型,来匹配一个合适的方法调用。因此,方法的重载又被称为“编译时多态”。
2.4 构造方法
构造方法(也被翻译成构造器)是面向对象特有的概念,是一种比较特殊的方法。
class Student{ public Student(){ System.out.println(“Student()”); } }
2.4.1 构造方法的基本概念
构造方法没有返回值类型
构造方法的方法名与类名相同
构造方法对方法名有要求,对参数表没有要求。因此,一个类中可以利用
方法重载,添加多个构造方法。
class Student{ public Student(){ System.out.println(“Student()”); } public Student(int n){ System.out.println(“Student(int)”); } }
构造方法不能手动调用,只能在对象创建时自动调用一次
构造方法由 JVM 来自动调用。在使用 new 关键字创建对象时,会自动调用对象的构造方法。
public class TestStudent{ public static void main(String args[]){ //创建一个 Student 对象,并在创建时调用无参构造方法 Student stu1 = new Student(); //创建一个 Student 对象,并在创建时调用有参构造方法 Student stu2 = new Student(10); } }
2.4.2 默认构造方法
class MyClass{ int a; int b = 100; } public class TestMyClass{ public static void main(String args[]){ MyClass mc = new MyClass();//编译正常 } }
在 Java 中,如果类中没有定义任何的构造方法,则编译器会自动生成一个公开的、无参的空构造方法。
class MyClass{ int a; int b = 100; //增加一个有参构造方法,则编译器就不生成默认构造方法 public MyClass(int n){} } 上述代码中,已经定义了一个有参的构造方法,则编译器不会添加默认无参的构造方法。 例如: public class TestMyClass{ public static void main(String args[]){ MyClass mc = new MyClass();//!编译出错,找不到无参构造方法 } }
需要注意的是,如果一个类中明确的定义了任何一个构造方法,则编译器就不会自动生成默认构造方法。
2.4.3 对象创建的过程
创建一个对象,在不涉及继承(这是下一章的内容)的情况下,基本步骤为 3 步:
1. 分配空间
计算机中的对象,本质上是内存中的一块数据。因此,在计算机中创建一个对象,就意味着必须在内存中为一个对象分配一块数据区域。
此外,在分配空间的同时,会把对象所有的属性设为默认值。这也是为什么实例变量不用赋值,就有默认值的原因。
2. 初始化属性
如果我们在定义实例变量的同时,为实例变量进行了赋值。则赋值语句在这一步骤执行。
3. 调用构造方法
当分配空间和初始化属性完成之后,最后一步是对该对象调用构造方法。
class MyClass{ int a; int b = 100; public MyClass(){ a = 20; b = 30; } } public class TestMyClass{ public static void main(String args[]){ MyClass mc = new MyClass(); System.out.println(mc.a); System.out.println(mc.b); } }
分析上述 MyClass 对象创建的过程。首先,为对象分配空间。分配的空间中,有一块区域用来保存实例变量 a,有一块区域用来保存实例变量 b。这两块区域在分配完之后,获得默认值 0。如下图所示:
分配空间之后,属性被赋值为默认值。之后,执行初始化属性的步骤。由于 a 属性没有被直接赋值,因此初始化属性时仅需要为 b 赋值即可。之后,调用 MyClass 的无参构造方法。由于在构造方法内部为 a 属性和 b 属性赋值为 20 和 30,因此最后在程序中输出时,输出的是 20 和 30。
综上所述,对象的创建过程分为三步:分配空间、初始化属性、调用构造方法。其中,调用构造方法是对象创建中最后一个步骤。当构造方法完成之后,意味着对象的创建彻底完成了。