Java类和对象全面解析

 更新时间:2026年05月22日 09:46:08   作者:01_ice  
本文介绍了Java面向对象编程的核心概念,文章通过具体代码示例,帮助读者理解Java面向对象编程的基本原理和实践方法,感兴趣的朋友跟随小编一起看看吧

1,面向对象的初步认识

Java是⼀⻔纯⾯向对象的语⾔(ObjectOrientedProgram,简称OOP),在⾯向对象的世界⾥,⼀切皆为对象。⾯向对象是解决问题的⼀种思想,主要依靠对象之间的交互完成⼀件事情。⽤⾯向对象的思想来设计程序,更符合⼈们对事物的认知,对于⼤型程序的设计、扩展以及维护都⾮常友好。

相比于面向过程,面向对象更好维护

个人认为面向对象是把有关对象的所有事物写在类里面

2, 类

类的格式

class ClassName{
    field;//字段(属性)或者成员变量
    method;// ⾏为或者成员⽅法
}

class为类定义的关键字,Classname为类名,{}里是类的主体

类中包含的内容称为类的成员。属性主要是⽤来描述类的,称之为类的成员属性或者类成员变量。⽅法主要说明类具有哪些功能,称为类的成员⽅法

以豌豆射手为例

class PeaShooter {
        //类的成员变量
        public int HP;  //生命值
        public int cost;  //费用
        public int ATK;   //攻击
        public double firingInterval; //射击间隔
        //类的成员方法
        public void attackTheZombies() {  //攻击僵尸
            System.out.println("攻击僵尸");
        }
}
  • 类名采用大驼峰(单词首字母都大写)定义
  • 类的成员方法名采用小驼峰(第一个单词首字母小写,其余首字母大写)

注意

  1. 一个文件当中只定义一个类
  2. public修饰的类必须要和文件名相同
  3. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发⼯具修改

类的实例化

定义了⼀个类,就相当于在计算机中定义了⼀种新的类型,⽤类类型创建对象的过程,称为类的实例化,在java中采⽤new关键字,配合类名来实例化对象。说白了就是创建一个类。

public static void main(String[] args) {
        PeaShooter bob = new PeaShooter();
        PeaShooter dave = new PeaShooter();
}

访问对象中的成员

PeaShooter bob = new PeaShooter();  //new实例化
bob.HP = 300;
bob.cost = 100;
bob.ATK = 20;
bob.firingInterval = 1.4;
bob.AttackTheZombies();
  • 通过来访问对象中的属性和⽅法
  • 同⼀个类可以创建多个实例

3, 对象

this关键字

为什么要有this引⽤?

如下代码定义了⼀个Date类,Date类中包含3个属性分别是year,month,day。分别使⽤setDay和 printDate对进⾏设置和打印⽇期

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;
        }
        public void printDate(){
            System.out.println(year + "/" + month + "/" + day);
        }
        public static void main(String[] args) {
            //构造三个⽇期类型的对象d1 d2 d3
            Date d1 = new Date();
            Date d2 = new Date();
            Date d3 = new Date();
            //对d1,d2,d3的⽇期设置
            d1.setDay(2026,5,15);
            d2.setDay(2026,5,16);
            d3.setDay(2026,5,17);
            //打印⽇期中的内容
            d1.printDate();
            d2.printDate();
            d3.printDate();
        }
}

如果形参名和成员变量名相同会发生什么?

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

结果是year = 0,month = 0,day = 0,局部优先,所有year = year都是形参,成员变量就会使用默认值0。

三个对象都在调⽤setDate和printDate函数,但是这两个函数中没有任何有关对象的说明, setDate和printDate函数如何知道打印的是那个对象的数据呢?

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

public class Date {
    public int year;
    public int month;
    public int day;
    public void setDay(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void printDate(){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
    public static void main(String[] args) {
        Date d = new Date();
        d.setDay(2026,5,19);
        d.printDate();
    }
}

this引用当前对象d

this引用的特性

  • this的类型:对应类类型引⽤,即哪个对象调⽤就是哪个对象的引⽤类型
  • this只能在"成员⽅法"中使⽤
  • 在"成员⽅法"中,this只能引⽤当前对象,不能再引⽤其他对象
  • this是“成员⽅法”第⼀个隐藏的参数,编译器会⾃动传递,在成员⽅法执⾏时,编译器会负责将调⽤成员⽅法对象的引⽤传递给该成员⽅法,this负责来接收
public void setDay(Date this,int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
public void printDate(Date this){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
}

形参里面的this一般是隐藏的

对象的构造及初始化

在Java⽅法内部定义⼀个局部变量时,必须要初始化,否则会编译失败,那么类对象怎样初始化呢?

1.用方法传值

public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    d.setDate(2026,5,20);
    d.printDate();
}

每次对象创建好后调⽤SetDate⽅法设置具体⽇期,比较麻烦,那对象该如何初始化?

局部变量必须要初始化才能使⽤,为什么字段声明之后没有给值依然可以使⽤?

默认初始化

对于成员变量来说,如果没有进⾏初始化,会有⼀个对应的默认值

类型

默认值

byte0
short0
int0
long0
float0.0f
double0.0
char/u0000
booleanfalse
referencenull

缺省参数(默认值)初始化

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(2026,5,20);
        Date d2 = new Date();
    }
}

没有传参数的就用上面的默认值初始化

构造方法初始化

构造⽅法(也称为构造器)是⼀个特殊的成员⽅法,名字必须与类名相同,在创建对象时,由编译器⾃动调⽤,并且在整个对象的⽣命周期内只调⽤⼀次。

public class Date {
    public int year;
    public int month;
    public int day;
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)⽅法被调⽤了 ");
    }
    public void printDate(Date this){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
    public static void main(String[] args) {
        //此处创建了⼀个Date类型的对象,并没有显式调⽤构造⽅法
        Date d = new Date(2026,5,20);   //输出Date(int,int,int)⽅法被调⽤了
        d.printDate();    // 2026/5/20
    }
}

注意事项:

  1. 名字必须和类名相同
  2. 没有返回值类型,设置为void也不⾏
  3. 创建对象时由编译器⾃动调⽤,并且在对象的⽣命周期内只调⽤⼀次(相当于⼈的出⽣,每个⼈只能出⽣⼀次)
  4. 构造⽅法可以重载(用户根据⾃⼰的需求提供不同参数的构造⽅法)

根据参数不同调用不同的构造(如果有的话)

public class Date {
    public int year;
    public int month;
    public int day;
    public Date() {
        this.year = 2026;
        this.month = 1;
        this.day = 1;
        System.out.println("Date()⽅法被调⽤了 ");
    }
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)⽅法被调⽤了 ");
    }
    public void printDate(Date this){
        System.out.println(this.year + "/" + this.month + "/" + this.day);
    }
    public static void main(String[] args) {
        //此处创建了⼀个Date类型的对象,并没有显式调⽤构造⽅法
        Date d1 = new Date(2026,5,20);   //输出Date(int,int,int)⽅法被调⽤了
        Date d2 = new Date();
        d1.printDate();    // 2026/5/20
        d2.printDate();    // 2026/1/1
    }
}

如果用户没有显式定义,编译器会⽣成⼀份默认的构造⽅法,⽣成的默认构造⽅法⼀定是⽆参的,

数值全是取的默认值,如果用户显式定义了构造方法就不会调用默认构造

构造⽅法中,可以通过this调⽤其他构造⽅法来简化代码

public Date(){
    this(1900, 1, 1);
}
// 带有三个参数的构造⽅法
public Date(int year, int month, int day) {
    this.year = year;
    this.month = month;
    this.day = day;
}
  • this(...)必须是构造方法的第一条语句
  • 不能形成环的调用(a调用b,b同时调用a)

对象的打印

public class Person {
    String name;
    String gender;
    int age;
    public Person(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }
    public static void main(String[] args) {
        Person person = new Person("Jim"," 男 ", 18);
        System.out.println(person);//Person@4eec7777
    }
}

如果我们直接打印对象的引⽤,此时输出的结果为:类路径名@对象的hashcode值

如果想要默认打印对象中的属性该如何处理呢?答案:重写toString⽅法即可

public class Person {
    String name;
    String gender;
    int age;
    public Person(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
}
    @Override
    public String toString() {
        return "[" + name + "," + gender + "," + age + "]";
    }
    public static void main(String[] args) {
        Person person = new Person("Jim","男", 18);
        System.out.println(person);
    }
}

重写会在多态讲到

4,包

4.1 定义

包(Package)是Java中一个组织类的方式,用于防止类名冲突和提高代码的可读性。包允许将类组织在一个层次中,类似于文件系统中的目录。文件夹

包是对类,接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式。

4.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());
        }
}

如果需要使用java.util中的其他类,可以用import java.util.*,*是通配符

import java.util.*;

但是还是显示指定要导入的类名,否则可能会出现冲突的情况

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        // util 和 sql 中都存在⼀个 Date 这样的类, 此时就会出现歧义, 编译出错 
        Date date = new Date();
        System.out.println(date.getTime());
    }
}

不同包里如果有相同名字的类就会出错,这种情况就要写出完整的类名

使用import static导入包中静态的方法和字段

import static java.lang.Math.*;
public class Test {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
        // 静态导⼊的⽅式写起来更⽅便⼀些
        // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        double result = sqrt(pow(x, 2) + pow(y, 2));
        System.out.println(result);
    }
}

不建议使用这种方法

4.3 自定义包

4.3.1 基本规则

  • 在文件的最上方加上一个package语句指定该代码在哪个包中
  • 包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式(例如net.csdn.blog)
  • 包名要和代码路径相匹配,创建net.csdn.blog的包就会存在一个对应的路径net/csdn/blog来存储代码
  • 如果一个类没有package语句,类会放在一个默认包中

idea中新建包

4.3.2 常见的包

java.lang: 系统常⽤基础类 (String 、 Object), 此包从 JDK1.1 后⾃动导⼊。 java.lang.reflect:java 反射编程包 ;

java.net: 进⾏⽹络编程开发包。

java.sql: 进⾏数据库开发的⽀持包。

java.util: 是 java 提供的⼯具程序包。 ( 集合类等 )

java.io:I/O 编程开发包。

4.4 包的访问权限

如果我们在定⼀个类的时候,如果没有指定成员变量/成员⽅法的访问权限,此时默认的访问权限就是包访问权限

private String cpu;          
private String memory;       
public String screen;       
String brand; 

像brand就是默认权限(包访问权限),在下面访问限定符中会具体讲解

5,封装

5.1 封装的概念

面向对象的三大特性:封装,继承,多态。封装简单来说就是套壳屏蔽细节(封闭包装)

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

class Student{
    private String name; //使⽤ private  修饰
    private int age; //使⽤ private  修饰
    public void eat() {
        System.out.println(this.name + " 正在吃饭!");
    }
    public void show() {
        System.out.println("name: "+name+" 年龄:"+age);
    }
}
public class Test {
    public static void main(String[] args) {
        Student stu= new Student();
    }
}

上述代码使⽤private修饰之后,在Test类中⽆法通过person引⽤来进⾏访问数据,这⾥封装就起到 了作⽤! 如果要想访问,此时只能⼿动提供get和set⽅法作为公开的接口来进⾏访问。

idea中快速生成get和set方法

  1. 右键点生成

2.会在光标处自动生成

5.2 封装的好处

1.降低代码的耦合性

封装可以降低对象和对象之间的耦合度,当对象内部发⽣变化时,只需要修改对象内部即可,不会影响到外部程序,因为公开的接口是不会发⽣改变的

2.降低代码的复杂性

封装是隐藏了对象内部的实现细节,只提供了公开的接口给外部,使⽤起来更加简单

3.提高安全性

封装可以隐藏对象的具体实现细节,阻⽌外部程序直接访问对象的内部状态,从⽽保护数据不被意外修改或破坏

5.3 访问限定符详解

Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的⽅法结合在⼀起,更符合⼈类对事物的认知,⽽访问权限⽤来控制⽅法或者字段能否直接在类外使⽤。Java中提供了四种访问限定符:

编号范围私有(private)默认(default)保护(protected)公有(public)
1同一包中的同一类
2同一包中的不同类
3不同包中的子类
4不同包中的非子类
  • public修饰的成员变量,在所指情况下都是可以正常访问的
  • private只能在当前类中使用
  • default是什么都不加,只能在包当中才能访问

6,static关键字

6.1 修饰成员变量

class Student{
    private String name; 
    private int age; 
    public static String classRoom = "1-101";
}
public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student();
        Student stu2 = new Student();
        Student stu3 = new Student();
    }
}

被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。

静态成员变量的特性

  1. 不属于某个具体的对象,是类的属性,所有对象共享,不存储在某个对象的空间中,存储在方法区
  2. 既可以通过对象访问,也可以通过类名访问,但⼀般更推荐使⽤类名访问
  3. ⽣命周期伴随类的⼀⽣(随类的加载⽽创建,随类的卸载⽽销毁)

6.2 修饰成员方法

被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员⼀般是通过静态方法来访问的

public class Student{
    private static String classRoom = "409";
    public static String getClassRoom(){
        return classRoom;
    }
}
public class TestStudent {
    public static void main(String[] args) {
        System.out.println(Student.getClassRoom());
    }
}

静态方法特性

  • 不属于某个具体的对象,是类⽅法
  • 可以通过对象调⽤,也可以通过类名.静态⽅法名(...)⽅式调⽤,更推荐使⽤后者
  • 不能在静态⽅法中访问任何⾮静态成员变量
  • 在静态⽅法中调⽤时候⽆法传递this引⽤

6.3 static成员变量初始化

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

就地初始化

public static String classRoom = "1-101";

7,代码块

7.1 概念

就是{}里面的代码,一共分为4类

  1. 普通代码块
  2. 构造块
  3. 静态块
  4. 同步代码块

7.2 不同代码块的结构

{ //直接使⽤定义,普通⽅法块
       int x = 10 ;
       System.out.println("x1 = " +x);
}
 //实例代码块
{
    this.name = "cyy";
    this.age = 12;
    this.sex = "man";
}
// 静态代码块
 static {
        classRoom = "409";
        System.out.println("I am static init()!");
}

注意

  • 静态代码块不管⽣成多少个对象,其只会执⾏⼀次
  • 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
  • 如果⼀个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执⾏(合并)
  • 实例代码块只有在创建对象时才会执⾏

到此这篇关于Java类和对象全面解析的文章就介绍到这了,更多相关Java类和对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springmvc中的转发重定向和拦截器的示例

    Springmvc中的转发重定向和拦截器的示例

    本篇文章主要介绍了Springmvc中的转发重定向和拦截器的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Java解压zip文件的关键代码

    Java解压zip文件的关键代码

    本文给大家分享一段java解压zip文件的关键代码,代码简单易懂,非常不错,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-09-09
  • Java设计模式之观察者模式observer pattern详解

    Java设计模式之观察者模式observer pattern详解

    这篇文章主要介绍了Java设计模式之观察者模式observer pattern详解,当一个对象发生数据变化时,通知其他相关的一系列对象,接受到通知的对象根据该对象的变化进行相应处理以响应变化的过程,需要的朋友可以参考下
    2023-12-12
  • 详解SpringBoot中@NotNull,@NotBlank注解使用

    详解SpringBoot中@NotNull,@NotBlank注解使用

    这篇文章主要为大家详细介绍了Spring Boot中集成Validation与@NotNull,@NotBlank等注解的简单使用,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-08-08
  • Spring Boot 集成接口管理工具 Knife4j

    Spring Boot 集成接口管理工具 Knife4j

    这篇文章主要介绍了Spring Boot 集成接口管理工具 Knife4j,首先通过创建一个 Spring Boot 项目展开主题,需要的小伙伴可以参考一下
    2022-05-05
  • Spring Security使用数据库认证及用户密码加密和解密功能

    Spring Security使用数据库认证及用户密码加密和解密功能

    这篇文章主要介绍了Spring Security使用数据库认证及用户密码加密和解密,本文通过代码与截图的形式给大家介绍的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 浅析Java中SimpleDateFormat为什么是线程不安全的

    浅析Java中SimpleDateFormat为什么是线程不安全的

    SimpleDateFormat是Java中用于日期时间格式化的一个类,它提供了对日期的解析和格式化能力,本文主要来和大家一起探讨一下SimpleDateFormat为什么是线程不安全的,感兴趣的可以了解下
    2024-02-02
  • 如何在Spring Boot项目中使用Spring AI

    如何在Spring Boot项目中使用Spring AI

    Spring AI是Spring框架中用于集成和使用人工智能和机器学习功能的组件,它提供了一种简化的方式来与AI模型进行交互,这篇文章主要介绍了Spring Boot 在项目中使用Spring AI,需要的朋友可以参考下
    2024-05-05
  • 一篇文章教你如何在SpringCloud项目中使用OpenFeign

    一篇文章教你如何在SpringCloud项目中使用OpenFeign

    这篇文章主要介绍了SpringCloud 使用Open feign 优化详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-08-08
  • Java基础之CardLayout的使用

    Java基础之CardLayout的使用

    这篇文章主要介绍了Java基础之CardLayout的使用,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05

最新评论