【JavaSE】初识 类和对象

》》》我的博客主页
》》》我的gitee链接
关注我,在学习Java的道路上共同进步!!!

Alt
Alt



一. 什么是类?什么是对象?

Java是一门面向对象的编程语言(Object Oriented Program,简称OOP),
在面向对象的世界里,一切皆为对象,
你是一个对象,我是一个对象,房子是一个对象,汽车是一个对象,电脑,手机等等都是对象。
在Java看来,这些对象都是一个一个实体,那Java如何描述上面一个个具体的对象?需要用类来描述。

类是什么?
类可以看作是对象的模板或蓝图,用来描述对象的属性(数据)和行为(方法)

Java怎么用类描述一个对象的属性和方法?

类首先需要一个语法来定义:

class 类名 {
    
    
}

例子:定义一个名为 Person 的类,
该类有两个属性:name 和 age,
并且有一个sleep方法来描述人的睡觉行为。

//用类描述一个人
class Person{
    
    
    //属性     比如每个人都有name属性和age属性
    public  String  name;
    public  int  age;

    //行为 / 方法    
    //比如用一个sleep方法描述人在睡觉的行为
    Public  void  sleep() {
    
    
   }
}

对象则是类的实例化,可以具体地表示现实世界中的一个个实体。通过定义一个类,然后把类当成一个模版进行实例化,就可以创建具体的对象。
例如,可以通过已经定义好的Person类,创建一个名为小明,年龄为18岁的Person对象,并调用其sleep方法来描述他在睡觉。

Alt

在这里插入图片描述

二. 什么是面向对象?什么是面向过程?

面向对象和面向过程是两种解决问题的思维方式,编程语言只是向计算机表达和传达思维的工具。
面向过程的编程语言 主要代表是 C语言。
面向对象的编程语言 主要代表是 C++ 和 Java 。

面向过程

面向过程是一种以过程为中心的思维方式,面向过程的重点在于将问题分解为多个步骤或函数,通过函数之间的调用来解决问题

比如,要用洗衣机洗衣服需要对下面的步骤一步一步的执行:
Alt

面向对象

面向对象是以对象为中心的思维方式,面向对象的重点是将问题分解为不同的对象,然后创建每个对象的属性和方法,让每个对象可以负责完成特定的任务,最后通过对象之间的交互来完成整个任务

比如,要洗衣服时,首先到人,衣服,洗衣液,洗衣机四个对象,如果要完成洗衣服,需要这四个对象相互协作才能完成:人会拿衣服和洗衣液并且把它们放进洗衣机里,洗衣机会洗涤放进去的衣服,洗衣液可以通过与衣服和洗衣机的相互作用达到清洁作用。
Alt

三. 类的定义

面向对象程序设计关注的是对象,而对象是实体,计算机并不知道这些实体,所以需要先定义类,把对象的属性和行为 (方法) 抽象出来,计算机才能对具体的对象进行描述和操作。

一个类包含 属性方法

  • 属性是类的特征,它们描述了 对象的状态和特性。
  • 方法是类的行为,它们定义了 对象可以执行的操作。方法可以用来改变属性的值,或者执行一些特定的功能。

比如一个洗衣机抽象成一个类,则:

  • 定义的属性(状态)可以是:洗衣机的产品品牌,型号,产品重量,外观尺寸,颜色…
  • 定义的方法(功能)可以是:洗衣,烘干、定时…

类的定义 格式

已知一个类包含了 属性 和 方法,类的关键字是 class :

// 创建类
class ClassName{
    
    
    field; // 可以叫 字段,属性 或者 成员变量
    method; // 可以叫 行为 或者 成员方法
}
  • 属性 也可以称作 字段,或者 成员变量
    成员变量与局部变量不同,局部变量定义在方法的内部;而成员变量定义在方法的外部, 类的内部
    成员变量还分为 普通成员变量 和 静态成员变量 (静态成员变量被 static 修饰)。

  • 方法 也可以称作 行为 或者 成员方法
    成员方法还分为 普通成员方法 和 静态成员方法。

//定义一个ClassName类
class ClassName {
    
    
    //普通成员变量
    public 数据类型 field;

    //静态成员变量
    public static 数据类型 staticField;

    //普通成员方法
    public 数据类型 method() {
    
    
    
    }
    
    //静态成员方法
    public static 数据类型 staticMethod() {
    
    
        
    }
}

Alt

比如定义一个洗衣机类:

class WashMachine{
    
    
	public String brand; // 品牌
	public String type; // 型号
	public double weight; // 重量
	public double length; // 长
	public double width; // 宽
	public double height; // 高
	public String color; // 颜色
	
	public void washClothes() {
    
     // 洗衣服
		System.out.println("洗衣功能");
	}
	
	public void dryClothes() {
    
     // 脱水
		System.out.println("脱水功能");
	}
	
	public void setTime() {
    
     // 定时
		System.out.println("定时功能");
	}
}

还有定义一个狗类:

class PetDog {
    
    
	//狗的属性
	public String name;//名字
	public String color;//颜色
	
	// 狗的行为
	public void barks() {
    
    
		System.out.println(name + ": 旺旺旺~~~");
	} 
	// 狗的行为
	public void wag() {
    
    
		System.out.println(name + ": 摇尾巴~~~");
	}
}

采用 Java 语言将洗衣机类在计算机中定义完成,经过 javac 编译之后形成 .class 文件,在JVM的基础上计算机就可以识别了。

类的定义和命名的基本原则和规范

  • 类名采用 大驼峰 定义 (即每个单词的首字母大写)
  • 成员变量名 和 成员方法名 采用 小驼峰 定义 (即第一个单词首字母小写,后面的单词首字母大写)
  • static 和 public 会在后面的文章中解释,定义 成员变量 和 成员方法 前面可以先默认加上 public (public 称为访问修饰限定符)
  • 一般一个文件当中被 public 修饰的类 只能定义一个,但也不建议一个文件有多个类,这样不利于管理
    Alt
  • public修饰的类必须要和文件名相同
    Alt
  • 每一个类编译之后都会产生一个字节码文件,而不是一个Java文件产生一个字节码文件(建议一个类 放到一个java文件当中,而不是一个java文件放多个类,这里在一个java文件中定义3个类只是证明每一个类产生一个字节码文件)
    查看字节码文件的方法:
    Alt
    然后点击项目文件就能看到 .class 文件
    Alt
    可以看到:一个类编译之后都会产生一个字节码文件
    Alt
  • 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改
    正确的修改步骤(这个方法只针对一个java文件只有一个类的时候):
    Alt
    Alt
    Alt

四. 类的实例化

定义了一个类,就相当于在计算机中定义了一种新的类型
与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的
类型。有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
类型创建对象的过程,称为类的实例化
在java中采用 new 关键字,配合类名来实例化对象(实例化对象指的是通过new关键字对类进行实例化)

用一个例子加深理解
之前已经定义了一个宠物狗类:

class PetDog {
    
    
    //狗的属性
    public String name;//名字
    public String color;//颜色

    // 狗的行为
    public void barks() {
    
    
        System.out.println(name + ": 旺旺旺~~~");
    }
    // 狗的行为
    public void wag() {
    
    
        System.out.println(name + ": 摇尾巴~~~");
    }
}

现在用宠物狗类进行实例化,注意 通过 new 关键字 可以实例化 多个对象
我这里实例化两个对象:哈士奇 和 柯基
Alt

public class Main {
    
    
    public static void main(String[] args) {
    
    
        //通过 new 关键字 可以实例化 多个对象
        //实例化一只哈士奇作为对象
        PetDog Husky = new PetDog();
        Husky.name = "奇奇";
        Husky.color = "黑白";
        Husky.barks();
        Husky.wag();

        //实例化一只柯基作为对象
        PetDog Corgi = new PetDog();
        Corgi.name = "小基";
        Corgi.color = "黄白";
        Corgi.barks();
        Corgi.wag();
    }
}

代码运行结果:
Alt

类的实例化 注意事项

  • new 关键字用于创建一个对象的实例
    Alt
  • 使用 . 来访问对象中的属性和方法
    Alt
  • 同一个类可以创建多个实例,比如一个宠物狗类可以生成多个品种的宠物狗对象。

对象存储的基本原理

在Java当中,当使用 new 关键字来实例化一个类时,会在中分配内存空间用于存储对象的实例。而在虚拟机栈中,会分配一个引用变量,该变量存储对象在堆中的地址,使得该引用指向堆中实际存储的对象本身

同样用 哈士奇 和 柯基 的例子:
Alt

哈士奇和柯基的具体细节还需要通过访问该对象中的属性,进行赋值。
Alt

五. this 引用

这里从一个例子开始引入 this的引用,

this . 成员变量

比如创建一个日期类并 实例化多个对象

public class Date {
    
    
	//日期类的属性
	public int year;
	public int month;
	public int day;
	
	//日期类的方法,用来设置具体的日期
	public void setDay(int y, int m, int d){
    
    
		year = y;
		month = m;
		day = d;
	}
	
	//在main方法中实例化2个对象
	public static void main(String[] args) {
    
    
        Date date1 = new Date();
        date1.setDate(2023,8,4);
        Date date2 = new Date();
        date2.setDate(2012,6,1);
    }
}

画图分析:
实例化第一个对象时:
Alt
实例化第二个对象时:
Alt
这里可以发现一个问题:对象可以有很多个,可是 setDate方法 只有一个,setDate方法是怎么确定是在给哪个对象赋值呢?

其实在setDate方法中隐藏了一个参数(程序员不需要主动加上Date this参数,这里只是更方便的展示):
Alt
date1 对象调用了setDate方法,那么 this 就是 date1对象;
date2 对象调用了setDate方法,那么 this 就是 date2对象。

Alt
那 setDate方法 中, year , month ,date 是怎么确定是哪个对象的呢?这就需要在 year , month ,date 前面用到 this (此时不加 this 也没问题,但加了一定对)
Alt
以上就是 this 的第一种引用场景,完整代码如下:

public class Date {
    
    
    public int year;
    public int month;
    public int date;

    public void setDate(int y, int m, int d) {
    
    
		//this引用
        this.year = y;
        this.month = m;
        this.date = d;
    }

    public static void main(String[] args) {
    
    
        Date date1 = new Date();
        date1.setDate(2023,8,4);
        Date date2 = new Date();
        date2.setDate(2012,6,1);
    }
}

还是创建一个 Date类并且实例化一个 date1对象:

public class Date {
    
    
    public int year;
    public int month;
    public int date;

    public void setDate(int year, int month, int date) {
    
    
        year = year;
        month = month;
        date = date;
    }

    public void printDate() {
    
    
        System.out.println("year:" + year + " month:" + month + " date:" + date);
    }
    public static void main(String[] args) {
    
    
        Date date1 = new Date();
        date1.setDate(2023,8,4);
        date1.printDate();
    }
}

输出结果:
Alt
显然,这个代码是有问题的。

Alt
解决办法:通过 this 引用成员变量。

public class Date {
    
    
    public int year;
    public int month;
    public int date;

    public void setDate(int year, int month, int date) {
    
    
        //通过this引用date1对象的成员变量
        this.year = year;
        this.month = month;
        this.date = date;
    }

    public void printDate() {
    
    
        System.out.println("year:" + year + " month:" + month + " date:" + date);
    }
    public static void main(String[] args) {
    
    
        Date date1 = new Date();
        date1.setDate(2023,8,4);
        date1.printDate();
    }
}

输出结果:
Alt

this . 成员方法

public class Date {
    
    
    public int year;
    public int month;
    public int date;

    public void setDate(int year, int month, int date) {
    
    
        this.year = year;
        this.month = month;
        this.date = date;
    }

    public void initalDate() {
    
    
        this.year = 2000;
        this.month = 1;
        this.date = 1;
    }
    public void printDate() {
    
    
        System.out.println("year:" + this.year + " month:" + this.month + " date:" + this.date);
        //this调用成员方法
        this.initalDate();
    }
    public static void main(String[] args) {
    
    
        Date date1 = new Date();
        date1.setDate(2023,8,4);
        date1.printDate();//year:2023 month:8 date:4
        date1.printDate();//year:2000 month:1 date:1
    }
}

this引用 总结

  • this 代表当前对象的引用 (this 引用指向当前对象),谁调用这个方法,this 指的就是谁
  • this 只能在 成员方法 中使用
  • this是 成员方法 第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收
  • 在成员方法中,this 只能引用当前对象,不能再引用其他对象

六. 初始化 对象中的成员变量

局部变量在使用前一定需要先初始化

int a;
System.out.println(a);//error
int a = 10;
System.out.println(a);//OK

但成员变量不是局部变量,所以可以不初始化,也可以初始化。
成员变量的初始化需要分类介绍(就地初始化,默认初始化,构造方法)。

1. 成员变量的就地初始化

在声明成员变量时,就直接给出了初始值

class Person{
    
    
	//对成员变量就地初始化
    public String name = "zhangsan";
    public int age = 18;

   public void show() {
    
    
        System.out.println("name: " + this.name + " age: " + this.age);
    }
    
    public static void main(String[] args) {
    
    
        Person person1 = new Person();
        person1.show();//输出的是name: zhangsan age: 18
    }
}

2. 成员变量的默认初始化

成员变量 在没有初始化的时候,都会有一个默认值
在成员变量中,基本数据类型的默认值是 0 (布尔类型是 false),引用数据类型的默认值都是 null

数据类型 默认值
byte 0
char ‘\u0000’
short 0
int 0
long 0L
boolean false
float 0.0f
double 0.0
reference (引用类型) null
class Person{
    
    
	//对成员变量默认初始化
    public String name;
    public int age;

    public void show() {
    
    
        System.out.println("name: " + this.name + " age: " + this.age);
    }
    
    public static void main(String[] args) {
    
    
        Person person1 = new Person();
        person1.show();//输出的是name: null age: 0
    }
}

3. 通过 构造方法 对成员变量初始化

构造方法是非常特殊的方法,成为构造方法需要满足两个条件:

  1. 没有返回值,设置为 void 也不行
  2. 方法名必须和类名一样
class Person{
    
    
    public String name;
    public int age;

    //构造方法
    public Person() {
    
    
        this.name = "zhangsan";
        this.age = 18;
    }

    public void show() {
    
    
        System.out.println("name: " + this.name + " age: " + this.age);
    }
    
    public static void main(String[] args) {
    
    
        Person person1 = new Person();
        person1.show();//输出的是name: zhangsan age: 18
    }
}

这个构造方法是如何被调用的呢?
原理:
Alt
注意 构造方法在整个对象的生命周期内只调用一次,只有在创建对象时编译器自动调用构造方法(比如一个人只能出生一次,如果再次出生,那一定是另一个人出生了)

对象中的成员变量可以不初始化的原因

实例化一个对象(初始化一个对象的过程)的时候,需要进行两个关键步骤:

  1. 为对象分配内存
  2. 调用 合适 的构造方法

可是在默认初始化和就地初始化时代码中并没有构造方法,那为什么还能正常运行?
因为当我们没有写任何一个构造方法的时候,Java会自动提供一个不带参数的构造方法

我们还可以写多个构造方法,因为 构造方法可以有多个,每个构造方法名又要与类名一样,因此构造方法之间构成了 重载关系。(方法的重载要保证方法名相同且参数不同,跟返回值没有关系)

class Person{
    
    
    public String name;
    public int age;

    //第一个构造方法
    public Person() {
    
    
        this.name = "zhangsan";
        this.age = 18;
    }
    //第二个构造方法
    public Person(String name,int age) {
    
    
        this.name = name;
        this.age = age;
    }
    public void show() {
    
    
        System.out.println("name: " + this.name + " age: " + this.age);
    }

    public static void main(String[] args) {
    
    
        Person person1 = new Person();//调用的是第一个构造方法
        person1.show();//name: zhangsan age: 18

        Person person2 = new Person("lisi",23);//调用的是第二个构造方法
        person2.show();//name: lisi age: 23
    }
}

那上面的代码中有两种构造方法,我把第一种 没有参数的构造方法 删掉可以吗? 答案:不可以。
原因:只有一个构造方法都没有的情况下,Java才会默认给一个不带参数的构造方法。一旦你写了任何的构造方法,编译器都不会再给你任何的构造方法了。

class Person{
    
    
    public String name;
    public int age;

	//第一个构造方法忽略掉 就无法编译
    /*public Person() {
        this.name = "zhangsan";
        this.age = 18;
    }*/

    public Person(String name,int age) {
    
    
        this.name = name;
        this.age = age;
    }
    public void show() {
    
    
        System.out.println("name: " + this.name + " age: " + this.age);
    }

    public static void main(String[] args) {
    
    
        Person person1 = new Person();//error
        person1.show();

        Person person2 = new Person("lisi",23);
        person2.show();
    }
}

在IDEA中通过快捷键快速生成 有参数的构造方法

两种方法:

  1. 键盘 alt + insert (或 alt + F12 ), 然后用鼠标点击constructor
  2. 鼠标右击代码空白处,选中Generate, 然后用鼠标点击constructor

Alt
Alt
为构造方法选择参数,可以按住 shift键 选择多个参数
Alt
如果只选择name作为参数,那么就会自动创建好有name参数的构造方法
Alt
如果选择 name 和 age 作为参数,那么就会自动创建好有 name 和 age 参数的构造方法
Alt
Alt

this访问构造方法

构造方法中可以通过 this 调用当前类当中的其他构造方法

this调用其他构造方法,只能在构造方法当中写,且只能出现在当前构造方法的第一条语句(注释除外)

class Person{
    
    
    public String name;
    public int age;

    public Person() {
    
    
        //this调用其他构造方法,只能在构造方法当中写,且只能出现在当前构造方法的第一条语句(注释除外)
        this("zhangsan",18);//调用当前类当中,带有两个参数的构造方法
    }

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public void show() {
    
    
        System.out.println("name: " + this.name + " age: " + this.age);
    }

    public static void main(String[] args) {
    
    
        Person person1 = new Person();
        person1.show();//name: zhangsan age: 18
    }
}

注意构造方法不能自己调用自己
Alt
也不能形成环
Alt

至此,我们已学习了3种 this 引用 的场景:

  1. this 引用成员变量
  2. this 引用成员方法
  3. this 引用构造方法

结语

类和对象是Java编程中的重要概念,但这篇博客只是一个开始。深入学习和理解类和对象需要持续的探索和实践。在这个过程中,我们可能会遇到各种错误和挑战,但正是通过不断解决问题,我们才能更好地理解和掌握这些知识。

如果在我的博客中存在任何错误或不准确的地方,还请指正。非常欢迎你的意见和建议,让我们一起不断学习和成长!

猜你喜欢

转载自blog.csdn.net/weixin_73276255/article/details/132024348