初识Java之类和对象

本文介绍了Java中的类和对象,包括面向对象的基本概念、类的定义与使用、实例化、this引用、对象构造及初始化、封装、静态成员和代码块。通过实例解释了面向对象与面向过程的区别,探讨了类的构造方法、访问限定符、包的管理和静态成员的使用。此外,还讨论了静态成员变量的初始化和代码块的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在关于Java学习中我们一直在强调类和对象,那么到底什么是类,什么是对象?类和对象是Java语言的精髓之所在,也是Java的一大特色,我们在学习Java务必要了解这一点。


1.面向对象的初步认识

1.1什么是面向对象

Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),在面向的对象的世界里,一切皆为对象。**面向对象是解决问题的一种思想,主要靠对象之间的交互来完成一件事。**面向对象的思想涉及程序,更符合人们对事物的认知,对于大型程序的设计、扩展以及维护都非常好。

1.2面向对象和面向过程

🤔我们举两个例子来简单说明一下面向过程和面向对象

在这里插入图片描述

在面向过程的时候,需要你自己去完成吃饭的每一个步骤,离开宿舍,去食堂打好饭,再带回宿舍吃饭,但是面向对象的时候,在整个打饭的过程中你都没有参与,只需要在宿舍等待室友打好饭回来即可。是不是你的对象也就是你的室友已经帮你完成了所有的步骤,此对象非男女朋友对象。


在面向对象的方式来处理,就不需要关注打饭的过程,室友是跑着去食堂还是走着去食堂,他是去几号窗口打的饭,我们都不需要关心。

2.类的定义和使用

面向对象程序设计关注的是对象,而对象是现实生活中的实体,比如洗衣机,但是计算机不认识洗衣机,需要我们告诉计算机这个洗衣机到底长什么样。
在这里插入图片描述

上图就是对一个简单洗衣机的简单描述,这个过程就是对洗衣机对象(这个实体)进行抽象的描述,但是我们说的再仔细,计算机也不认识,这个时候我们就需要用到Java这个编程语言来进行描述,要想拿到一个对象就得先有类👇🏾

2.1简单认识类

类是用来对一个实体(对象)进行描述的,例如洗衣机,我们描述它多大,怎么用,产自哪里,功率是多少,描述完成后,计算机就能识别到洗衣机。
那我们怎么定义一个类呢?👇🏻

2.2类的定义格式

在定义一个类时,就需要用到关键字class

class WashingMachine{
	members;//成员变量或者是属性
	method;//方法
}
//class是定义类的关键字,WashingMachine是类的名字,在{}中的部分就是类的主体

🦈 属性:主要是用来描述类的,成为类的成员变量或者成员属性
🐋方法:主要是用来说明类有哪些功能,成为类的方法


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

🕹注意事项:
1.类名采用大驼峰来定义🐫
2.成员前统一用public来修饰
3.此处写的方法不带static修饰

2.3练习

2.3.1定义一个狗类和一个猫类

class Dog{
    public String name;//名字
    public String color;//颜色


    //狗的属性
    public void bark(){
        System.out.println(name+"汪汪叫");
    }
    public void eat(){
        System.out.println(name+"在吃饭");
    }
}
class Cat{
    public String name;
    public String color;
    public  void bark(){
        System.out.println(name+"喵喵叫");

    }
    public void eat(){
        System.out.println(name+"在吃饭");
    }
	}
}

🧳注意事项:
1.一般一个文件当中只定义一个类
2.main方法所在的类一般要使用public修饰
3.public修饰的类必须和文件名相同
4.不要轻易修改public修饰的类名
5.一个.java文件中只能有一个public类

3.类的实例化

3.1什么是实例化

🧳 定义一个类,就相当于在计算机中定义了一个新的类型,例如Dog和Cat就用户自己定义的类,有了这些自定义的类型后,就可以使用这些类来定义实例(也就是对象)
💼用类类型创建对象的过程,称为类的实例化,在Java中采用new关键字,配合类名来实例化对象


我们利用代码来实现一下

public class Main {
    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.name="旺财";
        dog.bark();
        dog.eat();
        Cat cat=new Cat();
        cat.name="布丁";
        cat.bark();
        cat.eat();

    }

我们在对对象进行实例化之后,就可以来访问对象中的成员以及方法,通过new这个关键字来创建属于这个对象的实例,通过.号这个符号来访问对象中的成员以及方法。结合以上两个代码块,我们一开始定义了狗和猫这两个对象,但是计算机不知道他们具体的情况,我们就需要来实例化这两个小动物,他们有名字吗,会说话吗,会写字吗?

⬇️

在这里插入图片描述
在这里插入图片描述
那是否同一个类可以创建多个实例呢,答案是yes

⬇️

我们定一个Person类,通过new创建多个实例,这样完全是OK的

class Person{
    public String name;
    public int age;
    public void eat(){
        System.out.println("吃饭!");
    }
    public void sleep(){
        System.out.println("睡觉!");
    }
}

public class Test {
    public static void main(String[] args) {
        //一个类可以实例化多个对象
        Person person1=new Person();
        person1.name="本内特";
        person1.age=37;
        person1.sleep();
        person1.eat() ;
        System.out.println(person1.name+" "+person1.age);

        Person person2=new Person();
        person2.name="里弗斯";
        person2.age=27;
        person2.eat() ;
        System.out.println(person2.name+" "+person2.age);

    }

我们总结3点💬

  1. new关键字用于创建一个对象的实例
  2. 使用.来访问对象的成员和方法
  3. 同一个类可以创建多个实例

3.2类和对象的说明

🤔类和对象到底哪里不同
在这里插入图片描述
我们将类比作是一张房屋设计图,我可以设计出不同的房型,不同的房型就是不同的对象,至于这些房子里的卧室,厨房,洗手间是什么样的,就需要我们自己来设计,也就是类的实例化。

  1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员
  2. 类是一种自定义的类型,可以用来定义变量.
  3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
  4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

👤我们还是拿Person类来说明

我们实例化了两个对象,person1和person2。
他们是在main方法中创建的,方法内部创建的变量叫做局部变量,局部变量是存在栈上的,会在栈上开辟属于他们的空间,我们把person1和person2称为引用变量或者引用。引用变量:这个引用存储的是对象所在空间的地址。
new Person(),通过关键字new创建的对象都是在堆上保存的,所以person1和person2就存储了属于他们对象的地址,引用一定是指向对象的。
在这里插入图片描述

在这里插入图片描述

3.3补充

  1. 当一个引用赋值为null时,代表这个引用不指向任何对象,也就是空指针异常。
public static void main(String[] args) {
        Person person1=null;//这代表 person1不指向任何对象,会造成空指针异常
        person1.name="里弗斯";
        person1.age=28;
        person1.show();

    }

在这里插入图片描述
2.引用不能指向引用,这个说法是错误的
在这里插入图片描述
person1=person2;
这个代表person1这个引用指向了person2这个引用指向的对象
在这里插入图片描述
3.一个引用能否同时指向多个对象?不能
在这里插入图片描述
最后person1只指向了一个对象

4.this引用

4.1为什么要有this引用

public class DateUtil {
    public int year;
    public int month;
    public int day;

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

    }
    
public void show(){

        System.out.println("年:"+year+" 月:"+month+" 日:"+day);
        
    }
public static void main(String[] args) {
//创造3个日期类型的对象
//对3个对象进行设置
        DateUtil dateUtil1=new DateUtil();
        dateUtil1.setDate(2022,10,11);
        dateUtil1.show();

        DateUtil dateUtil2=new DateUtil();
        dateUtil2.setDate(2022,11,12);
        dateUtil2.show();

        DateUtil dateUtil3=new DateUtil();
        dateUtil3.setDate(2022,12,13);
        dateUtil3.show();

    }
}

我们仔细观察上面的代码,定义了一个日期类,然后在类方法中创建了三个对象,并通过setDate和show两个成员方法进行设置以及打印,代码的逻辑正确,看上去没有任何问题,我们运行一下来看下结果。
在这里插入图片描述
🤔年月日全是0,这不是我们想要的结果

答:因为形参和局部变量名字重复。而局部变量优先使用,自己给自己赋值,并没有给对象的 year month day赋值,int的默认初始值为0,所以出现的是上述的结果

在这里插入图片描述


🤔三个对象都调用了setDate和show方法,但是这两个方法压根不知道是谁调用了他们

在这里插入图片描述

为了避免这种情况的发生,就需要用到this引用


4.2什么是this引用

目前为止我们知道的是,方法前面是哪个引用就调用哪个对象的方法⬇️

在这里插入图片描述

 public void setDate(DateUtil this,int year,int month,int day){
		//这里会隐藏一个参数this,可以不加上,但是必须要知道
		//每一个成员方法第一个参数默认是this
        year=year;
        month=month;
        day=day;

    }

那这个this代表的是什么?可以理解为代表的是当前的对象,我们调试来看下
在这里插入图片描述
⬇️

在这里插入图片描述

⬇️

在这里插入图片描述


在这里插入图片描述

⬇️

在这里插入图片描述

⬇️

在这里插入图片描述

总结:this代表的是当前对象的引用,当前对象是谁,就看谁调用了这个方法,谁就是this

现在我们给成员加上this看看,形参中的 this可以不加,这里只是提示。
在这里插入图片描述
在这里插入图片描述
加上this表示给当前的对象属性赋值,所以这个时候就不用担心会出现赋值混乱的情况了。
我们总结一下什么是this引用

this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问(所有的操作对用户都是透明的,即用户不需要传递,都是由编译器自动完成)


1.this的类型:对应类型引用,即哪个对象调用就是那个对象的引用类型
2.this只能在成员方法中使用,离开了成员方法,this就无法再使用
3.在成员方法中,this只能引用当前对象,不能再引用其他对象
4.this是成员方法第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责接收

⬇️

public class DateUtil {
    public int year;
    public int month;
    public int day;
    public void setDate(DateUtil this,int year,int month,int day){  
            this.year=year;
            this.month=month;
            this.day=day;
    }
      public void show(DateUtil this){//here
        System.out.println("年:"+this.year+" 月:"+this.month+" 日:"+this.day);//here
    }
     public static void main(String[] args) {
        DateUtil dateUtil1=new DateUtil();
        dateUtil1.setDate(2022,10,11);
        dateUtil1.show();

        DateUtil dateUtil2=new DateUtil();
        dateUtil2.setDate(2022,11,12);
        dateUtil2.show();

        DateUtil dateUtil3=new DateUtil();
        dateUtil3.setDate(2022,12,13);
        dateUtil3.show();

    }
}

⬇️

在这里插入图片描述

除了引用成员变量之外,this还能引用成员方法以及构造方法

5.对象的构造以及初始化

5.1如何初始化对象

在Java方法内部定义一个局部变量时,必须要初始化,否则就会编译失败

public class test {
    public static void main(String[] args) {
        int a;
        System.out.println(a);
    }
}

在这里插入图片描述
例如我们在上个例子中实现的,在通过访问成员变量的同时直接给成员变量设置初始值

DateUtil dateUtil1=new DateUtil();
        dateUtil1.setDate(2022,10,11);
        dateUtil1.show();

1.此时代码不会报错,如果我们每次设置日期都需要设置具体日期,这样很麻烦,对象如何初始化。
2.局部变量必须初始化才能使用,为什么字段声明之后,没有赋值并没有报错。

	public int year;
    public int month;
    public int day;
    //字段声明之后并没有报错

这就需要我们用到构造方法⬇️

5.2构造方法

5.2.1概念

构造方法也称为构造器,是一个特殊的成员方法,名字必须与类名相同,有编译器自动调用,并且没有返回值在整个对象的声明周期内只调用一次
可以认为构造方法就是为成语变量以及成员方法赋值使用

public class Date {

    public int year;
    public int month;
    public int day;
    // 构造方法:
    // 名字与类名相同,没有返回值类型,设置为void也不行
    // 一般情况下使用public修饰
    // 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("带有3个参数的构造方法");
    }
        public void show () {
            System.out.println(year + " " + month + " " + day);
        }

        public  static void main (String[]args){
            Date d = new Date(2021, 6, 9);
            d.show();
        }

    }

在这里插入图片描述

这就是构造方法的基本形式,不过大家仔细想想,我们在之前的代码中,没有给过构造方法啊,不是也没有报错吗?

⬇️

📓1.如果你没有写任何的构造方法,此时Java会提供一个不带任何参数的构造方法。


public class DateUtil {
    public int year;
    public int month;
    public int day;

    
     public void show(DateUtil this){
        System.out.println("年:"+this.year+" 月:"+this.month+" 日:"+this.day);
    }
     public static void main(String[] args) {
        DateUtil dateUtil=new DateUtil(2020,9,1);
        dateUtil.show();
    }

}

在这里插入图片描述

📔2.但是如果你自己写了构造方法,就会调用你自己的那份构造方法,而且只会调用一次。

public class DateUtil {
    public int year;
    public int month;
    public int day;

public DateUtil(){
        System.out.println("不带参数的构造方法,如果没有写,java会默认提供");

    }
      public DateUtil(int year,int month,int day){
        this.year=year;
        this.month =month;
        this.day=day;
        System.out.println("带有3个参数的构造方法");

    }
     public void show(DateUtil this){
        System.out.println("年:"+this.year+" 月:"+this.month+" 日:"+this.day);
    }
     public static void main(String[] args) {
        DateUtil dateUtil=new DateUtil(2020,9,1);
        dateUtil.show();
    }
}

在这里插入图片描述

📒3.无论是什么构造方法,Java都不会给你提供不带参数的构造方法了。


📕4.构造方法可以重载

⬇️(一个无参一个有参)

在这里插入图片描述
🕹重载:方法名必须相同,参数列表不同,返回值没有影响

📗5. 可以通过this调用其他构造方法来简化代码(this必须是构造方法中的第一条语句)

public class DateUtil {
    public int year;
    public int month;
    public int day;

    public DateUtil(){
        this(1999,9,9);
    }
     public DateUtil(int year,int month,int day){
        this.year=year;
        this.month =month;
        this.day=day;
        System.out.println("带有3个参数的构造方法");

    }
     public void show(DateUtil this){
        System.out.println("年:"+this.year+" 月:"+this.month+" 日:"+this.day);
    }

    public static void main(String[] args) {
        DateUtil dateUtil=new DateUtil();
        dateUtil.show();
    }

在这里插入图片描述

 public DateUtil(){
        this(1999,9,9);//可以通过this来调用当前对象的其他构造方法
        //也就是利用无参构造方法来调用有参构造方法
        }

📘 6.this调用构造方法不能形成闭环

public class DateUtil {
    public int year;
    public int month;
    public int day;

    public DateUtil(){
        this(1999,9,9);//这里调用this
    }
     public DateUtil(int year,int month,int day){
        this();//这里也调用this
        this.year=year;
        this.month =month;
        this.day=day;
        System.out.println("带有3个参数的构造方法");

    }
     public void show(DateUtil this){
        System.out.println("年:"+this.year+" 月:"+this.month+" 日:"+this.day);
    }

    public static void main(String[] args) {
        DateUtil dateUtil=new DateUtil();
        dateUtil.show();
    }

闭环调用会问题

⬇️

在这里插入图片描述

5.3默认初始化

上文我们已经知道该如何给对象初始化,第二个问题还没有解决,为什么局部变量必须要初始化,成员变量可以不用初始化呢?🤔

public class test {
    public static void main(String[] args) {
        int a;
        System.out.println(a);//这样输出就会有报错,原因是因为没有对局部变量a进行初始化
    }
}

public class Date {


        public int year;
        public int month;
        public int day;
        public Date(int year, int month, int day) {

// 成员变量在定义时,并没有给初始值, 为什么就可以使用呢?
            System.out.println(this.month);
            System.out.println(this.day);
            System.out.println(this.year);
        }
        public static void main(String[] args) {
           
            Date d = new Date(2022, 1, 9);
        }
}

要清楚整个过程就需要了解new关键字背后发生的一些事情

Date d = new Date(2022, 1, 9);

这看上去虽然只是一条简单的代码,但是在JVM中需要做很多事

  1. 检测对象对应的类是否加载了,如果没有加载就需要加载
  2. 为对象分配内存空间
  3. 处理并发安全问题(例如多个线程同时申请对象,JVM要保证给对象分配的空间不冲突)
  4. 初始化所分配的空间⬇️
    即:对象空间申请好之后,对象中包含的成员已经设置好初始值,所以我们声明字段之后并没有出现错误
    在这里插入图片描述
    5.调用构造方法,给对象中的成员赋值

5.4就地初始化

public class Date1 {
    public int year=1900;
    public int month=1;
    public int day=1;
    public Date1(){
        
    }
    public Date1(int year,int month,int day){
        
    }
    public static void main(String[] args) {
       Date1 d1=new Date1(2021,1,2);
       Date1 d2=new Date1();
    }
}

这种初始化的方式没有意义,不建议使用

🦈代码编译完成后,编译器会将所有给成员初始化的这些语句添加到构造函数中


至此,this访问成员方法,成员变量和其他构造方法已经使用过,总结一下

💵this.data访问当前对象的成员变量
💴this.func()访问当前对象的成员方法
💶this()调用当前对象的其他构造方法

6.封装

6.1封装的概念

面向对象三大特性:封装,继承,多态,现阶段我们需要认识的是封装,什么是封装?
就是套壳屏蔽细节
在这里插入图片描述
这是一台电脑,对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB插孔等,让用户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU、显卡、内存等一些硬件元件。 对于使用者而言我们不去关心主板上的线路是如何布置的,键盘是如何连接的。因此计算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可。

🗣封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互

6.2访问限定符

在这里插入图片描述
比如:
public可以理解为一个人长什么样子大家都知道
default一个公司或者一家人都知道的秘密,对于集体之外的人来说就是隐私了
private只有自己知道,除你之外任何人都不知道

public class Computer {
    private String cpu;
    private String memory;
    public String screen;
    String brand; // 品牌---->default属性

    public Computer(String brand, String cpu, String memory, String screen) {
        this.brand = brand;
        this.cpu = cpu;
        this.memory = memory;
        this.screen = screen;
    }

    public void Boot() {
        System.out.println("开机~~~");

    }

    public void PowerOff() {
        System.out.println("关机~~~");
    }

    public void SurfInternet() {
        System.out.println("上网~~~");
    }

    public static void main(String[] args) {


       
        Computer p = new Computer("HW", "i7", "8G", "13*14");
        System.out.println(p.brand);//default属性:只能在包中才能访问
        System.out.println(p.screen);// public属性: 可以任何其他类访问
        System.out.println(p.cpu);// private属性:只能在Computer类中才能访问,不能被其他类访问
    }
}

注意:一般情况下成员变量设置为private,成员方法设置为public

6.3封装扩展之包

6.3.1包的概念

为了更好的管理不同的类,把多个类收集在一起成为一组,称为软件包
例如下图,为了更好的管理电脑中的书籍,我们将不同种类的书籍放在相同的文件夹中。在Java中引入了包这个概念,包是对类,接口等封装机制的体现,是一种对类或者接口等的很好的组织方式,以及在一个工程中允许存在相同名称的类,只要在不同包中即可

在这里插入图片描述

6.3.2导入包中的类

Java 中已经提供了很多现成的类供我们使用. 例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的 Date类。


public class Test {
    public static void main(String[] args) {
        java.util.Date date=new java.util.Date();
        // 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
    }
}

在这里插入图片描述
可以直接使用import直接导入包

⬇️

import java.util.Date;
public class Test {
    public static void main(String[] args) {
        Date date=new Date();
        // 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
    }
}
import java.util.*;
public class Date {
        public static void main(String[] args) {
            java.util.Date date=new java.util.Date();
            // 得到一个毫秒级别的时间戳
            System.out.println(date.getTime());
           
        }
}

这里要注意的是import java.util.*;并不是把里面所有的都导出来,随用随取,用到哪个类就会导哪个类

6.3.3自定义包

1️⃣
在这里插入图片描述

2️⃣
在这里插入图片描述

3️⃣
在这里插入图片描述
以上就是我们自定义创建的包
在目录中也可以查找

⬇️

在这里插入图片描述

6.3.4包的访问权限


package demo1;

public class TestDemo1 {
    private String name;
    public int age;
    String work;

    public void care(){
        System.out.println("her name is "+name);
    }
    public void talk(){
        System.out.println(name+" "+"where are you");


    }

}


将成员以及方法放在demo1中的TestDemo1的类中

package demo1;

public class TestDemo2 {

        public static void main(String[] args) {
            TestDemo1 demo1=new TestDemo1();
            demo1.name="橘子";
            System.out.println(demo1.age);
            demo1.talk();
            demo1.work="hangzhou";
        }
    }


在这里插入图片描述


将main方法放在demo1中的TestDemo2的类中,名字是由private修饰,只能在当前类中访问

package demo2;

public class TestDemo3 {
    public static void main(String[] args) {
        System.out.println(demo1.work);
    }
}


在这里插入图片描述
work是默认权限,不允许被其他包中的类访问

6.3.5常见的包

🤖

  1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
  2. java.sql:进行数据库开发的支持包。
  3. java.lang.reflect:java 反射编程包;
  4. java.net:进行网络编程开发包。
  5. java.io:I/O编程开发包。
  6. java.util:是java提供的工具程序包。(集合类等) 非常重要

7.static成员

7.1再谈学生类

public class Student {

    public String name;
    public String gender;
    public int age;
    public double score;

    public Student(String name, String gender, int age, double score) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.score = score;
    }

    public static void main(String[] args) {
            Student s1 = new Student("Li leilei", "男", 18, 3.8);
            Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
            Student s3 = new Student("Jim", "男", 18, 2.6);
        }
}

在这里插入图片描述
我们假设这三位同学都需要在同一间教室上课,既然是在同一间教室上课,能否加上一个成员变量来保存同学们在一件教室上课?答案是无法做到。

7.2static修饰成员变量

在Java中,被static修饰的成员称为静态成员,静态成员变量最大的特性:不属于具体的对象,而是所有对象共享

成员变量:
1.静态成员变量/类变量/类成员
2.非静态成员变量/普通成员变量

public class Student {

    public String name;
    public String gender;
    public int age;
    public double score;
    public String classRoom="5b08";//这里的成员变量没有使用static修饰

    public Student(String name, String gender, int age, double score) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.score = score;
    }


    public static void main(String[] args) {
          //  System.out.println(Student.classRoom);
            Student s1 = new Student("Li leilei", "男", 18, 3.8);
            System.out.println(s1.classRoom);
            Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
            System.out.println(s2.classRoom);
            Student s3 = new Student("Jim", "男", 18, 2.6);
            System.out.println(s3.classRoom);

        }
}

在这里插入图片描述
🏣以上是没加staic修饰的情况


public class Student {

    public String name;
    public String gender;
    public int age;
    public double score;
   public static String classRoom="5b08";


    public Student(String name, String gender, int age, double score) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.score = score;
    }


    public static void main(String[] args) {
            System.out.println(Student.classRoom);
            Student s1 = new Student("Li leilei", "男", 18, 3.8);

            Student s2 = new Student("Han MeiMei", "女", 19, 4.0);

            Student s3 = new Student("Jim", "男", 18, 2.6);


        }
}

在这里插入图片描述
🏣以上是加了static修饰的情况
我们从调试的窗口中看到,static修饰的成员变量并没有存储到具体的某个对象,静态成员变量是共享的。

📟静态成员变量属性:
1.不属于某个具体的对象,**是类的属性,所有对象共享,**不存储在某个对象的空间中
2.一般使用推荐类名进行访问
在这里插入图片描述
3.类方法存储在方法区当中

在这里插入图片描述

4.声明周期伴随类的一生(即:随着类的加载而创建,随类的卸载而销毁)
5.静态的不依赖对象,这点要记住⬇️

在这里插入图片描述

7.3static修饰成员方法

如果我们把成员变量设置为private,成员方法设置为public,之前被我们设置为static的静态成员变量classRoom怎么在类外访问呢?🤔

成员方法:
1.静态成员方法/类方法
2.非静态成员方法


🗣我们需要关注3个点

1️⃣在静态方法内部不能直接调用非静态成员方法。在静态方法内部,不能直接使用非静态的数据成员

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


2️⃣只要是非静态的数据成员都需要通过对象的引用才能调用
在这里插入图片描述
在这里插入图片描述

public class Student {

    public String name;
    public String gender;
    public  int age;
    public  double score;
    public static String classRoom = "5b08";

    private static  int size=9;
    public static int getSize() {
        return size;
    }

    public static void setSize(int size) {
        Student.size = size;
    }

    public void mainStaticFunc(){
        System.out.println("非静态成员方法");
    }

    public static  void func(){

        System.out.println("静态成员方法");

    }
    public static void main(String[] args) {
        Student test=new Student();
        System.out.println(test.size);
   	 }
    }

我们在声明成员变量的阶段定义了一个静态成员变量的size,通过实例化对象的方式进行访问并输出⬇️

在这里插入图片描述

是不是很麻烦,所以我们建议获取静态成员变量或者是设置静态的成员变量,此时的方法最好是静态的,如果是非静态的,还需要实例化对象,等于说是画蛇添足没有意义。


3️⃣静态方法可以通过对象调用,也可以通过类名.静态方法名来调用,不过切记,不能在静态方法中使用this

在这里插入图片描述

7.4static成员变量初始化

注意:静态成员变量初始化一般不会放在构造方法中来初始化,构造方法中初始化是与对象相关的实例属性

静态成员变量的初始化分两种:就地初始化和静态代码初始化

1️⃣就地初始化
就地初始化是指:在定义的时候给出初始值

public class Student{
	private static String name="lisi";
	private static String gender="女";
	private static String classRoom="5b08"
//这是直接赋值的方法
}

还有一种就是通过get和set的方法来进行初始化,我们在刚刚的size也提到过,顺序是如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就是对一个静态成员变量进行初始化


ps:Constructor是构造方法初始化,注意区别
在这里插入图片描述
在这里插入图片描述
这里可以选择对设定的成员变量使用构造方法的方式进行初始化。

静态代码块初始化又是什么意思呢,往下看⬇️

8.代码块

8.1代码块概念以及分类

使用中括号{}定义的一段代码称为代码块,根据代码块定义的位置以及关键字,可分为4种

  • 普通代码块
  • 构造块
  • 静态块
  • 同步代码块(这里不做详细解释,后续会介绍)

8.2普通代码块

普通代码块:定义在方法中的代码块。

public class Main {
    public static void main(String[] args) {
       int x=10;
        System.out.println("x="+x);
    }
}

8.3构造代码块

构造块:定义在类中的代码块(不加任何修饰符)也叫做:实例代码块。构造代码块一般用于初始化实例成员变量。

public class Student {
    //实例成员变量
    private String name;
    private String gender;
    private int age;



public  Student(){
    System.out.println("成员方法");
}


    //实例代码块:对成员变量进行初始化
    {
        this.name="Jason";
        this.age=21;
        this.gender="man";
        System.out.println("构造代码块");
    }

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

    public static void main(String[] args) {
        Student stu=new Student();
        stu.show();



    }
}

在这里插入图片描述
注意:如果都是非静态代码块那么看定义的顺序


8.4静态代码块

如果静态的,非静态的,构造方法都在一起,运行起来的顺序是如何?

public class Student {
    //实例成员变量
    private String name;
    private String gender;
    private int age;
    private static String classRoom;





    //实例代码块:对成员变量进行初始化
    {
        this.name="Jason";
        this.age=21;
        this.gender="man";
        System.out.println("非静态代码块/实例化代码块/构造代码块->初始化非静态的数据成员");
    }


    //静态代码块
    static {
    classRoom="5b08";
        System.out.println("静态代码块->初始化静态的数据成员/提前准备一些数据");

    }
    public  Student(){
        System.out.println("不带参数的构造方法");
    }

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


    public static void main(String[] args) {
        Student s1=new Student();
        System.out.println("=====================");
        Student s2=new Student();
    }



//    public static void main1(String[] args) {
//        Student s1=new Student();
//        Student s2=new Student();
//
//
//
//
//    }
}

在这里插入图片描述
通过上述代码我们不难发现静态的代码是最先执行的,并且只执行了一次,然后到我们的非静态代码块,最后是构造方法。

  • 静态代码不管生成多少个对象,只会执行一次
  • 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
  • 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后顺序执行
  • 实例代码块只有在创建对象时才会执行
    ⬇️
    在这里插入图片描述

在面向对象的学习中深感愚钝,静态方法部分内容讲解若有偏差,望指正。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值