面向对象基础

本文深入解析面向对象编程(OOP)的核心理念,包括封装、继承和多态,类与对象的区分,以及Java对象创建内存剖析。讲解了类的定义、对象的创建与操作,构造方法、重载和匿名对象的应用。适合初学者和进阶者了解OO设计原则。

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

面向对象基础

面向对象思想

面向对象是相对于面向过程而言的,指把相关数据和方法组织为一个整体来看待。

与面向过程相比,面向对象更关注的是具备功能的对象(不那么关注繁琐的细节,更关注统筹架构的问题),而不是执行过程。

三大思想
  1. OOA:面向对象分析(Object Oriented Analysis)

  2. OOD:面向对象设计(Object Oriented Design)

  3. OOP:面向对象程序(Object Oriented Programming)

三大特征
  1. 封装:所有内容对外不可见

  2. 继承:将其他功能继承下来继续发展

  3. 多态:方法的重载本身就是一个多态性的体现

类与对象

  • 类表示共同的属性,是一个综合特征

  • 对象是个性化的,是一个个体的特征

类必须通过对象才能使用,对象的所有操作都定义在类中。

定义格式:

class 类名称{
	成员属性
	成员方法
}

类由属性和方法组成:

  1. 属性:相当于对象的特征,如人的性别、身高、体重

  2. 方法:相当于对象的行为,如说话、吃饭、睡觉

属性定义格式:

数据类型 属性名;

属性定义并赋值:

数据类型 属性名 = 初始值;

方法定义格式:

权限修饰符 返回值类型 方法名(形式参数列表) {
	// 方法体
	return 返回值;
}
对象

对象的创建与使用:

对象定义格式:

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

访问类中的属性和方法:

  1. 属性: 对象.属性名;

  2. 方法: 对象.方法名(实际参数列表);

对象创建时的内存分析
  • Java栈只占2m左右的区域,特点是存取速度特别快(仅次于PC寄存器)。

  • 栈存储的特点——先进先出

存储速度快的原因——栈内存通过“栈指针”来创建和释放空间:

  • 指针向下移动->创建新内存,向上移动->释放内存,如下
public static void main(String[] args) {
    
    int a = 10;
    Test t = new Test();
    
    // 上述代码中 10(基本数据类型的数据) 和 t(引用变量) 将存在栈内存中。
}

对象创建内存分析1

这种方式必须要明确移动的大小和范围——为了方便指针移动,这是一个对数据存储的限制,存储的数据大小是固定的,影响了程序的灵活性。

因此栈中只存放方法体中的 局部变量(若为基本数据类型,则该变量的值也存在栈内存中)引用数据类型的引用变量

而把更大部分的数据存在堆内存中。

  • 存放的是类的对象(普通成员变量——基础数据类型)。

  • 对象都是通过new关键字创建的,new关键字是告诉JVM,需要去创建一个新的对象,去开辟一块新的堆内存空间。

  • 优点在于:创建对象时,不必关注堆内存中需要开辟多少存储空间,也不需要关注内存占用时长。

  • 内存释放由GC(垃圾回收器)完成:当栈内存中不存在此对象的引用时,则视其为垃圾,等待GC回收。如:

Test t0 = new Test();   // 假设创建的Test对象地址为0x123
Test t1 = new Test();   // 假设创建的Test对象地址为0x124
t1 = t0;    // 此时t1和t0都指向内存地址0x123,则地址为0x124的对象在堆内存中被视为垃圾,等待GC回收。
  1. 方法区

    存放:

    • 类信息
    • 静态成员变量
    • 常量
    • 成员方法

    方法区中存在一个常量池,将由final 和 static共同修饰的静态常量存入其中。

  2. PC寄存器

    PC寄存器保存:当前正在执行的JVM指令的地址

    Java程序中,每个线程启动时,都会创建一个PC寄存器。

  3. 本地方法栈

    保存本地(native)方法的地址。

举例理解Java对象创建时的内存细节
public Test{
    public static void main(String[] args) {

        Person p = new Person();
        p.Test();

    }
}

public Person{

    private int a = 1;
    private String b = "strb";
    public static int c = 2;
    public static String d = "strd";

    public void Test() {

        int x = 10;
        String str = "str";
        String str1 = new String("str");
        String str2 = "str";
        Person p1 = new Person();

        System.out.println(str == str1); // false
        System.out.println(str == str2); // true

    }

}

对象创建内存分析2

分析:

当Person对象被创建时,会在堆内存开辟一块新的存储空间,其中

  • 成员变量:

    • 非静态:存储在堆中的对象中(即存储在堆中的对象实际上就是各种非静态成员变量)。

    • 静态:存储在方法区中。

  • 成员方法:

    • 调用时都会在栈内存中开辟空间,静态与非静态的区别在于:

      非静态:在栈内存中存储的是对象的引用this形参对应的临时变量(若有)

      静态:在栈内存中存储的是类名的引用(指向方法区中该类的静态方法区地址)。

  • 方法体中的变量:

    • 基础数据类型的变量:变量都存在栈内存

    • 引用数据类型的变量:引用变量存在栈内存,new出来的对象存在堆内存

  • 特殊的String类型:

    • String类型的对象有两种创建方式:

String str = "str";

String str1 = new String("str");

  • 第一种创建方式,jvm首先会到方法区中的字符串常量池中查找是否存在常量"str",若存在则直接返回该常量的引用,若不存在则创建该常量,并将该常量的引用返回给String str。

  • 第二种创建方式,jvm会直接在堆内存中创建一个字符串对象,并返回该对象的引用给String str1。(不管该字符串在字符串常量池中是否已存在,都会在堆内存中开辟新空间。且如果不存在,也不会将该字符串加入到常量池中。)

构造方法(构造器)

在对象创建的格式中:

Test t = new Test();

在Test后面出现的(),实际上就是在调用该对象的构造方法。

  1. 作用

    用于对象初始化。

  2. 执行时机

    在创建对象时自动调用

  3. 特点

  • 所有的Java类都会至少存在一个构造方法
  • 如果一个类中没有明确编写构造方法,则编译器会自动生成一个无参构造方法,该构造方法中没有任何代码。
  • 如果自行编写了任一构造器,则编译器不会再自动生成无参构造方法。因此自定义构造方法后,最好再重写一个无参构造方法。
  1. 定义格式

    方法名必须与类名相同,且没有返回值声明

    public class Demo{
        public static void main(String[] args) {
            Test t = new Test();
            t = new Test();
            t = new Test();
            t = new Test();
        }
    }
    
    class Test{
        public Test() {
            System.out.println("调用构造方法!");
        }
    }
    
  2. 构造方法设计

  • 建议自定义无参构造方法,不要对编译器形成依赖,避免错误发生。
  • 当类中有非常量成员变量时:建议提供两个构造方法——无参构造方法、全参构造方法。
  • 当类中所有成员变量都是常量没有成员变量时,建议不提供任何版本的构造方法。
方法重载
  • 当方法名称相同,参数的类型、顺序、个数不同时,可以完成方法的重载。!!注意,方法的重载与返回值无关!!

  • 作用:在不同需求下,通过传递不同的参数来完成具体的功能。

构造方法的重载
  • 一个类可以存在多个构造方法,参数列表的长度、类型、顺序不同就可以完成构造方法的重载。

  • 作用:在不同需求下,调用不同的构造方法来完成对象的初始化。

匿名对象
  • 即没有名称的对象。

  • 匿名对象只能使用一次,由于没有任何的对象引用,被视为垃圾,只能等待GC回收。

  • 只使用一次的对象可通过匿名对象的方式完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值