Skip to content

Java面向对象核心:类与对象、封装、构造方法与static关键字

一、核心知识点

1. 匿名对象

1.1 概念

匿名对象是指没有名字的对象,只有 new 对象(),没有等号左边的部分。

java
Person p = new Person();  // 有名对象
new Person();             // 匿名对象

1.2 使用方式

java
new 类名().成员名;

1.3 注意事项

  • 如果涉及到赋值,千万不要用匿名对象
  • 使用场景:简单调用一个方法,让方法执行一次

1.4 代码示例

java
public class Person {
    String name;
    public void eat(){
        System.out.println("吃饭");
    }
}

public class Demo01Object {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "张三";
        System.out.println(p1.name);
        p1.eat();

        System.out.println("==================");

        new Person().eat();

        new Person().name = "李四";
        System.out.println(new Person().name);
    }
}

匿名对象演示


2. 对象内存图解

2.1 一个对象的内存图

java
public class Phone {
    String brand;
    int price;

    public void call(){
        System.out.println("打电话");
    }
}

public class Demo01Object {
    public static void main(String[] args) {
        Phone phone1 = new Phone();
        System.out.println(phone1);
        System.out.println(phone1.brand);
        System.out.println(phone1.price);
        phone1.brand = "华为";
        phone1.price = 8888;
        System.out.println(phone1.brand);
        System.out.println(phone1.price);
        phone1.call();
    }
}

一个对象的内存图

2.2 两个对象的内存图

new了两次对象,在堆内存中开辟了两个不同的空间,修改一个空间中的数据不会影响到另外一个空间的数据。

两个对象的内存图

2.3 两个对象指向同一片空间

phone2是phone1给的,会将phone1的地址值给phone2,此时phone1和phone2地址值是一样的,操作同一个空间中的数据,所以修改一个对象的数据会影响另外一个对象。

两个对象指向同一片空间


3. 成员变量与局部变量

区别成员变量局部变量
定义位置类中方法外方法内或形参位置
初始化值有默认值没有默认值,必须手动赋值
作用范围整个类只作用于自己方法内部
内存位置堆中栈中
生命周期随对象创建而创建,随对象消失而消失随方法执行而创建,随方法消失而消失
java
public class Person {
    String name;

    public void eat() {
        System.out.println(name);
        int i = 10;
        System.out.println(i);
    }

    public void show() {
        System.out.println(name);
    }
}

4. 封装

4.1 面向对象三大特征

  • 封装
  • 继承
  • 多态

4.2 封装概述

隐藏细节(不让外界随便调用),对外提供公共的接口(让外界通过这个公共接口间接使用封装起来的细节)。

4.3 private关键字

被private修饰的成员只能在本类中直接使用,别的类中不能直接使用。

4.4 公共接口:get/set方法

方法作用
getxxx()获取属性值
setxxx()为属性赋值
java
public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
}

private关键字演示


5. this关键字

5.1 概述

代表当前对象(哪个对象调用的this所在的那个方法,this就代表哪个对象)。

5.2 作用

区分重名的成员变量和局部变量,this.后面的就是成员变量。

java
public class Person {
    String name;
    public void speak(String name){
        System.out.println(this.name+"您好,我是"+name);
    }
}

this关键字演示


6. 构造方法

6.1 特点

  • 方法名和类名一致
  • 构造方法没有返回值,连void都没有
  • 一new就相当于调用了构造方法

6.2 空参构造

java
public 类名(){

}

作用:new对象,初始化对象的属性

特点:每个类中都默认有一个无参构造,即使不写,jvm也会默认提供一个

6.3 有参构造

java
public 类名(形参){
    为属性赋值
}

作用

  • new对象
  • 为属性赋值

注意:如果写了有参构造,jvm将不再提供无参构造,所以建议无参的、有参的构造都写出来

6.4 代码示例

java
public class Person {
    private String name;
    private int age;

    public Person(){
    }

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

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
}

构造方法演示


7. 标准JavaBean

7.1 规范要求

  1. 类必须是具体的(非抽象 abstract)和公共的,public class 类名
  2. 具有无参数的构造方法
  3. 成员变量私有化,并提供用来操作成员变量的set和get方法

7.2 标准代码示例

java
public class Student {
    private int sid;
    private String name;

    public Student() {
    }

    public Student(int sid, String name) {
        this.sid = sid;
        this.name = name;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

7.3 快捷键生成

通用快捷键:alt+insertalt+fn+insert

快捷键演示


8. static关键字

8.1 概述

static是静态关键字,可以修饰方法和成员变量。

修饰方法

java
权限修饰符 static 返回值类型 方法名(形参){
    方法体
    return 结果
}

修饰成员变量

java
权限修饰符 static 数据类型 变量名

8.2 特点

特点说明
归属静态成员属于类成员,不属于对象成员
加载时机静态成员会随着类的加载而加载
优先级静态成员优先于对象存在
共享性凡是根据static关键字所在的类创建出来的对象,都可以共享这个静态成员

8.3 代码示例

java
public class Student {
    int id;
    String name;
    static String classRoom;
}

public class Demo01Static {
    public static void main(String[] args) {
        Student.classRoom = "教研室6";

        Student s1 = new Student();
        s1.id = 1;
        s1.name = "张三";
        System.out.println(s1.id+"..."+s1.name+"..."+Student.classRoom);

        Student s2 = new Student();
        s2.id = 2;
        s2.name = "李四";
        System.out.println(s2.id+"..."+s2.name+"..."+Student.classRoom);
    }
}

static关键字演示

8.4 static成员访问特点

场景能否直接访问访问方式
静态方法中访问非静态成员不能new对象访问
静态方法中访问静态成员同类直接调用,不同类类名调用
非静态方法中访问静态成员同类直接调用,不同类类名调用
非静态方法中访问非静态成员同类直接调用,不同类new对象调用

8.5 使用场景

工具类:拥有多个通用性功能的类

工具类要求

  • 构造私有化
  • 成员都是静态的
java
public class ArrayTools {
    private ArrayTools(){}

    public static int getSum(int[] arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }
}

public class Test01 {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30, 40, 50};
        System.out.println(ArrayTools.getSum(arr));
    }
}

二、常见面试题

⭐ 基础题

Q1: 匿名对象的使用场景是什么?什么情况下不能使用匿名对象?

答:

  • 使用场景:简单调用一个方法,让方法执行一次
  • 不能使用的情况:涉及到赋值操作时,因为每次new都会创建新对象,赋值后无法获取

Q2: 成员变量和局部变量有什么区别?

答:

区别成员变量局部变量
定义位置类中方法外方法内或形参位置
初始化值有默认值没有默认值,必须手动赋值
作用范围整个类只作用于自己方法内部
内存位置堆中栈中
生命周期随对象创建而创建随方法执行而创建

Q3: private关键字的作用是什么?

答:被private修饰的成员只能在本类中直接使用,别的类中不能直接使用,实现了封装的隐藏细节功能。


⭐⭐ 进阶题

Q4: this关键字的作用是什么?

答:

  • 代表当前对象(哪个对象调用的this所在的那个方法,this就代表哪个对象)
  • 可以区分重名的成员变量和局部变量,this.后面的就是成员变量

Q5: 构造方法有什么特点?空参构造和有参构造的作用分别是什么?

答:

  • 特点:方法名和类名一致;没有返回值,连void都没有;一new就相当于调用构造方法
  • 空参构造:new对象,初始化对象的属性
  • 有参构造:new对象的同时为属性赋值

Q6: 如果写了有参构造,还需要写空参构造吗?为什么?

答:需要。如果写了有参构造,jvm将不再提供无参构造。如果后续需要使用空参构造创建对象,就会报错,所以建议都写出来。


Q7: 有参构造可以new对象并为属性赋值,那还需要set方法吗?

答:需要。如果我们要单独修改一个属性的值,没有必要重新new对象,直接利用对象的set方法就可以单独为属性改值。


⭐⭐⭐ 高级题

Q8: static关键字有什么特点?静态成员什么时候使用?

答:

  • 特点:
    • 静态成员属于类成员,不属于对象成员
    • 静态成员会随着类的加载而加载
    • 静态成员优先于对象存在
    • 同一个类的所有对象共享静态成员
  • 使用场景:定义工具类时,工具类中的成员都是静态成员

Q9: 在静态方法中能否直接访问非静态成员?为什么?

答:不能。因为静态成员随着类的加载而加载,优先于对象存在。非静态成员属于对象,需要创建对象才能访问。在静态方法中想访问非静态成员,需要先new对象。


Q10: 什么是标准JavaBean?它有哪些规范要求?

答:JavaBean是Java语言编写类的一种标准规范。规范要求:

  1. 类必须是具体的(非抽象)和公共的
  2. 具有无参数的构造方法
  3. 成员变量私有化,并提供set和get方法

Q11: 两个对象指向同一片内存空间会有什么影响?

答:当一个对象将地址值赋给另一个对象时,两个对象指向同一片内存空间。此时修改一个对象的数据会影响另一个对象,因为它们操作的是同一片内存区域。


三、实用代码片段

1. 标准JavaBean模板

java
public class Student {
    private int sid;
    private String name;

    public Student() {
    }

    public Student(int sid, String name) {
        this.sid = sid;
        this.name = name;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2. 工具类模板

java
public class ArrayTools {
    private ArrayTools(){}

    public static int getSum(int[] arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }
}

3. 封装使用示例

java
public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        if(age < 0 || age > 120) {
            System.out.println("年龄输入有误");
            return;
        }
        this.age = age;
    }
    public int getAge() {
        return age;
    }
}

四、经典练习题

练习1:定义生日类

题目:定义一个类MyDate,代表生日,类中定义三个属性,分别为year、month、day,并为三个属性赋值。

参考答案

java
public class MyDate {
    private int year;
    private int month;
    private int day;

    public MyDate() {
    }

    public MyDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }
}

练习2:定义公民类

题目:定义一个公民类Citizen,类中定义三个属性,分别为cardId(String)、name(String)、MyDate(MyDate),并为三个属性赋值。

注意:如果属性为自定义的类型,赋值时需要new对象赋值,不然直接调用时会出现空指针异常。

参考答案

java
public class Citizen {
    private String cardId;
    private String name;
    private MyDate birthday;

    public Citizen() {
    }

    public Citizen(String cardId, String name, MyDate birthday) {
        this.cardId = cardId;
        this.name = name;
        this.birthday = birthday;
    }

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }
}

public class Test {
    public static void main(String[] args) {
        Citizen c = new Citizen();
        c.setCardId("110101199001011234");
        c.setName("张三");
        c.setBirthday(new MyDate(1990, 1, 1));
        
        System.out.println("身份证号:" + c.getCardId());
        System.out.println("姓名:" + c.getName());
        System.out.println("生日:" + c.getBirthday().getYear() + "年" 
            + c.getBirthday().getMonth() + "月" 
            + c.getBirthday().getDay() + "日");
    }
}

五、知识小结

核心要点速记

知识点核心要点
匿名对象没有名字的对象,只适合简单调用方法,不适合赋值
成员变量vs局部变量位置、初始化、作用范围、内存、生命周期五方面区别
封装隐藏细节,对外提供公共接口(get/set)
private私有访问权限,只能在本类中直接使用
this代表当前对象,区分重名的成员变量和局部变量
构造方法方法名与类名相同,无返回值,用于创建对象和初始化
JavaBean公共类、无参构造、私有属性、get/set方法
static静态成员属于类,随类加载,优先于对象,被所有对象共享

快捷键速查

功能快捷键
生成构造方法/get/setalt+insertalt+fn+insert

六、学习建议

  1. 理解内存模型:通过内存图理解对象的创建和引用传递,这是理解面向对象的基础
  2. 掌握封装思想:private + get/set 是封装的核心体现,理解为什么要隐藏细节
  3. 熟练使用this:this关键字在构造方法和set方法中使用频繁,要理解其代表"当前对象"的含义
  4. 区分static和非static:理解静态成员属于类,非静态成员属于对象的区别
  5. 多写标准JavaBean:这是Java开发中最常用的类结构,要能快速编写