对象与类的关系

本文探讨了在开发过程中对象与类的关系,强调类是对象的模板,对象是类的具体实例。同时,解释了类作为一种复杂数据类型的概念,并讨论了类之间的is-a、as-a和use-a关系。在Java中,继承是一种类与类的关系,通过内存叠加实现,子类继承父类的部分信息,但并非所有内容。此外,文章提到了单继承和Object类的重要性,以及equals和toString方法的默认实现和重写需求。

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

1、先有类?还是先有对象? 在开发过程中,其实是分为两个阶段的,一个是设计阶段,一个是实现阶段。 在设计阶段是我们通过场景,带入用例去分析,在这个时候这些用例都是以对象的方式出现的。然后在通过归纳发现具有相同属性和行为的对象,这个归纳是人脑的一种抽取,我们得到类的概念。 此时,是通过人脑的抽象把具有相同属性和行为的对象归纳为一类。

在实现过程中,代码是先定义类,然后通过类产生对象。这里体现的是编码中的复用思想,把类看成是对象“模版”,先定义好模版,然后通过模版进行复制,产生无数个对象。在具体使用的时候,一定是用对象而不是用类。 类是对象的模版,对象是类的具体的实际的存在。

2、类是一种数据类型 数据类型本身就是一个非常重要的概念,没有它,大部分编程语言是没有办法设计出来。这是因为软件的任务就是操作数据,而硬件提供的工作环境只有0和1组成的二进制。那么在现实场景当中需要用到的各种数据,最终都会化为0和1,那么在运算的时候如何分辨?如何进行不同的运算呢?就靠“数据类型”。

现实中的数据类型实在是太丰富了,且变化太多了。因此没有一门语言可以把所有的数据类型全部预设,只能预设最基本的数据类型。基本上都是有限的几个:数字型(有些会分整型和实型),字符型, 布尔型(有些没有)等等。然后再提供语法,让开放人员可以自定义更复杂的数据类型。

Java里面提出的就是“类”这个概念,它能保存更多的数据(属性),还能定义各种各样的操作方法。所以,我们完全可以把类描述为“复杂数据类型”。如果我们更看重它产生的变量和对象在内存中的保存形式,那么我们也可以把它称为“引用数据类型”。

3、类与类之间的关系
is - a 把对方做为自己的父类
as - a 把对方作为自己的属性
use - a 把对方作为自己某个方法的局部变量

在设计的时候,不要为了达到最终效果去做设计,而是要更多的去贴近现实场景的关联关系。虽然可能不符合场景关联的设计你也能绕出最终效果,但是如果场景发生变化,那么很可能你会推翻之前的设计全部重来。而符合场景的关联关系设计,可以随着场景的变化,其自身也可以符合这种变化,那么我们修改的量更少,可扩展性更强。

继承

继承是一种类与类的关系(is - a); 设计继承的目的同样是为了复用。

语法很简单: 1、extends 2、单继承 3、默认继承Object

内存实现: “内存叠加” -- 这是Java继承的内存核心实现。

在产生一个子类对象的时候,JVM会首先调用父类的构造方法,在内存中产生一个父类对象部分(里面包含了父类的信息内容),然后再调用子类自己的构造方法,在父类对象部分的下面叠加上子类特有部分,从而构成一个完整的子类对象。

细节上要注意: 1、这里并不意味着产生了两个对象(父类对象和子类对象),其实只产生了一个子类对象。只是这个子类对象里面有一个父类对象部分。 2、父类并不是所有的信息内容都会被子类继承,比如:构造方法不会继承;父类中的私有属性且该属性没有允许子类操作到的方法(get/set)。 3、子类可以再定义一个与父类完全一个样的属性(类型一样名称一样),父类的定义的是放在父类对象部分,子类定义的是放在子类特有部分,并不会出现覆盖的情况。使用的时候用super.属性和this.属性进行区分,当然出现这种设计是不合理的,没有必要把同一个属性定义两次。

单继承的选择是Java语言的设计者的选择,不是所有的面相对象语言都是单继承。选择了它就要承受它的好(继承树的层次结构清晰,构建大型结构的时候不会出现网状结构),也要接受它的不好(丰富度不够)。这也是Java要设计接口这种类型的原因,接口可以通过多实现弥补这个问题。

Object是所有类包括数组的父类,这个特性需要各位同学一定要重视,因为这说明Object当中的方法是公用性最强的方法,换句话说只要是一个Java语言当中的对象就应该拥有的方法。其中最重要的是:equals和toString。

equals方法从名字上看就是“判断是否相等”,但问题是什么算相等?在Java程序中有两种情况都可以说是否“相等”。一个是他们是不是一个对象;还有一个是他们两个对象的内容是否相等。 前者,其实运算符"=="号就是专用来判断该情况的。那么就没有必要再提供一个equals方法来做同样的事情,所以equals方法设计的本意就是用到第2种情况的(即判断两个对象的内容是否相等)。只是由于在根类Object中,并不知道每个子类的具体内容是什么,所以先人在默认实现的时候还是用了“==”号,它只能由子类的实现者去重写。

toString方法不是把对象转换成字符串,而是返回对象的字符串描述。同样是由于它是定义在Object当中的,Object不知道子类的信息当然也不知道该用什么样的字符串内容去描述子类对象。所以,先人只能采用默认的方式---“类型@16进制Hash值”。如果我们在子类当中希望用自己的方式去描述这个对象,那么就对toString方法进行重写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值