定义
类是由成员属性和方法组成。成员属性主要定义类的一个具体信息,实际上一个成员属性就是一个变量,而方法是一些操作的行为。类的定义基础语法如下。
class 类名称 {
[访问修饰符] 数据类型 成员属性(变量);
...
public 返回值的数据类型 方法名称(参数类型 参数1, 参数类型 参数2, ...){
程序语句;
[return 表达式;]
}
}
一个类定义完成后并不能够被直接使用,因为类描述的只是一个广义的概念,而具体的操作必须通过对象来执行,由于类属于Java引用数据类型,所以对象的定义格式如下。
/*第一种:声明并实例化对象*/
类名称 对象名称 = new 类名称();
/*第二种:分步定义*/
类名称 对象名称 = null; // 声明对象
对象名称 = new 类名称(); // 实例化对象
在Java中引用数据类型是需要进行内存分配的,所以在定义时必须通过关键字new来分配相应的内存空间后才可以使用,此时该对象也被称为”实例化对象“,而一个实例化对象就可以采用【对象.成员属性;对象.方法();】的方式进行类结构的操作。
对象内存分析
Java中类属于引用数据类型,所有的引用数据类型在使用过程中都要通过关键字new开辟新的内存空间,当对象拥有了内存空间后才可以实现成员属性的信息保存,在引用数据类型操作中最为重要的内存有两块【heap】堆内存、【stack】栈内存。
- 【heap】堆内存:保存的是对象的具体信息(成员属性),在程序中堆内存空间的开辟是通过new完成的。
- 【stack】栈内存:保存的是一块栈内存的地址,即通过地址找到堆内存,而后找到对象内容。
对象引用传递分析
类是一种引用数据类型,而引用数据类型的核心本质在于堆内存和栈内存的分配与指向处理。在程序开发中,不同的栈内存可以指向同一块的堆内存空间,这样就形成了对象的引用传递过程。
引用传递与垃圾产生分析
引用传递的本质意义在于,一块堆内存空间可以被不同的栈内存所引用,每一块栈内存都会保存有堆内存的地址信息,并且只允许保存一个堆内存地址信息,即如果一块栈内存已经存在有其他堆内存的引用,当需要改变引用指向时就需要丢弃已有的引用实体更换为新的引用实体。【被丢弃的引用实体如果没有被任何栈内存指向,就会产生垃圾,所占用的空间就会成为垃圾空间。所有的垃圾空间将等待GC(Garbage Collection,垃圾收集器)不定期地进行回收释放】。
成员属性封装
面向对象的第一大特性指的就是封装性,而封装性最重要的特点就是内部结构对外不可见。在之前的操作中可以发现所有类中的成员属性都可以直接通过实例化对象在类的外部调用,而这样的调用是不安全的,那么此时最稳妥的做法就是利用private实现成员属性的封装处理。而一旦使用了private封装之后,是不允许外部对象直接访问成员属性的,而此时的访问则需要按照Java的开发标准定义setter()、getter()方法处理。
class Person{
private String name;
private int age;
public void tell() {
System.out.println("姓名:" + name + "、年龄:" + age);
}
public void setName(String tempName) {
name = tempName;
}
public void setAge(int tempAge) {
age = tempAge;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
构造方法与匿名对象
构造方法是在类中定义的一种特殊方法,它在一个类使用关键字new实例化新对象时默认使用,其主要功能是完成对象属性的初始化操作。
在Java语言中,类中构造方法的定义要求如下。
- 构造方法的名称与类名称保持一致。
- 构造方法不允许有返回值类型声明。
由于对象实例化操作一定需要构造方法的存在,所以如果在类之中没有明确定义构造方法的话,则会自动生成一个无参数并且无返回值的构造方法,供用户使用;如果一个类中已经明确定义了一个构造方法,则不会自动生成无参且无返回值的构造方法,也就是说,一个类中至少存在一个构造方法。
class Person{
private String name;
private int age;
// 构造方法
public Person(String tempName,int tempAge){
name = tempName;
age = tempAge;
}
public void tell() {
System.out.println("姓名:" + name + "、年龄:" + age);
}
public void setName(String tempName) {
name = tempName;
}
public void setAge(int tempAge) {
age = tempAge;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
构造方法虽然定义形式特殊,但是其本质依然属于方法,所以构造方法也可以进行重载。
在对象实例化定义格式中,关键字new的主要功能是进行堆内存空间的开辟,而对象的名称是为了对该堆内存的引用,这样不仅方便使用堆内存同时防止其变为垃圾空间,也就是说对象真正的内容是在堆内存里面,而有了构造方法之后就可以在堆内存开辟的同时进行对象实例化处理,这样即便没有栈内存指向,该对象也可以使用一次,而对于这种没有指向的对象就称为匿名对象。
public class JavaDemo {
public static void main(String args[]) {
new Person("张三",18).tell();
}
}
this关键字
this描述的是本类结构调用的关键字,在Java中this关键字可以描述3种结构的调用。
- 当前类中的属性:this.属性。
- 当前类中的方法(普通方法、构造方法):this()、this.方法名称()。
- 描述当前对象。
this调用本类属性
class Person{
private String name;
private int age;
// 构造方法
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void tell() {
System.out.println("姓名:" + this.name + "、年龄:" + this.age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
this调用本类方法
调用本类普通方法:可以使用“this.方法()”调用,并且可以在构造方法与普通方法中使用。
class Person{
private String name;
private int age;
// 构造方法
public Person(String name,int age){
this.setName(name); // 调用本类setName()方法
setAge(age); // 不使用“this.方法()”也表示调用本类方法
}
public void tell() {
System.out.println("姓名:" + this.name + "、年龄:" + this.age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
调用本类构造方法:调用本类其他构造方法使用this()形式,此语句只允许放在构造方法首行使用。
class Person{
private String name;
private int age;
// 无参构造方法
public Person(){
System.out.println("一个新的Person类对象实例化了")
}
// 单参构造方法
public Person(String name){
this(); // 调用本类无参构造方法
this.name = name;
}
// 构造方法
public Person(String name,int age){
this(name); // 调用本类单参构造方法
this.age = age;
}
public void tell() {
System.out.println("姓名:" + this.name + "、年龄:" + this.age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
static关键字
static是一个用于声明程序结构的关键字,此关键字可以用于全局属性和全局方法的声明,主要特点是可以避免对象实例化的限制,在没有实例化对象的时候直接进行此类结构的访问。
static属性
在一个类中,主要组成就是属性和方法(构造方法、普通方法),而每一个对象都分别拥有各自的属性内容(不同对象的属性保存在不同的堆内存中)。如果想要类中的某个属性定义为公共属性(所有对象都可以使用的属性),则可以在声明属性前加上static关键字。
class Person{
private String name;
private int age;
static String country = "中华人民共和国";
// 构造方法
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void tell() {
System.out.println("姓名:" + this.name + "、年龄:" + this.age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
static描述的是全局属性,对于全局属性除了可以利用实例化对象调用外,最大的特点在于可以直接利用类名称并且在没有实例化对象产生的情况下进行调用。
public class JavaDemo {
System.out.println("直接访问static属性:" + Person.country);
}
static定义方法
static除了可以进行属性定义外,也可以进行方法的定义,一旦使用了static定义了方法,那么此方法就可以在没有实例化对象的情况下调用。
class Person{
private String name;
private int age;
private static String country = "中华人民共和国";
// 构造方法
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void tell() {
System.out.println("姓名:" + this.name + "、年龄:" + this.age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
// 修改静态属性内容
public static void setCountry(String country) {
this.country = country;
}
}
public class JavaDemo {
Person.setCountry("伟大的中国")
}
代码块
代码块一共分为四种:普通代码块、构造代码块、静态代码块和同步代码块。
普通代码块
普通代码块是定义在方法中的代码块,利用这类代码块可以解决代码块在一个方法中过长导致出现重复变量定义的问题。
public class JavaDemo {
public static void main(String args[]) {
{
int x = 10;
System.out.println("x = " + x);
}
int x = 100;
System.out.println("x = " + x);
}
}
构造代码块
将代码块定义在一个类中,这样就成为构造代码块。构造代码块的主要特点是在使用关键字new实例化新对象时进行调用。
class Person {
public Person() {
System.out.println("【构造方法】Person类构造方法执行")
}
{
System.out.println("【构造代码块】Person类构造方法执行")
}
}
public class JavaDemo {
public static void main(String args[]) {
new Person();
new Person();
}
}
通过执行上述程序可以发现,每一次实例化新的对象时都会调用构造代码块,并且构造代码块的执行优先于构造方法的执行。
原创文章,作者:ZERO,如若转载,请注明出处:https://www.edu24.cn/course/java/java-learn-classvsobject.html