Java是一门纯面向对象的语言,在面对对象的世界里,一切皆为对象。而对象的创建又和类的定义息息相关。本文主要阐述了类和对象的使用与理解。解释类的定义方式以及对象的实例化,类中的成员变量和成员方法的使用,以及对象的整个初始化过程。
目录
导言:
正文:
一.类的定义和使用
二.类的构造方法
三.this引用
四.类的实例化
五.类的初始化
总结:
类是一种抽象的数据类型,是用于描述具有相同属性和行为的对象的集合。
具体来说,类是用来对一个实体(对象)来进行描述的,主要用来描述该实体(对象)具有哪些属性,哪些功能。
类的定义:使用关键字class来定义一个类,通常包含类的访问修饰符、类名、类体等部分。
类的访问修饰符:类可以有四种访问修饰符,分别是public、protected、private和默认(即不加修饰符)。这些修饰符控制着类的可见性,即哪些代码可以访问该类。
类名:类名是一个标识符,用于唯一标识一个类。类名的命名规范是以大写字母开头,采用驼峰命名法。
类体:类体是类的主体部分,包含了类的属性和方法的定义。类体由一对花括号{}括起来。
这里对修饰符先进行一个解释,,类、方法和属性都可以使用权限修饰符来控制它们的访问权限,这些权限修饰符包括public、protected、private和默认(即不加修饰符)。
public:public是最宽松的权限修饰符,它可以被任何类、方法和属性访问。如果一个类、方法或属性被声明为public,那么它可以被同一个包中的其他类、不同包中的其他类以及任何地方的子类和非子类访问。
protected:protected修饰符可以被同一个包中的其他类访问,也可以被不同包中的子类访问。如果一个类、方法或属性被声明为protected,那么它可以被同一个包中的其他类、不同包中的子类访问,但是不可以被不同包中的非子类访问。
private:private是最严格的权限修饰符,它只能被同一个类中的其他方法和属性访问。如果一个方法或属性被声明为private,那么它只能被同一个类中的其他方法和属性访问,不可以被同一个包中的其他类或不同包中的任何类访问。
默认权限修饰符:如果一个类、方法或属性没有使用任何权限修饰符,那么它的访问权限就是默认的。默认权限修饰符只能被同一个包中的其他类访问,不可以被不同包中的任何类访问。
类的定义具体语法如下
// 创建类
修饰符 class 类名{
修饰符 field; // 字段(属性) 或者 成员变量
修饰符 method(); // 行为 或者 成员方法
}
例如:
public class Student11_4 {
public String name;//成员变量
public int age;//成员变量
//成员方法
public void show(){
System.out.println("hello world");
}
}
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
构造方法有以下几个特点:
构造方法与类同名:构造方法的名称必须与类的名称完全相同。
没有返回类型:与普通方法不同,构造方法没有返回类型,包括void。构造方法的主要目的是初始化对象,而不是返回某个值。
可以有多个构造方法:一个类可以有多个构造方法,它们之间的区别可以通过参数的类型、个数和顺序来区分。这种情况下被称为构造方法的重载,即构造方法也支持重载。
默认构造方法:如果一个类没有定义任何构造方法,编译器会自动为该类生成一个默认的无参构造方法。默认构造方法不做任何初始化操作。
显式定义构造方法:如果在类中显式定义了一个或多个构造方法,编译器就不会生成默认构造方法。在这种情况下,如果想使用无参构造方法,需要显式地定义一个无参构造方法。
构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。内存分配的工作是由JVM在实例化对象时自动完成的。构造方法只负责对对象的属性进行初始化。构造方法执行完毕后,对象才被完全创建并可以使用。
例如,假设有一个名为Person的类,它有属性name和age,并且定义了两个构造方法:
//定义一个人类
public class Person {
//成员变量
private String name;
private int age;
// 无参构造方法
public Person() {
name = "Unknown";
age = 0;
}
// 带参构造方法
public Person(String name, int age) {
//this在这里先进行使用,后面会进行解释
this.name = name;
this.age = age;
}
}
在这个例子中,Person类定义了一个无参构造方法和一个带参构造方法。无参构造方法用于初始化name和age属性的默认值,带参构造方法用于接收外部传入的name和age值,并将其赋给对象的属性。
在Java中,this是一个特殊的关键字,它表示当前对象的引用。this关键字可以在类的方法和构造方法中使用,用于引用当前对象的成员变量、成员方法和构造方法。
this关键字的主要作用有以下几个方面:
1. 引用当前对象的成员变量:在类的方法中,如果方法中的局部变量与成员变量同名,可以使用this关键字来引用当前对象的成员变量。
例如:
public class Person {
private String name;
public void setName(String name) {
this.name = name; // 使用this关键字引用当前对象的成员变量
}
}
在这个例子中,setName方法中的参数name与成员变量name同名,为了区分它们,使用this.name表示当前对象的成员变量。
2. 调用当前对象的成员方法:在类的方法中,可以使用this关键字来调用当前对象的其他成员方法。例如:
public class Person {
private String name;
public void setName(String name) {
this.name = name; // 使用this关键字引用当前对象的成员变量
}
}
在这个例子中,method2方法中使用this.method1()调用了当前对象的method1方法。
3. 在构造方法中调用其他构造方法:在一个类中,可以定义多个构造方法,通过使用this关键字在一个构造方法中调用另一个构造方法。这种方式称为构造方法的重载。例如:
public class Person {
private String name;
private int age;
public Person() {
this("Unknown", 0); // 调用带参构造方法
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
在这个例子中,无参构造方法中使用this("Unknown", 0)调用了带参构造方法,实现了对name和age属性的初始化。
需要注意的是,this关键字只能在非静态方法和构造方法中使用,因为静态方法没有this引用,它是属于类而不是对象的。
4.事实上,成员方法中都有this。this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收在代码层面来简单演示--->注意:下图右侧中的Date类也是可以通过编译的
定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义的一个新的类型,它们本质都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。
对象的构造和初始化是指在创建对象时,为对象分配内存空间并对对象的属性进行初始化的过程。
对象的构造:在Java中,使用关键字"new"来创建一个对象。当使用"new"关键字实例化一个类的对象时,JVM会为该对象分配内存空间,并调用该类的构造方法来初始化对象的属性。
对象的初始化:对象的初始化是指在构造方法中对对象的属性进行赋值操作,使对象的属性具有初始值。初始化可以在构造方法中直接赋值,也可以通过调用其他方法或外部传入的参数来进行赋值。对象的初始化是在对象创建之后立即执行的,确保对象的属性在创建之后具有正确的初始值。
具体的语法是:类名 对象名 = new 类名();
//定义一个人类
public class Person {
//成员变量
private String name;
private int age;
//构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//成员方法
public void sayHello() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}
}
可以通过以下方式实例化Person类:
//调用Person类的有参构造
//创建了一个Person类的对象
Person person = new Person("John", 25);
//调用成员方法
person.sayHello();
在这个例子中,通过new关键字创建了一个Person类的对象,并将其赋值给变量person。同时,调用了Person类的构造方法来初始化对象的属性。然后,可以通过person来访问和调用对象的属性和方法,例如person.name、person.age和person.sayHello()。
先来看一段代码,
public class Date {
public int year;
public int month;
public int day;
public Date(int year, int month, int day) {
// 成员变量在定义时,并没有给初始值, 为什么就可以使用呢?
System.out.println(this.year);
System.out.println(this.month);
System.out.println(this.day);
}
public static void main(String[] args) {
// int a;
// System.out.println(a);
// 此处a没有初始化,编译时会报错:
// Error:(24, 28) java: 可能尚未初始化变量a
//编译通过
Date d = new Date(2021,6,9);
}
}
可以看到局部变量在使用时必须要初始化,但成员变量即使没有初始化也可以正常使用。
事实上,并非成员变量没有初始化,只是编译器帮我们做了这件事,对成员变量设置了初始值。
Date d = new Date(2021,6,9);
在程序层面只是简单的一条语句,但在JVM层面需要做好多事情,下面简单介绍下:
1. 检测对象对应的类是否加载了,如果没有加载则加载
2. 为对象分配内存空间
3. 处理并发安全问题
比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突
4. 初始化所分配的空间 即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:
数据类型 | 默认值 |
byte | 0 |
char | '\u0000' |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |
5. 设置对象头信息
6. 调用构造方法,给对象中各个成员赋值
我们也可以在声明成员变量时,就直接给出了初始值。
public class Date {
public int year = 1900;
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}
代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中
类和对象之间的关系可以理解为类是对象的模板,而对象是类的实例。通过类可以创建多个对象,每个对象都有自己的属性和行为,但是它们共享同一个类的定义。对象是类的实例化结果,它是类的具体实体。对象具有类定义的属性和行为,并且可以通过访问对象的成员变量和调用对象的方法来操作对象。每个对象都有自己的状态(成员变量的值)和行为(方法的执行)。希望本文对你有所帮助。