Java面向对象思想以及原理以及内存图解

news/2025/6/19 18:24:33

文章目录

  • 什么是面向对象
    • 面向对象和面向过程区别
    • 创建一个对象用什么运算符?
    • 面向对象实现伪代码
    • 面向对象三大特征
    • 类和对象的关系。
  • 基础案例
    • 代码实现
    • 实例化
    • 创建car对象时car引用的内存图
    • 对象调用方法过程
  • 成员变量和局部变量
    • 作用范围
    • 在内存中的位置
  • 关于对象的引用关系
    • 简介
    • 相关代码
    • 内存图解
    • 对象相等和引用相等的区别
    • 类的构造方法的作用是什么
    • 构造方法的特点
    • 深拷贝和浅拷贝区别
      • 浅拷贝
      • 深拷贝
  • 匿名对象
    • 实例代码
    • 匿名对象与实例对象的区别
      • 实例代码
      • 图解匿名与非匿名内存运行
    • 使用场景
  • 封装
    • 什么是封装
    • 什么时private修饰
    • 代码示例
  • 构造函数
    • 什么是构造函数
    • 构造函数的小细节
    • 构造代码块
      • 构造代码块示例以及与构造方法的区别
  • this关键字
    • 什么是this关键字
    • this的应用
      • 解决构造函数初始化的问题
      • 用于构造函数之间进行互相调用
  • static关键字
    • 什么是static关键字
    • static特点
    • 实例变量和类变量的区别
    • 静态使用注意事项:
    • 静态有利有弊
      • 利处
      • 弊处
    • 错误代码示范
    • 图解对象如何调用static变量
  • main函数
    • 主函数
    • 主函数的定义格式以及关键字含义
    • 主函数是固定格式的
    • 如何使用args
  • 静态代码块
    • 格式
  • 设计优化
    • 单例模式
      • 简介
      • 饿汉式
      • 懒汉式(线程不安全)
      • 懒汉式(线程安全)
      • 内部类模式
      • 双重锁校验(线程安全)
      • 枚举单例模式(线程安全)
  • 相关面试题
  • 参考文献

什么是面向对象

面向对象和面向过程区别

面向过程:面向过程是将解决问题的思路转为一个个方法。
面向对象:面向对象则是编写一个对象,将这些思路封装成一个个对象方法,后续调用这个对象解决问题,相对面向过程而言,这种思路更符合人的思维并且更易扩展、复用、维护。

面向对象和面向过程性能差距:人们常常认为面向过程性能高于面向对象,因为创建的对象开销远远大于面向过程,实际上Java面向对象性能差的原因并不是这个,真正的原因是Java为半编译语言,运行并不是直接拿着二进制机械码执行,而是需要结果字节码转换这一步。
而且面向过程的性能并不一定比面向过程快,面向过程也需要计算偏移量以及某些脚本语言的性能也一定比Java好。

创建一个对象用什么运算符?

用new运算符,创建的对象的实例会在堆内存中开辟一个空间。而引用则在栈内存中,指向对象实例。

面向对象实现伪代码

以人开门为例,人需要开门,所以我们需要创建一个门对象,描述门的特征,这个门可以开或者关。所以门的伪代码如下:

门{开(){操作门轴}
}

上文说到了,面向对象的特点就是符合人的思维,而人开门这个功能,我们就可以创建一个人的对象,编写一个开门的动作,把门打开。通过这种对象调用对象的方式完成了功能。后续我们需要狗开门,猫开门也只是编写一个方法调用门对象的开的动作。

{开门(门对象){.()}}

面向对象三大特征

  1. 封装
  2. 继承
  3. 多态

类和对象的关系。

以生活事务为例,现实生活中的对象:张三 李四。他们都有姓名、性别、学习Java的能力。

所以我们要想通过面向对象思想实现抽象出对象,就得提取共性,编写一个类有姓名、性别、学习Java的能力。

public class Student {private String name;private int sex;public void studyJava(){System.out.println(this.name+"学习java");}
}

描述时,这些对象的共性有:姓名,年龄,性别,学习java功能。再将这些分析映射到java中,就是以class定义的类进行展开。

public static void main(String[] args) {Student zhangsan=new Student();zhangsan.setName("张三");zhangsan.studyJava();Student lisi=new Student();lisi.setName("李四");lisi.studyJava();//        输出结果
//        张三学习java
//                李四学习java}

而具体对象就是对应java在堆内存中用new建立实体。

基础案例

需求:描述汽车(颜色,轮胎数)。描述事物其实就是在描述事物的属性和行为。

属性对应在类中即变量行为对应的类中的函数(方法)

代码实现

public class Car {//描述颜色String color = "红色";//描述轮胎数int num = 4;//运行行为。public void run() {System.out.println("颜色:"+color + " 轮胎数:" + num);}
}

实例化

public class Main {public static void main(String[] args) {Car car = new Car();car.run();}
}

创建car对象时car引用的内存图

在这里插入图片描述

对象调用方法过程

首先我们看一段代码,这是一个人类的class类代码

public class Person {private String name;private int age;private static String country = "cn";public Person(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 static void showCountry() {System.out.println("showCountry " + country);}public void speak() {System.out.println(this.getName() + " speak");}
}

假如我们在main中编写这样一段代码,请问在内存中他是如何工作的呢?

 public static void main(String[] args) {Person p = new Person("张三", 18);p.setName("李四");}

我们先从类类加载时开始分析,由于static关键字修改的变量或者方法会随着jvm加载类时一起创建,所以countryshowCountry()在方法区是这样的。

在这里插入图片描述

然后main方法开始执行对应代码,首先main方法入栈,初始化一个p引用

在这里插入图片描述

堆区开辟一个空间,创建一个person实例,p引用指向这个内存空间

在这里插入图片描述

调用setName,setName入栈,完成name值修改之后销毁

在这里插入图片描述

成员变量和局部变量

作用范围

成员变量作用于整个类中。
局部变量变量作用于函数中,或者语句中。

在内存中的位置

成员变量:在堆内存中,因为对象的存在,才在内存中存在。
局部变量:存在栈内存中。

关于对象的引用关系

简介

对象引用用于指向0个或者多个对象实例,对象实例可以被多个对象引用指向。

相关代码

假如我们使用上文car类执行以下代码,那么在内存中会如何执行呢?

car c=new car();
c.num=5;
car c1=c;
c.run();

内存图解

  1. 首先堆区开辟一个空间创建car对象,初始化值
  2. 修改num为5
  3. c1引用指向c,如下图所示
    在这里插入图片描述

对象相等和引用相等的区别

  1. 对象相等:两个对象内存中的存放的内容都相等
  2. 引用相等:两个引用指向的内存地址相等。

类的构造方法的作用是什么

完成对象初始化,首先在堆区创建对象实例。

构造方法的特点

  1. 与类名相同
  2. 无返回值
  3. 生成对象时自动执行
  4. 不可重写可以重载

深拷贝和浅拷贝区别

浅拷贝

对象进行拷贝时,如果内部有引用类型,克隆对象仅仅是复制被克隆内部对象的引用地址

为了介绍浅拷贝我们贴出这样一段代码,可以看到一个学生类有id和name,以及一个Vector的引用对象

public class Student implements Cloneable {private String id;private String name;private Vector<String> vector;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Vector<String> getVector() {return vector;}public void setVector(Vector<String> vector) {this.vector = vector;}public Student() {try {System.out.println("创建对象需要三秒......");Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}public Student newInstance() {try {return (Student) this.clone();

https://dhexx.cn/news/show-5537715.html

相关文章

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…

深入理解 React 样式方案

React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…

docker容器互联

1.docker可以通过网路访问 2.docker允许映射容器内应用的服务端口到本地宿主主机 3.互联机制实现多个容器间通过容器名来快速访问 一 、端口映射实现容器访问 1.从外部访问容器应用 我们先把之前的删掉吧&#xff08;如果不删的话&#xff0c;容器就提不起来&#xff0c;因…

【java】【服务器】线程上下文丢失 是指什么

目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失&#xff1f; 直观示例说明 为什么上下文如此重要&#xff1f; 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程&#xff0c;代码应该如何实现 推荐方案&#xff1a;使用 ManagedE…

Java多线程实现之Runnable接口深度解析

Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…

C++_AVL树

本篇文章是对C学习的AVL树部分的学习分享 希望也能够为你带来些许帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、AVL树的概念 AVL 树作为计算机科学领域中重要的数据结构&#xff0c;是最早出现的自平衡二叉查找树。其核心特性在于&#xff0c;它要么为空树…

基于 Three.js 的数字雨波纹效果技术解析

文章目录 一、基础环境搭建与 Three.js 引入​二、场景与相机设置​三、后期处理:光晕效果的实现​四、纹理创建:定制雨滴、波纹和水花外观​五、粒子系统:模拟雨滴下落与交互​1,雨滴粒子系统​2,波纹与水花系统​六、动画循环与交互响应​本文将深入剖析一段实现该效果的…

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包

DataFrame中.iloc 属性

.iloc 是 Pandas 库中 DataFrame 和 Series 对象的一个属性&#xff0c;用于基于整数位置的索引来选择数据。与基于标签的 .loc 索引不同&#xff0c;.iloc 使用从 0 开始的整数位置来访问行和列。这对于处理需要按位置而不是按标签选择数据的场景非常有用。 目录 基本用法 代…

使用homeassistant 插件将tasmota 接入到米家

我写一个一个 将本地tasmoat的的设备同通过ha集成到小爱同学的功能&#xff0c;利用了巴法接入小爱的功能&#xff0c;将本地mqtt转发给巴法以实现小爱控制的功能&#xff0c;前提条件。1需要tasmota 设备&#xff0c; 2.在本地搭建了mqtt服务可&#xff0c; 3.搭建了ha 4.在h…