【类与对象】你真的知道Java中的类和对象吗?

前言

本篇文章主要是深入讲一讲类和对象,包括他们的关系,内存分配,如何使用等等。其实如果对类和对象有过了解的读者应该会看起来更加舒服,我接下来讲的只要理解就好了,不一定说要特意去背啊这种,你可以收藏起来,有事没事多看看,看他个十几次,你对类和对象的理解应该会越来越透彻。

1.面向对象简述

面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向对象的设计思路,才形成C++,而由C++产生了Java这门面向对象的编程语言。

但是在面向对象设计之前,广泛采用的是面向过程,面向过程只是针对于自己来解决问题。面向过程的操作是以程序的基本功能实现为主,实现之后就完成了,也不考虑修改的可能性,面向对象,更多的是要进行子模块化的设计,每一个模块都需要单独存在,并且可以被重复利用,所以,面向对象的开发更像是一个具备标准的开发模式。

在面向对象定义之中,也规定了一些基本的特征:
(1)封装:保护内部的操作不被破坏;
(2)继承:在原本的基础之上继续进行扩充;
(3)多态:在一个指定的范围之内进行概念的转换。

对于面向对象的开发来讲也分为三个过程:OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)。

2.类与对象的关系

类是对象的抽象,而对象是类的具体实例。类与对象的关系:抽象(该抽象是名词)与类的实例化就是对象,对象的共性特征抽象(该抽象是动词)出来就是类。

比如你要买一台PC,你在订单上列出了这台PC的CPU和显卡型号、显示屏的大小、键盘是104还是87位、主机的颜色等等,这所有信息组成在一起就是一个电脑的类,但你只有它的参数并没有一个符合这个要求的实物对象,而当服务员拿出了一台符合这个订单的具体PC时,这个PC就是那个类的具体对象。

我曾经看过一篇文章,那篇文章是描述作者找工作遇到的印象较深的基础面试问题,我觉得这个问题很有意思,问题大概是这样的:
         面试官:男人和女人是同一个类吗?
         我:是同一类。
         面试官:钢笔和铅笔是同一个类吗?
         我:是同一类。
         面试官:男人和钢笔是同一个类吗?
         我犹豫了3秒钟,
         我:不是同一类
         面试官:看来你对基础概念理解的还不到位啊。

  这里,首先你要懂得万物皆对象,对象都是类的实例,而类是对象的抽象。那么我在JAVA中就可以定义男人和钢笔都是A类,而这个类可以是描述都是看的见或摸的着的特征,亦或是什么都不描述的但就是用来实例化男人和钢笔的类(类可以是你随性定义的),即男人和钢笔是同一类。同理,时间和水是一类吗?思维和手是一类吗?都是的。
  其实面试官在这也埋了一个坑----没有交代问题的前提条件。我认为完美的答案应该是:
  “从生活角度讲,男人和女人是同一类,钢笔和铅笔是同一类,但男人和钢笔不是同一类。
   从Java中类与对象的关系来说,男人和女人是同一类,钢笔和铅笔是同一类,男人和钢笔也是同一类。”

面试官还问过他一个对象问题:
         面试官:若我是一个完全不懂IT和编程的人,你能给我解释一下什么是对象吗?
         我:在JAVA中,对象就是一类数据的实例化,他们有着一种或几种的相同特征。
         面试官:你认为一个普通人听得懂这个吗?你只需要说万物皆对象就好,再举几个生活中的例子,没必要去背概念。

3.类与对象的定义和使用

范例:定义一个Person类:

class Person {     // 类名称首字母大写
    String name ;
    int age ;
    public void tell() {        // 没有static
          System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}

类定义完成之后,肯定无法直接使用。如果要使用,必须依靠对象,那么由于类属于引用数据类型,所以对象的产生格式如下(类的实例化):

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

范例:使用对象操作类:

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = new Person() ;// 声明并实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}

运行结果:

姓名:张三,年龄:30

以上完成了一个类和对象的操作关系,下面换另外一个操作来观察一下:


class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = null;//声明对象
            per = new Person() ;//实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}

运行结果:

姓名:张三,年龄:30

那么,问题来了,以上两种不同的实例化方式有什么区别呢?
我们从内存的角度分析。首先,给出两种内存空间的概念:
(1)堆内存:保存对象的属性内容。堆内存需要用new关键字来分配空间;
(2)栈内存:保存的是堆内存的地址(在这里为了分析方便,可以简单理解为栈内存保存的是对象的名字)。

任何情况下,只要看见关键字new,都表示要分配新的堆内存空间,一旦堆内存空间分配了,里面就会有类中定义的属性,并且属性内容都是其对应数据类型的默认值。

于是,上面两种对象实例化对象方式内存表示如下:

两种方式的区别在于①②,第一种声明并实例化的方式实际就是①②组合在一起,而第二种先声明然后实例化是把①和②分步骤来。

另外,如果使用了没有实例化的对象,结果如何?

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = null;//声明对象
            //per = new Person() ;//实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}

运行结果:

Exception in thread "main" java.lang.NullPointerException
    at com.wz.classandobj.TestDemo.main(TestDemo.java:15)

此时,程序只声明了Person对象,但并没有实例化Person对象(只有了栈内存,并没有对应的堆内存空间),则程序在编译的时候不会出现任何的错误,但是在执行的时候出现了上面的错误信息。这个错误信息表示的是“NullPointerException(空指向异常)”。

4.对象引用传递初步分析

引用传递的精髓:同一块堆内存空间,可以同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。

下面通过若干个程序,以及程序的内存分配图,来进行代码的讲解。

我们来看一个范例:

class Person {     
         String name ;
         int age ;
         public void tell() {        
                   System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}
public class TestDemo {
         public static void main(String args[]) {
                   Person per1 = new Person() ;         // 声明并实例化对象
                   per1.name = "张三" ;
                   per1.age = 20 ;
                   Person per2 = per1 ;  // 引用传递
                   per2.name = "李四" ;
                   per1.tell() ;
         }
}

对应的内存分配图如下:

再来看另外一个:

class Person {
         String name ;
         int age ;
         public void tell() {
                   System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}
public class TestDemo {
         public static void main(String args[]) {
                   Person per1 = new Person() ;         // 声明并实例化对象
                   Person per2 = new Person() ;
                   per1.name = "张三" ;
                   per1.age = 20 ;
                   per2.name = "李四" ;
                   per2.age = 30 ;
                   per2 = per1 ;// 引用传递
                   per2.name = "王五" ;
                   per1.tell() ;
         }
}

垃圾:指的是在程序开发之中没有任何对象所指向的一块堆内存空间,这块空间就成为垃圾,所有的垃圾将等待GC(垃圾收集器)不定期的进行回收与空间的释放。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/347479.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

P4769 [NOI2018] 冒泡排序 洛谷黑题题解附源码

[NOI2018] 冒泡排序 题目背景 请注意,题目中存在 n 0 n0 n0 的数据。 题目描述 最近,小 S 对冒泡排序产生了浓厚的兴趣。为了问题简单,小 S 只研究对 1 1 1 到 n n n 的排列的冒泡排序。 下面是对冒泡排序的算法描述。 输入&#x…

JS高频面试题(上)

1. 介绍JS有哪些内置对象? 数据封装类对象:Object、Array、Boolean、Number、String 其他对象:Function、Arguments、Math、Date、RegExp、Error ES6新增对象:Symbol(标识唯一性的ID)、Map、Set、Promise…

【Java程序员面试专栏 专业技能篇】MySQL核心面试指引(二):核心机制策略

关于MySQL部分的核心知识进行一网打尽,包括三部分:基础知识考察、核心机制策略、性能优化策略,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 本篇Blog为第二部分:核心机制策略,子节点表示追问或同级提问 日志机制 关于MySQL的几…

图像处理python基础

array 读取图片 tensor 模型预测 一般过程:读取数据np->tensor->model->result->np->画图 shape确保图像输入输出尺寸正确 读取图片 将在GPU上运行的tensor类型转变成在CPU上运行的np类型 三类计算机视觉任务的输入: 分类&#xff1…

加速应用开发:低代码云SaaS和源码交付模式如何选

随着数字化转型的加速,企业对于快速开发和交付高质量应用的需求也越来越迫切。为了满足这一需求,开发者们开始探索采用低代码平台进行软件开发工作,以加速应用开发过程。 目前,市场上的低代码产品众多,但基本可分为简单…

imgaug库图像增强指南(38):从入门到精通——图像卷积的全面解析

引言 在深度学习和计算机视觉的世界里,数据是模型训练的基石,其质量与数量直接影响着模型的性能。然而,获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此,数据增强技术应运而生,成为了解决这一问题的…

Redis——关于它为什么快?使用场景?以及使用方式?为何引入多线程?

目录 1.既然redis那么快,为什么不用它做主数据库,只用它做缓存? 2.Redis 一般在什么场合下使用? 3.redis为什么这么快? 4.Redis为什么要引入了多线程? 1.既然redis那么快,为什么不用它做主数据…

磺化-Cy5-左旋聚乳酸,Sulfo-Cyanine5-PLLA,一种生物相容性良好的生物降解材料

您好,欢迎来到新研之家 文章关键词:磺化-Cy5-左旋聚乳酸,Sulfo-Cyanine5-PLLA,Sulfo-Cyanine5-Poly(L-lactic acid) 一、基本信息 产品简介:Sulfo Cy5 PLLA, also known as sulfonated Cyanine5 L-polylactic acid,…

Go实现LRU算法

LRU是什么? LRU是内存淘汰策略,LRU (Least recently used:最近最少使用)算法在缓存写满的时候,会根据所有数据的访问记录,淘汰掉未来被访问几率最低的数据。也就是说该算法认为,最近…

开源运维平台Spug本地docker部署结合内网穿透实现远程访问

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台,整合了主机管理、主机批量执行、主机在线终端、文件…

Qt Quick程序的发布|Qt5中QML和Qt Quick 的更改

# Quick程序的发布旧版做法 # Qt5中QML和Qt Quick 的更改 1.QML语言的更改(Qt4->Qt5) 在QML语言中,只有少量更改会影响QML代码的迁移:无法直接导入单独的文件(例如:import"MyType.qml”),需要导人该文件所在的目录; JavaScript文件中的相对路径被解析…

性能优化-OpenCL 介绍

「发表于知乎专栏《移动端算法优化》」 本文首先对 GPU 进行了概述,然后着重地对移动端的 GPU 进行了分析,随后我们又详细地介绍了 OpenCL 的背景知识和 OpenCL 的四大编程模型。希望能帮助大家更好地进行移动端高性能代码的开发。 🎬个人简介…

Chatgpt的崛起之路

Chatgpt的崛起之路 背景与发展历程背景发展历程 技术原理第一阶段:训练监督策略模型第二阶段:训练奖励模型第三阶段:采用强化学习来增强模型的能力。 国内使用情况及应用的领域面临的数据安全挑战与建议ChatGPT获取数据产生的问题数据泄露问题…

2023年AI大模型:从科技热潮到商业变革

出品:新商纪,作者:独孤依风 2023年,大模型技术在全球科技界掀起了一场风暴,引发了科技巨头们的激烈角逐。这一年,大模型不仅重新定义了人工智能的边界,还催生了跨行业技术革新。 根据IDC的预测…

如何在Kali系统配置启动SSH并结合内网穿透实现远程连接

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过[cpolar 内网穿透](cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站)软件实现ssh 远程连接kali! …

JavaEE之多线程编程:5. 死锁(详解!!!)

文章目录 一、死锁是什么二、关于死锁的三种形式三、如何避免死锁 一、死锁是什么 死锁是这样的一种情形:多个同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 【举个例子理解死…

24.1.25Linux shell之cal、ncal、printf

cal 命令用于在终端上显示当前月份的日历。默认情况下,它会展示当前月份的完整日历,包括星期和日期。常用的就是下面两个参数: ncal 这个比上面得的功能多,一个是会把今天的日子标注出来,一个是排版不一样&#xff1…

redis-持久化主从复制

一.主从复制 1.是什么 主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 2.能干嘛 读写分离,性能扩展(主 写 从 读) 容灾快速恢复 3 主从复制 一主二…

使用redisson控制多个springboot实例负载同时只有一个实例执行任务

一 redisson依赖 <!-- redisson 依赖--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.4</version></dependency> 二 定时任务代码 pack…

【复现】奥威亚视屏云平台文件读取漏洞_27

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 奥威亚视屏云平台拥有丰富的应用模块&#xff0c;包括结对帮扶、网络教研、教研共同体、优课汇聚、教学资源、在线巡课、AI课堂分…