变量、对象和引用到底有什么区别?
例如:它们都指向某种类型,并且它们都必须保存值(当然,除非您拥有临时可空类型),但是它们的函数和实现彼此之间究竟有何不同?
的例子:
Dog myDog = new Dog(); //variable myDog that holds a reference to object Dog
int x = 12; //variable x that hold a value of 12
他们有相同的概念,但他们有什么不同?
(只是为了清楚,我在这里给出的解释是特定于Java和c#的。不要认为它适用于其他语言,尽管它的某些部分可能适用。
我喜欢用一个比喻来告诉别人我住在哪里。我可以把我的地址写在一张纸上:- 变量就像一张纸。它保存一个值,但它本身不是这个值。你可以把那里的东西划掉,然后写一些别的东西。
- 我写在纸上的地址就像一个参考。这不是我的房子,但这是一种导航到我家的方式。 我的房子本身就像一个物体。我可以给出对同一个对象的多个引用,但只有一个对象。
有帮助吗?
值类型和引用类型的区别在于写在纸上的内容。例如:
int x = 12;
就像一张直接写了数字12的纸。而:
Dog myDog = new Dog();
不把Dog对象的内容本身写在纸上——它创建了一个新的Dog
,然后在纸上写了一个对Dog的引用。
在非类比条件下:
- 变量表示内存中的存储位置。它有一个名称,您可以在编译时引用它,并且在执行时它有一个值,该值将始终与其编译时类型兼容。(例如,如果您有一个
- 字段(状态)
- 类型引用(在对象的生命周期内永远不能改变)
- 监视器(用于同步)
- 引用是用来访问对象的值,例如调用对象的方法,访问对象的字段等。通常使用
.
操作符导航引用。例如,如果foo
是Person
变量,那么foo.getAddress().getLength()
将获取foo
(一个引用)的值,并在该引用引用的对象上调用getAddress()
。结果可能是String
引用…然后在引用所指向的对象上调用getLength()
。
Button
变量,该值将始终是对Button
类型的对象或某些子类的引用-或null
引用。)对象是一种独立的实体。重要的是,变量或任何表达式的值绝不是对象,而只是引用。一个对象有效地包括:在解释这些概念时,我经常使用以下类比:
想象一个物体是一个气球。变量是一个人。每个人要么在值类型团队中,要么在引用类型团队中。他们都玩了一个小游戏,规则如下:
值类型的规则:- 你抱着一个充满空气的气球。(值类型变量存储对象)
- 你必须一直拿着一个气球。(值类型不可为空) 当别人想要你的气球时,他们可以自己吹一个一模一样的,然后把它抱在怀里。(在值类型中,对象被复制)两个人不能拿同一个气球。(值类型不共享)
- 如果你想拿一个不同的气球,你必须打破你已经拿着的一个,然后抓住另一个。(值类型对象在被替换时被销毁)
- 你可以抓住一根绳子,它通向一个充满氦气的气球。(引用类型变量存储对对象的引用)
- 你可以拿一根绳子,也可以不拿绳子。(引用类型变量可为空) 当别人想要你的气球时,他们可以自己找一根绳子,把它绑在和你一样的气球上。(在引用类型中,引用被复制)
- 多个人可以拿着通往同一个气球的绳子。(引用类型的对象可以共享)
- 只要至少有一个人还在握着气球的绳子,气球就是安全的。 (一个引用类型的对象,只要它是可访问的,它就是活的。)
- 对于任何一个特定的气球,如果每个人最终都放开它,那么气球就会飞走,没有人能再到达它。(引用类型对象可能在某些时候变得不可访问)
- 在游戏结束前的某个时间点,由于大气压力,一个丢失的气球可能会自己爆开。(不可达对象有资格进行垃圾收集,这是不确定的。)
你可以把它想象成回答问题。
对象是什么?
它就像世界上的任何物理事物一样,一个"事物"本身是可识别的,并且具有区别于其他"事物"的重要属性。就像你知道狗是狗,因为它会叫,如果你扔球,它会动尾巴,追球。
就像你看着自己的手。每一只手本身就是一只手。它们的皮肤里有手指、指甲和骨头,但你知道一只是左手,另一只是右手。也就是说,你可以有两个相同类型/类型的"东西",但每一个都可以以自己的方式不同,可以有不同的值。
如果你看一条街上的两栋房子,虽然它们都有自己的门面,但你可以通过它们唯一的地址到达每一栋房子,这意味着,如果你离得很远,比如三个街区远,或者在另一个国家,你可以说出房子的地址,因为它们仍然在你离开的地方,即使你不能直接指向它们。
现在为了编程的缘故,c++方式的例子
class Person{...}
Person Ana = new Person(); //An object is an instance of a class(normally)
也就是说,Ana是一个人,但她有独特的属性,使她与另一个人区别开来。
&Ana //This is a reference to Ana, that is to say, a "where" does the variable
//"Ana" is stored, wether or not you know it's value(s)
Ana
本身是用于存储名为"Ana"的人的属性的变量
Jon的回答非常适合类比。如果更具体的措辞对你有用,我可以帮忙。
让我们从一个变量开始。变量是一个包含值的[命名]事物。例如,int x = 3
定义了一个名为x的变量,其中包含整数3。如果我接着赋值,x=4
, x现在包含整数4。关键是我们没有替换变量。我们没有一个新的"变量x的值现在是4",我们只是用一个新值替换了x的值。
现在让我们转移到对象。对象很有用,因为你经常需要一个"东西"从很多地方被引用。例如,如果您在编辑器中打开了一个文档,并希望将其发送到打印机,那么最好只有一个文档,由编辑器和打印机同时引用。这将节省你复制它的次数。
然而,因为你不想复制它多次,所以我们不能把对象放在变量中。变量保存一个值,所以如果两个变量保存一个对象,它们必须创建两个副本,每个变量一个。引用是解决这个问题的中介。引用是小的,容易复制的值,可以存储在变量中。
因此,在代码中,当您键入Dog dog = new Dog()
时,new操作符创建一个新的Dog对象,并返回该对象的引用,以便将其赋值给变量。然后赋值给dog
一个引用到你新创建的对象的值。
new Dog()将实例化一个对象Dog(),它将为该对象创建一个内存。您需要访问该变量来操作一些操作。为此,您需要一个引用,即Dog myDog。如果你试图打印对象,它将打印一个不可读的值,除了地址之外什么都没有。
myDog -------> new Dog().