首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java基础之面向对象以及内存分析

Java基础之面向对象以及内存分析

原创
作者头像
曾高飞
发布2025-06-16 13:45:40
发布2025-06-16 13:45:40
12200
代码可运行
举报
运行总次数:0
代码可运行

面向对象思想介绍

  1. 面向对象:编程使用的一种编程思想,编程思路
  2. 面向对象和面向过程的比较: 都是编程思想,面向过程是面向对象的基础,面向对象是基于面向过程的。

面向过程:解决问题时,强调的是解决问题的步骤,强调的是解决问题的方式, 更强调的是方法,编程思想是: 自顶向下, 不断的分解过程;

面向对象:更强调是解决问题的主体,强调的是谁来解决这个问题,更强调的是数据,更强调的是对象,更强调谁拥有这个数据,谁拥有操作数据的能力, 编程思想是: 自底向上, 不断拼装;

举例说明: 洗衣服问题

面向过程: 准备盆子, 放进洗衣液, 放水, 放脏衣服, 浸泡一会, 搓一搓揉一揉, 涮一涮, 拧一拧, 晾出去;

面向对象: 找个女朋友, 发出指令”洗衣服”

面向对象的好处

1、更符合人类生活习惯:凡事习惯找对象,找工具,找别的人, 而不是自己找方法去解决

2、复杂问题简单化

3、从此从执行者变成了指挥者

4.面向对象的特征:

1.封装

2.继承

3.多态

5. 面向对象是相对于面向过程更高层次的设计思想,面向过程是面向对象基础.面向对象是基于面向过程的.

类和对象

类和对象的比较

  1. 类: 类型, 对一类就有相同事物和行为的抽象, 是一个概念性的东西,看不见摸不着
  2. 对象:对象就是类的一个具体呈现,是实实在在存在事物,能够看得见摸得着; “万事万物皆对象”

类的说明

  1. 类: 具有相同事物和行为的抽象
  2. 举例说明:

1⃣️学生:

属性: 姓名, 年龄 , 性别

行为: 吃饭, 睡觉, 上学, 考试, 打游戏

2⃣️车:

属性: 颜色, 轮子, 玻璃, 门 , 座椅, 发动机

行为: 点火, 挂挡, 跑, 刹车, 车震

3⃣️Java程序员

属性: 姓名 年龄 性别

行为: 上班, 下班, 写代码, 使用eclipse, 使用MySql, 会安装JDK

4⃣️ 讲师:

属性:姓名 , 年龄 , 性别

行为: 上课, 讲作业, 会java, 会安装JDK, 使用eclipse, 会讲段子

对象的说明

  1. 对象: 就是一个类的具体实现(呈现)
  2. 能够看得见摸得着

3 . 例子: 汽车是类: 马自达 讲师是类: 老师 Java程序员类: 范宝

Java中如何定义类和对象

  1. java中类的定义:

格式:

[修饰符] class 类名 {

属性:其实就是之前学的变量, 成员变量, 对象的属性;

属性的格式:

数据类型1 变量名1;

数据类型2 变量名2;

行为: 行为就是之前学过的方法, 对象行为, 对象方法

去掉static关键字

public 返回值数据类型 方法名(参数列表){

方法体;

return 数据;

}

  1. java中对象的定义: 使用对象必须依赖于类, 没有类就没有对象

对象创建的格式:

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

创建对象的格式说明:

类名: 要创建对象的数据类型 例如: Scanner , Person

对象名: 只要是一个合法的标识符就可以, 小驼峰命名法, 见名知意, 对象名就是一个引用类型变量;

=: 将对象在堆区申请内存空间首地址赋值给对象名存储

new: 在堆区申请一块内存空间,并把申请空间首地址赋值给 对象名

类名: 和前面的类名一致

();表示调用的是一个方法, 这个方法就是构造方法(构造方法用来创建对象的方法)

  1. 对象的使用:

调用属性:

对象名.属性名; (访问属性中的值);

对象名.属性名 = 值;(赋值操作)

调用方法:

对象名.方法名();

创建对象的内存分析

创建一个对象时内存分析

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 创建一个对象的内存分析 {
	public static void main(String[] args) {
		// 创建女孩对象
		Girl g = new Girl();
		System.out.println(g.name);
		System.out.println(g.age);
		g.name = "翠花";
		g.age = 18;
		g.sayHi();
	}
}

class Girl{
   String name;// 引用类型属性,没赋值之前默认值是null
   int age; // 基本数据类型,默认值是0
   public void sayHi(){
	 System.out.println("我的名字是:"+name+", 年龄:"+age);
   }
}

两个对象的内存分析

总结对象内存分析:

  1. 创建对象步骤:
  2. 将要创建对象的所属的.class文件(字节码文件)加载到方法区, 形成一个.class字节码对象的区域
  3. 在栈内存中创建一个Girl对象的引用,将来用来存储堆区申请对象的地址
  4. 在堆内存中开辟空间, 给各个属性也配一块空间, 并赋初始值, 引用类型初始值null, 基本数据是0, boolean类型: 赋值 false
  5. 将堆区申请的地址,赋值给栈区对象的引用
  6. 内存图示的说明
  7. 第一使用某个类型的时候,会把该类型的字节码文件加载到方法区,第二次的时候就不再加载
  8. 在堆区创建的对象, 内部空间中会持有一份该类字节码文件在方法区的地址
  9. 每个对象在调用自己的对象方法时,该方法中都会有一个地址指向这个对象在堆区的地址
  10. 每使用一次new, 就会创建出一个新的对象, 都会在堆区申请新的空间.

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 创建两个对象的内存分析 {
	public static void main(String[] args) {
		Girl g = new Girl();
		g.name = "翠花";
		g.age = 18;
		g.sayHi();
		Girl g2 = new Girl();
		g2.name = "如花";
		g2.age = 20;
		g2.sayHi();
	}
}
// 女孩类
// 属性: name, age
// 行为: sayHi  
class Girl{
   String name;// 引用类型属性,没赋值之前默认值是null
   int age; // 基本数据类型,默认值是0
   public void sayHi(){
	 System.out.println("我的名字是:"+name+", 年龄:"+age);
   }
}

两个引用指向同一对象的内存图解

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 两个引用指向同一对象的内存图解 {
	public static void main(String[] args) {
		Girl g = new Girl();
		g.name = "妲己";
		g.age = 18;
		// System.out.println(g.isBeautiful); false 
		g.sayHi();
		Girl g2 = g;
		g2.name = "貂蝉"; 
		g.sayHi();
	}
}
class Girl{
   String name;
   int age; 
   boolean isBeautiful;
   public void sayHi(){
	 System.out.println("我的名字是:"+name+", 年龄:"+age);
   }
}

面向对象其他的内容

成员变量和局部变量区别

  1. 成员变量:定义类的大括号的变量就是成员变量, 局部变量:定义在方法中变量就是局部变量
  2. 相同点:都可以用来存储数据
  3. 不同点:

代码层面: 定义位置不同

局部变量: 定义在方法中

成员变量: 定义在类中

内存层面: 空间位置不同

局部变量: 属于方法,方法运行时会入栈,所以局部变量就在栈区

成员变量: 属于对象,对象的位置在堆区, 所以成员变量在堆区

初始化的状态也不同:

局部变量: 没有默认初始化的值, 不初始化不能使用;

成员变量: 有初始化的值, 系统会自动申请空间并初始化

引用类型初始化值: null

基本数据类型: 整型: 0

布尔: false

小数: 0.0

字符 ‘\u0000’ ‘’

生命周期不同: 就是在内存中存储时间

局部变量:随着方法的调用被创建出来, 方法调用结束就消失

成员变量:随着对象的创建而存在,随着对象的消失而消失. 即使栈内存的对象名被销毁了,对象也不一定立即被销毁.这个对象只能通过垃圾回收机制,才能被销毁;

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 成员变量和局部变量区别 {
	public static void main(String[] args) {
		Demo d1 = new Demo();
		System.out.println(d1.str); // null
		System.out.println(d1.i); // 0
		System.out.println(d1.d); // 0.0
		System.out.println(d1.c);// ''
		System.out.println(d1.b); // false
		// System.out.println(a);
		d1.test();
		System.out.println("哈哈哈");
	}
}
代码语言:javascript
代码运行次数:0
运行
复制
class Demo{
	// 这些变量,直接定义在类后大括号中(类体),叫做成员变量
	String str;
	int i;
	double d;
	boolean b;
	char c;
	public void test(){
		// 在方法后大括号中定义的变量就是局部变量
		int a = 10; 
		int b = 20;
		int f;
		System.out.println(f);
		System.out.println(a +"--"+b);
	}
}

方法的形式参数是引用数据类型

  1. 方法的形式参数,既可以是基本数据类型,也可以是引用数据类型
  2. 引用数据类型: 数组, 类, 枚举, 接口
  3. 当方法的形式参数是引用数据类型是, 其实在调用方法的时候,需要传递一个对象当做方法的实参, 对象中存储是这个对象在堆区的地址, 所以在方法的内部就可以操作这个对象堆区的内容, 可以操作内容有: 属性和方法

图示

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 方法的参数是引用数据类型 {
	public static void main(String[] args) {
		 NoteBook book1 = new NoteBook();
		 book1.brand = "联想2000";
		 book1.price = 3000.0;
		 useNoteBook(book1);
	}
	public static void useNoteBook(NoteBook  nb){
		System.out.println(nb.brand);
		System.out.println(nb.price);
		nb.show();
	}
}

// 笔记本类

代码语言:javascript
代码运行次数:0
运行
复制
class NoteBook{
	String brand;
	double price;
	public void show(){
		System.out.println("品牌是:"+brand+", 价格是:"+ price);
	}
}

方法的返回值是引用类型

  1. 方法的返回值是引用类型, 之前方法返回值都是void或者是基本数据类型, 现在要返回一个对象
  2. 方法的返回值是引用类型, 必须要在return关键字之后,返回一个该引用类型对象

案例: 定义手机类

属性; 品牌, 价格

行为: 打电话, 玩游戏

在其他地方定义方法,用于生产手机;

图示:

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 方法的返回值是引用类型{
	public static void main(String[] args) {
		 // 调用生产手机的方法
		Mobile mine =  getMobile();
		mine.call();
		mine.play();
		System.out.println(mine.brand);
		System.out.println(mine.price);
	}

// 定义一个生产手机的方法

代码语言:javascript
代码运行次数:0
运行
复制
	public static Mobile getMobile(){
		Mobile m = new Mobile();
		m.brand = "诺基亚";
		m.price = 75.0;
		// 把制造手机返回
		return m;
	}
}

// 手机类

代码语言:javascript
代码运行次数:0
运行
复制
class  Mobile{
	String brand;
	double price;
	public void call(){
		System.out.println("打电话...");
	}
	public void play(){
		System.out.println("玩王者荣耀");
	}
}

匿名对象的理解和使用

  1. 匿名对象: 没有名字对象
  2. 匿名对象定义的格式:

new 类名();

  1. 匿名对象的使用场景:
  2. 如果某个对象创建之后,你就在方法中使用了一次,此时就可以使用匿名对象
  3. 可以作为方法的实际参数,匿名对象可以直接当做实际实际参数去使用,省去了创建变量名的过程.
  4. 可以作为方法的返回值使用, 当方法返回值是引用数据时,可以在return后写 new 类名(); 调用者在获取到这个匿名对象,可以直接使用,也可以自己定义变量名存储

4.匿名对象使用注意事项

匿名对象,如果没有赋值给一个带有名字的变量,这个匿名对象只能使用一次; 这个匿名对象被使用使用之后,其他地方就再也无法被使用, 过一会他就会被垃圾回收机制,回收掉它在堆区申请的内存空间.

代码语言:javascript
代码运行次数:0
运行
复制
实例代码    *
class 匿名对象的理解和使用 {
	public static void main(String[] args) {
		// 场景1
		// 宝宝买了辆车,就想开着它兜风
		// Car c = new Car();
		// c.run();
		new Car().run();
		// new Car().run();
		// 买了车, 就想跑
		new Car().carShark();
		// Car c = new Car();
		// cleanCar(c);
		// 场景2
		cleanCar(new Car());
		// 场景3
		// 获取对象后找一个变量名存储
		Car c  = getCar();
		c.run();
		c.carShark();
		// 获取对象,直接使用
		getCar().carShark();	
	}
	// 造车
	public static Car getCar(){
		// Car c = new Car();
		// return c;
		return new Car();
	}
	// 洗车
	public static void cleanCar(Car c){
		c.carShark();
	}

}
class Car{
	// 跑
	public void run(){
		System.out.println("风驰电掣...");
	}
	// 哈哈
	public void carShark(){
		System.out.println("摇啊摇...");
	}
}

封装

封装的概述

  1. 封装概念: 隐藏事物属性的实现细节, 对外公开一个公共方法方式;
  2. 封装的好处:
  3. 隐藏实现细节
  4. 提高代码的复用性
  5. 提高安全性
  6. 类封装的原则

隐藏事物的属性;

隐藏事物事项细节;

提供一个公共的访问方式;

没有封装时坏处:

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class 没有封装的时候 {
	public static void main(String[] args) {
		Human h = new Human();
		// h.age = 18888;  不合理
		// h.age = -5; 不合理
		// 没有封装时,属性的值存在很多安全隐患
		h.showAge();
	}
}
class Human{
	int age;
	public void showAge(){
		System.out.println("我的年龄是:"+age);
	}
}

private关键字

  1. private单词: 私有的, 私密的
  2. private关键字能修饰的内容:

修饰成员变量; (今天的要讲的)

修饰成员方法;

修饰构造方法;

修饰内部类;

  1. private关键修饰之后效果

被private修饰之后, 只能在类的内部直接访问, 但是出了类之后,再类的外部是不能直接访问的

  1. private关键字的注意事项:

private只是封装的一种体现形式,封装处理private修饰符之外还能使用别的修饰符完成;

实例代码

代码语言:javascript
代码运行次数:0
运行
复制
class private关键字 {
	public static void main(String[] args) {
		Student s = new Student();
		/*  private修饰之后外界不能直接访问
		s.name = "张三";
		s.age = 8;
		s.sex = "未知";
		*/
		/* private修饰的方法外界不可以直接访问
		s.show();
		s.study();
		s.play();
		*/
		s.doHomeWork();


	}
}

// 学生 Student

// 属性: 姓名 年龄 性别

// 行为: 学习, 玩游戏, 做作业

代码语言:javascript
代码运行次数:0
运行
复制
class Student{
	private String name; 
	private int age;
	private String sex;
	// 学习
	private void study(){
		System.out.println("好好学习, 天天向上");
	}
	// 玩
	private void play(){
		System.out.println("玩推箱子...");
	}
	// 做作业
	private void doHomeWork(){
		System.out.println("做家庭作业");
	}
	// 展示属性
	public void show(){
		// private修饰之后,在类的内部仍然能直接访问
		System.out.println("姓名:"+name+"性别:"+sex+"年龄:"+age);
	}
}

Getter和Setter方法

  1. 当属性(成员变量)被私有化之后,外界不能直接访问了,所以需要提供公共的访问方式,让外界可以间接的访问成员变量.
  2. 属性赋值的公共方式:叫做Setter方法, 属性取值的公共方法:叫做Getter方法
  3. 属性的Settter方法的属性格式:

变量访问的就近原则

  1. 变量访问的就近原则:

变量的定义: 数据类型 变量名; 定义就是在声明变量, 声明时一定要带数据类型

变量的使用: 称之为变量的访问, 直接使用变量名,不要带数据类型

就近原则: 当访问某个变量名的时候, 会现在访问这条语句所在的大括号中寻找有没有定义此变量, 如果找到了,就是用;如果没有找到去外面接着找,如果找的到就是用; 找不着编译报错;

当局部变量名和成员变量名重名的时候,访问变量时会优先使用离它最近的这个变量中的数据;

  1. this关键字

表示当前类型对象的引用

那个对象调用this所在的方法,那么this就代表是那个对象;

作用: 可以区分同名的成员变量和局部变量, this.成员变量名代表访问的就是成员表能量,没有this的那个变量代表局部变量;

希望这篇文章能够让大家更清晰的认识到java的面向对象的特点,码字不易,点个赞呗或者点个关注再走。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 面向对象思想介绍
  • 面向对象的好处
  • 4.面向对象的特征:
  • 5. 面向对象是相对于面向过程更高层次的设计思想,面向过程是面向对象基础.面向对象是基于面向过程的.
  • 类和对象
  • 类和对象的比较
  • 类的说明
  • 对象的说明
  • Java中如何定义类和对象
  • 创建对象的内存分析
  • 面向对象其他的内容
  • 方法的形式参数是引用数据类型
  • 方法的返回值是引用类型
  • 匿名对象的理解和使用
  • 封装
  • 封装的概述
  • private关键字
  • 实例代码
  • Getter和Setter方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档