Nibbles Blog Nibbles Blog
  • 专题汇总
    • 技术学习
    • 个人成长
    • 运营技能
    • 自媒体
    • Minecraft
  • 推荐
    • 专业高可用AI
    • 好物推荐
    • APP推荐
  • 关于我
  • 友情链接
首页 › 技术学习 › 类和对象 | Java语言关键

类和对象 | Java语言关键

Avatar photo
Nibbles 尼布
5 9 月, 2025

在之前文章中已经入门简单的语法,那么接下来将讲到Java中很重要的概念——面向对象。

在Java的Wikipedia中多范式(Paradigm)的条目中是这样解释的:

generic, object-oriented (class-based), functional, imperative, reflective, concurrent
通用、面向对象(基于类)、函数式、命令式、反射式、并发

介绍

类是一种创建对象的图纸,对象是根据类所创建的实例。

可以在类中定义好属性(描述其的变量)和方法(可以执行的操作)。而根据类来创建的对象,也就具有了这些属性和可使用的方法。如果要创建多个同类对象,只需要根据同一类来创建这多个对象即可,这样大大方便了代码的复用与维护。

面向对象(OOP)可以看作为是一种编程思想,指的是利用对象之间的交互去实现功能。

这样以面向对象的形式来组织代码,就可以做到比如引入外部的类,直接使用方法和属性,而且无需知道和细究方法内部的具体实现,只需要知道方法能做到的功能即可。

对一个对象的重新认识的一个过程就是对对象进行抽象。

类的定义

public class Demo {
    public int number;
    public void out(){
        System.out.println("OUT");
    }

}

如上,一个类的定义包含:

  • 类的名字,一般我们使用大驼峰命名法(如ClassName),名字中每个英文都是大写。
  • 成员变量
  • 成员方法

一般建议,一个文件中定义一个类。 且public修饰的类名必须要和文件名相同,而且这样的类名最好通过IDE的内置工具修改。

你可能会感觉到这和C语言的结构体很像,但是与之不同的是,Java的类是面向对象的,且包含了成员变量和成员方法,支持访问控制修饰符(public/private等),并且还有继承、多态等多种机制。这些会在后续展开。

类的实例化=对象

用类类型创建对象的过程,称为类的实例化。实例化的代码:

public class Test {
    public static void main(String[] args) {
        Demo obj = new Demo();
        obj.out();
    }
}

这样如第三行所示的格式,就是一个创建对象的语句。(关键字是new , 所以常有人说“new一个对象”)

而创建好的名为obj的对象就是根据名为Demo的类创建的。之后我访问了Demo类中的成员方法(见第四行),访问或修改类中的成员一般使用点号( . ),这样就成功输出了“OUT”

这样从内存空间存储的角度上,类这个“图纸”其实并不会占用程序运行时候用的堆内存,只是作为一种设计蓝图,一种元数据被存储在方法区,而根据类创建出对象才是真正会开辟堆内存空间的,所以这样也就更好地理解了为什么创建对象能被称为“实例化”。

this引用

在成员方法内,当出现方法中定义的形参和成员变量相同的时候,就需要用this+点号( this. )来表示指明是这个对象的成员变量。

类似的,前面说到可以一个类可以创建多个对象,那么试想在这个类中有负责传入参数的成员方法,程序如何知道传给哪个对象相应的数据?同样也是借助了 this 对当前对象的引用。

回到前面,讲讲如何对这个对象内的成员变量进行赋值。

如果只是类内对成员变量指定初始值的话直接就是一条 public int yes = 1;即可,但是不可以拆开来两条去写,如public int yes; yes = 1; 。这是因为对于类内只能有“成员的声明”和“初始化块”,而前条语句会被判为初始化,而后者会被认为是普通语句不可使用。

如果对于对象,不同的对象希望有不同的变量值的话,则需要写修改器,这也是种成员方法。而且对于IDEA很简单,可以直接借助内置工具生成。在类的文件内右键选择 Generate… (ALT+Insert快捷键) -> 选择 Setter, 然后在弹出的窗口中选中需要使用的修改器传入值的变量。则编辑器会直接生成如下的的代码:

public void setNumber(int number) {
    this.number = number;
}

你会发现,在第二行好像自带了一个 this ,没错,就是在这里做到了让程序知道值应该传递给哪个对象。只要哪个对象调用了这个方法,那么这个 this 就是代指哪个对象。只能引用当前对象,不能再引用其他对象。而且有的时候编译器会在成员方法会被执行的时候将其自动传递。

看一个自动传递的例子,还有种方法叫做访问器,这也是种成员方法。还是右键,Generate… (ALT+Insert快捷键) -> 选择 Getter,然后在弹出的窗口选择需要输出的变量。就会生成一个我们很熟悉的用于打印变量的方法:

public void numOut(){
    System.out.println(number);
}
// 一般直接生成的是上面这样的

public void numOut(){
    System.out.println(this.number);
}

其实简单改改自动生成的方法如第二段所示的,会发现结果也是一样。而这种情况即使不写,编译器也会自动加上 this 。

构造方法

也成为构造器,也是一个特殊的成员方法。名字必须与类名相同,在创建对象的时候由编译器自动调用,并且在整个对象的生命周期内只使用一次。

// 文件Student.java中
public class Student {
    public String name;
    public int age;
    public String gender;

    // 构造方法
    public Student(String name, int age, String gender) {
        this.name=name;
        this.age=age;
        this.gender=gender;
    }
    public Student(){
        this.name="nameless";
        this.age=0;
        this.gender="boy";
    }

}

需要注意的几点是:无需设置返回值也不能设置,可以重载(即同一方法可以按照使用场景设置不同的参数,如上无参数的构造方法,可以作为指定成员变量的默认值的一种方式)

如果开发者没有显式定义(如上直接在类中写出构造方法即为显式定义),则编译器会默认生成一个不带参数的构造方法。如果有则不再额外生成。

如果只是无参来指定默认值的话,上述无参的构造方法还可以用this简化为:

public class Student {
    public String name;
    public int age;
    public String gender;

    // 构造方法
    public Student(){
        this("nameless",0,"boy");
    }
    public Student(String name, int age, String gender) {
        this.name=name;
        this.age=age;
        this.gender=gender;
    }
    
}

注意,使用this()调用其他构造方法时,必须将该调用语句放在构造方法的第一行

绝大多数情况下使用public来修饰,特殊场景下会被private修饰(单例)

对象打印

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

用上面的代码直接打印会输出 Student@3b07d329 这样的“类名@hash值”的格式。

但是如果想要打印对象中的成员变量,可以使用类中重写的 toString 方法。因为在上面的例子中,对于对象是直接进行了“sout”打印,实际上在类中是在调用一个默认的 toString 成员方法。

IDEA也可以生成一个简单的重写方法,右键,Generate… (ALT+Insert快捷键) -> 选择 toString -> 选择要打印的成员变量即可。

public class Student {
    public String name;
    public int age;
    public String gender;

    public Student(){
        this("nameless",0,"boy");
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

如果希望自己写 toString ,记得加上 @Override 注解确保正确重写。

之后会继续讲包、封装、还有继承、多态等,虽然在本文有部分是提到但暂不细讲,循序渐进。

声明:本站原创文章文字版权归本站所有,转载务必注明作者和出处;本站转载文章仅仅代表原作者观点,不代表本站立场,图文版权归原作者所有。如有侵权,请联系我们删除。 评论网址声明:仅接受个人技术博客或诸如Travelling博客联盟的链接,本站已接入ICP备案与公安备案,所有伪ICP备案的站点评论和邀请一律回绝。
Java
1
0
Avatar photo
Nibbles 尼布
向着终生成长者迈进!
赞赏

评论 (0)

取消
    发表评论

猜你喜欢

  • 包和封装 | Java语言关键
  • 运算符 | Java语言基础
  • 变量详解 | Java语言基础

公众号同步更新

🔍微信搜一搜“尼布技术志”

AIAPI站点新老用户回馈!

文章目录

  • SiteMap
  • Umami
  • CSDN
  • xLog
  • Substack
Copyright © 2022-2025 Nibbles Blog. Designed by nicetheme. 浙公网安备33038102332481号 浙ICP备2024120131号
合作: AIAPIs.VIP 技术小铺
  • Java6
  • C语言4
  • python2
  • AI2
  • 公众号2
  • 专题汇总
    • 技术学习
    • 个人成长
    • 运营技能
    • 自媒体
    • Minecraft
  • 推荐
    • 专业高可用AI
    • 好物推荐
    • APP推荐
  • 关于我
  • 友情链接