Java基础快速入门: 面向对象核心基础

本文纲要

  1. 面向过程与面向对象编程思想对比
  2. 类与对象的关系
  3. 类的定义(成员变量与成员方法)
  4. 对象的创建与使用
  5. 案例:手机类的创建和使用
  6. 对象内存图(单个对象、两个对象、两个引用指向同一对象)
  7. 成员变量与局部变量的区别
  8. private 关键字与数据安全性
  9. this 关键字及其内存原理
  10. 封装思想
  11. 构造方法的格式与执行时机
  12. 构造方法的作用
  13. 构造方法的注意事项
  14. 标准 JavaBean 类的编写与使用
  15. 总结

面向过程与面向对象编程思想对比

1 ) 两种思想的定义

面向过程(Procedure Oriented Programming, POP):以过程为中心,每一步都由开发者自己实现。之前编写的所有代码基本都是面向过程的——例如遍历数组、求最大值,都需要手写循环、判断等每一步逻辑。

面向对象(Object Oriented Programming, OOP):以对象为中心,通过“指挥对象”来实现具体功能。重点在“指挥”二字,即找能干活的“对象”帮我们完成需求。

通俗理解:
面向过程 = 自己干活
面向对象 = 找别人(对象)干活

2 ) 生活案例

需求1:吃一盘“普罗旺斯茄块烩马铃薯”(地三鲜)
面向过程:自己买菜、学菜谱、洗菜、做菜……全包。
面向对象:指挥女朋友或厨师做菜,女朋友和厨师就是“对象”。

需求2:洗衣服
面向过程:自己泡衣服、洗、拧、晾。
面向对象:指挥洗衣机或女朋友,洗衣机和女朋友就是“对象”。

3 ) 代码对比

在代码中,同样遍历打印数组的需求,两种思想实现完全不同:

面向过程版本(自己一步步实现):

public class Demo1Pop {
    public static void main(String[] args) {
        int[] arr = {11,22,33,44,55};
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if(i == arr.length - 1){
                System.out.println(arr[i] + "]");
            }else{
                System.out.print(arr[i] + ", ");
            }
        }
    }
}

面向对象版本(指挥对象干活):

// 数组服务员对象(为演示思想使用了中文命名,实际开发需用英文)
public class 数组服务员 {
    public void 遍历打印数组(int[] arr){
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if(i == arr.length - 1){
                System.out.println(arr[i] + "]");
            }else{
                System.out.print(arr[i] + ", ");
            }
        }
    }
}
 
public class Demo1Oop {
    public static void main(String[] args) {
        int[] arr = {11,22,33,44,55};
        数组服务员 二狗 = new 数组服务员();
        二狗.遍历打印数组(arr);  // 指挥二狗对象干活 
    }
}

面向对象让我们从“执行者”切换到“指挥者”,但对象内部仍然是按面向过程的步骤实现功能。面向对象是基于面向过程演变而来的。

类与对象的关系

1 ) 什么是类

类是对现实世界一类具有共同属性和行为的事物的抽象,相当于一张“设计图”。例如“学生”类,描述了学生都有姓名、年龄、毕业院校等属性,以及学习、做开发等行为。

类的组成:
属性:事物的各种特征(如姓名、年龄)→ 在代码中用成员变量体现
行为:事物能完成的功能(如学习)→ 在代码中用成员方法体现

2 ) 什么是对象

对象是看得见摸得着的真实存在的实体。类只是描述,对象才是真正存在的具体事物。根据一张设计图(类),可以创建多个具体的对象。

3 ) 类与对象的关系

类是对对象的描述(模板)
对象是类的实体(实例)

例如:Student 类描述了学生这个群体,stu1、stu2 就是具体的学生对象。

类的定义

在 Java 中,类由成员变量和成员方法组成

定义步骤:

  1. 编写类:public class 类名 { }
  2. 在类中编写成员变量(属性)
  3. 在类中编写成员方法(行为)

代码示例:

package com.wb.object1;
 
public class Student {
    // 成员变量:姓名、年龄 
    String name;
    int age;
 
    // 成员方法:学习 
    public void study(){
        System.out.println("学习");
    }
}

注意:
成员变量的定义格式与普通变量相同,但位置在类中、方法外。
成员方法的格式与普通方法相同,但去掉 static 关键字。
类只负责描述事物,不应包含具体个人数据(如不应写死 name = “张三”),具体值应在创建对象后赋值。

对象的创建与使用

1 ) 创建对象格式

类名 对象名 = new 类名();

例如:Student stu = new Student();

2 ) 使用成员变量

对象名.变量名 

可以对变量赋值或取值。

3 ) 使用成员方法

对象名.方法名();

4 ) 示例代码

package com.wb.object1;
 
public class TestStudent {
    public static void main(String[] args) {
        Student stu = new Student();       // 创建对象 
        System.out.println(stu.name);      // null (默认初始化值)
        System.out.println(stu.age);       // 0 
 
        stu.name = "张三";                 // 为成员变量赋值 
        stu.age = 23;
        System.out.println(stu.name);      // 张三 
        System.out.println(stu.age);       // 23 
 
        stu.study();                       // 调用成员方法 
        System.out.println(stu);           // 打印地址值 
    }
}

输出包含内存地址(如 com.wb.object1.Student@b4c966a),其中 @ 前是全类名(包名+类名),@后是十六进制内存地址

案例:手机类的创建和使用

需求:定义手机类,包含品牌、价格属性,以及打电话、发短信方法;在测试类中创建对象并调用。

// Phone.java 
package com.wb.test1;
 
public class Phone {
    String brand;      // 品牌 
    int price;         // 价格 
 
    public void call(String name){
        System.out.println("给" + name + "打电话");
    }
 
    public void sendMessage(){
        System.out.println("群发短信");
    }
}

// TestPhone.java 
package com.wb.test1;
 
public class TestPhone {
    public static void main(String[] args) {
        Phone p = new Phone();
        p.brand = "大米";
        p.price = 2999;
        System.out.println(p.brand + "..." + p.price);
        p.call("阿强");
        p.sendMessage();
    }
}

运行结果:

大米...2999 
给阿强打电话 
群发短信

对象内存图

1 ) JVM 内存区域简要划分

栈内存:存放方法中的局部变量、方法运行时的内存模型。
堆内存:存放 new 出来的对象、数组,以及成员变量。
方法区:存放 .class 字节码文件(包括成员变量和成员方法的信息)。

2 ) 单个对象内存图

堆内存

栈内存

方法区

TestStudent.class
main方法

Student.class
成员变量: name,age
成员方法: study

main方法栈帧
s = 0x001

Student对象
地址0x001
name=null
age=0
study方法地址->B

执行流程:

  1. TestStudent.class 加载进方法区,main 方法进栈。
  2. 执行 Student stu = new Student(); → 加载 Student.class 进方法区,在堆中开辟空间,成员变量有默认初始化值(name=null, age=0),并存储成员方法的引用地址。
  3. 将堆中地址赋值给栈中的变量 stu。
  4. 通过 stu.name 等访问堆中变量,赋值或取值。
  5. 调用 stu.study() 时,根据堆中方法地址找到方法区中的方法,进栈执行。

3 ) 两个对象内存图

堆内存

栈内存

方法区

Student.class
name,age
study方法

s1 -> 0x001

s2 -> 0x002

Student对象
地址0x001
name=阿强
age=23

Student对象
地址0x002
name=阿珍
age=24

要点:
每个对象在堆中有自己独立的空间,成员变量各自存储。
多个对象共用同一份字节码文件,即共用一个成员方法(方法区中的 study),对象中只记录方法的地址。

4 ) 两个引用指向同一对象

Student stu1 = new Student();
stu1.name = "阿强";
Student stu2 = stu1;          // stu2 也指向 stu1 的对象 
stu2.name = "阿珍";
System.out.println(stu1.name); // 阿珍 
System.out.println(stu2.name); // 阿珍 

内存示意图:

stu1 -> 0x001

stu2 -> 0x001

对象0x001
name=阿珍

当 stu1 = null; 时,stu1 断开引用;若 stu2 也被置为 null,则堆中对象成为垃圾,会被 JVM 的垃圾回收器自动回收。

成员变量与局部变量的区别

区别点成员变量局部变量
类中位置类中、方法外方法内部,或方法的形参声明上
内存位置堆内存(对象内)栈内存(方法栈帧内)
生命周期随对象存在而存在,对象消失后消失随方法调用而存在,方法结束弹栈后消失
默认初始化值有(如 int 为 0,引用类型为 null)没有,必须手动赋值后才能使用

识别关键:看变量定义的位置,在类中方法外 → 成员变量;在方法中 → 局部变量。

private 关键字

1 ) 为什么需要 private
直接通过 对象名.变量名 访问成员变量存在安全隐患,比如为年龄赋值负数,代码无法阻止。

stu.age = -23; // 不合理,但程序不报错 

2 ) private 的作用
private 是一个权限修饰符,可修饰成员变量和成员方法。被 private 修饰的成员只能在本类中访问。

3 ) 标准做法:private + get/set 方法

私有化成员变量后,对外提供公共的 set 和 get 方法进行操作,可在方法中加入校验逻辑。

package com.wb.object2;
 
public class Student {
    String name;
    private int age;
 
    // 设置值,加入校验 
    public void setAge(int a){
        if(a >= 0 && a <= 120){
            age = a;
        }else{
            System.out.println("您的年龄不合理");
        }
    }
 
    // 获取值 
    public int getAge(){
        return age;
    }
 
    public void show(){
        System.out.println(name + "..." + age);
    }
}

测试:

Student stu = new Student();
stu.name = "张三";
stu.setAge(-23);   // 输出:您的年龄不合理 
stu.show();        // 张三...0 

这样,数据的合法性得到了保证,提高了程序的安全性。

this 关键字

1 ) 为什么需要 this

当成员变量和局部变量重名时,Java 遵循就近原则,优先使用局部变量。例如:

public void setName(String name){
    name = name;   // 左右两边都是局部变量自己给自己赋值,成员变量没有变化 
}

为解决重名问题,使用 this 关键字明确指定成员变量。

2 ) this 的作用

this 代表当前对象的引用(地址值)。
可以调用本类的成员变量和成员方法:this.成员变量、this.成员方法()。

3 ) 代码示例与验证

package com.wb.mthis;
 
public class Student {
    private String name;
 
    public void setName(String name){
        System.out.println(this);   // 打印当前对象的地址 
        this.name = name;
    }
}
 
public class TestStudent {
    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println(s1);
        s1.setName("张三");
        // s1 地址与 setName 中 this 地址一致 
 
        Student s2 = new Student();
        System.out.println(s2);
        s2.setName("李四");
        // s2 地址与 setName 中 this 地址一致 
    }
}

结论:哪个对象调用方法,方法中的 this 就代表哪个对象。

4 ) this 的内存原理

调用方法时,方法入栈,并隐式传递当前对象的地址给 this。因此方法内通过 this. 访问的就是调用该方法的那个对象的成员。

封装

1 ) 封装思想

封装是面向对象三大特征之一(封装、继承、多态),核心思想:隐藏实现细节,仅对外暴露公共的访问方式。

例如:插线板用外壳隐藏内部电路,只露出插孔。

2 ) 代码中的封装体现

private + get/set:将成员变量私有化,只提供公共方法访问,内部校验逻辑对外不可见。
方法抽取:将重复代码提取为方法,调用者只需知道方法名,不关心实现细节。
类封装数据:将零散的变量组成为一个类,通过对象来操作。

3 ) 封装的好处
提高安全性:避免非法数据直接进入。
提高复用性:方法可多处调用。

构造方法的格式和执行时机

1 ) 什么是构造方法

构造方法是在创建对象时自动调用的方法,负责对象的初始化。

2 ) 格式

  1. 方法名必须与类名完全相同(包括大小写)。
  2. 没有返回值类型,连 void 都不写。
  3. 不能使用 return 带回具体返回值。

示例:

public class Student {
    private String name;
    private int age;
 
    // 构造方法 
    public Student(){
        System.out.println("我是Student类的构造方法");
    }
}

3 ) 执行时机

每次使用 new 创建对象时,构造方法自动执行一次,且不能手动调用。创建几次对象就执行几次。

构造方法的作用

构造方法的核心作用是创建对象。利用执行时机,可以在构造方法中为对象的成员变量赋初始值(即对象初始化)

带参构造方法

public class Student {
    private String name;
    private int age;
 
    public Student(String name, int age){
        this.name = name;
        this.age = age;
        System.out.println("我是Student类的构造方法");
    }
 
    public void show(){
        System.out.println(name + "..." + age);
    }
}

使用时直接在 new 的同时传入参数:

Student stu = new Student("张三", 23);
stu.show();  // 张三...23 

这样可以在创建对象的同时完成属性赋值,非常便捷。

构造方法的注意事项

  1. 默认构造方法:如果一个类没有定义任何构造方法,系统会自动提供一个无参构造方法。
  2. 自定义覆盖:一旦手动定义了构造方法(无论带参还是无参),系统就不再提供默认构造方法。
  3. 建议:开发中,无论是否需要,都手动写出无参构造和带参构造,避免因缺少构造方法而报错。
  4. 重载:多个构造方法参数列表不同,构成重载关系。
public Student() {}                            // 无参构造 
public Student(String name, int age) { ... }   // 带参构造 

标准 JavaBean 类的编写与使用

1 ) 标准类(JavaBean)规范

所有成员变量使用 private 修饰
提供无参构造方法和带参构造方法
为每个成员变量提供 setXxx 和 getXxx 方法
提供显示对象信息的方法(如 show)

package com.wb.test3;
 
public class Student {
    private String name;
    private int age;
 
    public Student() {}
 
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
 
    public void show(){
        System.out.println(name + "..." + age);
    }
}

2 ) 测试使用

public class TestStudent {
    public static void main(String[] args) {
        // 方式一:无参构造 + set方法赋值 
        Student stu1 = new Student();
        stu1.setName("张三");
        stu1.setAge(23);
        stu1.show();
 
        // 方式二:带参构造直接赋值 
        Student stu2 = new Student("李四", 24);
        stu2.show();
    }
}

输出:

张三...23 
李四...24 

3 ) IDEA 快捷生成

在类中右击 → Generate → Constructor 可自动生成无参/带参构造,选择 Getter and Setter 可自动生成 get/set 方法。开发中可极大提升效率。

总结

本篇文章从零开始,讲解了 Java 面向对象编程的核心基础:类与对象、封装、构造方法、this 关键字以及内存原理。掌握这些内容,是进一步学习继承、多态等高级特性的前提。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值