什么是类,引用和对象?
我已经编写了2年Java,显然我遇到了一个问题,我不能理解和区分类,引用和对象(我不明白为什么我忘了这些概念)。
让我们来回答这个问题,即我不确定一个类或引用是否相同,尽pipe我已经知道什么是对象。
有人能以一种很好的,可以理解的,完整的方式来区分什么是类,引用和对象?
我所知道的是,class级更像是一个对象的模板(蓝图到房子是蓝图,房子是对象)。
如果你喜欢住房隐喻:
- 一个阶级就像一座房子的蓝图。 使用这个蓝图,你可以build造尽可能多的房子,只要你喜欢。
- 你build立的每个房子(或OO术语实例化)是一个对象 ,也被称为一个实例 。
- 当然,每个房子也有一个地址。 如果你想告诉某人房子在哪里,你可以给他们一张写有地址的卡片。 那张牌是对象的参考 。
- 如果你想访问房子,你看看写在卡上的地址。 这被称为解引用 。
你可以尽可能多地复制那个参考文件,但是只有一个房子 – 你只是复制了有地址的卡,而不是房子本身。 Java方法总是按值传递,但是这个值可能是一个对象的引用。 所以,如果我有:
Foo myFoo = new Foo(); // 1 callBar(myFoo); // 2 myFoo.doSomething() // 4 void callBar(Foo foo) { foo = new Foo(); // 3 }
那么让我们看看发生了什么。
-
new Foo()
告诉JVM使用Foo
蓝图build立一个新房子。 JVM这样做,并返回一个房子的参考。 然后,您将此引用复制到myFoo
。 这基本上就像是要一个承包商为你盖房子一样。 他呢,然后告诉你房子的地址; 你写下这个地址。 - 在第2行中,您将此地址指定给另一个方法
callBar
。 接下来让我们跳到这个方法。 - 在这里,我们有一个参考
Foo foo
。 Java是通过值传递的,所以callBar
的foo
是myFoo
引用的副本 。 把它看作是给它自己的卡上的房子的地址callBar
。callBar
用这张卡做什么? 它要求build造一座新房子,然后用你给它的卡片来写这个新房子的地址。 请注意,callBar
现在callBar
第一个房子(我们在第一行build立的那个房子),但是这个房子没有改变,因为一张曾经拥有地址的卡片现在有一些其他房子的地址。 - 回到第一个方法,我们解引用
myFoo
来调用它的一个方法(doSomething()
)。 这就像看着卡片,到地址在卡片上的房子,然后在那个房子里做一些事情。 请注意,我们的卡与myFoo
的地址是由callBar
方法不变 – 记住,我们给callBar
我们的参考副本 。
整个序列会是这样的:
- 要求JVMbuild造一座房子。 它确实,并给我们的地址。 我们将这个地址复制到名为
myFoo
的卡片上。 - 我们调用
callBar
。 在我们做之前,我们把写在myfoo
上的地址复制到一个新的卡上,我们给callBar
。 它把这张牌叫做foo
。 -
callBar
要求JVM换另一间房子。 它创build它,并返回新房子的地址。callBar
这个地址复制到我们给的卡上。 - 回到第一种方法,我们看看我们原来的,不变的卡; 去我们信用卡上的房子 并在那里做一些事情。
当你编码时,你build立一个
实例(发生,复制)
一个
目的
的一个说
类
并保持一个
参考
对它,所以你可以调用它的方法。
另外,一些OOP基础: 类 , 对象 , 实例和引用 。
在Bruce Eckel的“Thinking in Java”一书中,已经有了很好的描述:
“你可能想象一个电视机(这个物体)和一个遥控器(参考),只要你拿着这个参考电视机,你就可以连接到电视机,但是当有人说”改变频道“或者”降低音量“,你操纵的是参考,反过来修改对象,如果你想在房间里走动,仍然控制电视机,你可以拿遥控器,而不是电视机。
而且,遥控器可以独立,没有电视。 也就是说,仅仅因为你有一个引用并不意味着必然有一个对象连接到它。 所以,如果你想持有一个字或句子,你创build一个string引用:
String s;
但是在这里你只创build了引用,而不是一个对象。 如果你决定发送消息给s,你会得到一个错误,因为s
实际上并没有附加任何东西(没有电视)。 那么更安全的做法是在创build时总是要初始化一个引用:
String s = "asdf";
但是,这使用了一个特殊的Java特性:string可以用带引号的文本进行初始化。 通常,您必须使用对象的更一般types的初始化。
当你创build一个引用时,你想要连接一个新的对象。 一般来说,你是这样做的。 关键字new说:“让我成为这些对象中的一个新对象”。所以在前面的例子中,你可以说:
String s = new String("asdf");
这不仅意味着“让我成为一个新的string”,而且还提供了有关如何通过提供初始string来创buildstring的信息。 当然,除了String之外,Java还有大量现成的types。 更重要的是你可以创build自己的types。 实际上,创build新types是Java编程的基本活动。“
假设你写了两行代码:
Engine app1 = new Engine(); //LINE 1 Engine app2 = app1; //LINE 2
在第一行,引擎是一个类 ,基本上是一个蓝图。
新的Engine()是在堆上创build的实例 。
您在代码中使用app1和app2来引用该实例 。
所以app1和app2是引用 。
类是一个模板,你是对的。 这是关于数据结构的一些知识。 对象是内存中的结构实例。 引用是该实例的内存地址。
如果按Object
表示Java标识符,那么Object
就是所有复杂Java类的基本类。
当你创build一个对象的时候,场景后面发生的事情就是保留一段内存来容纳这个对象。 这可能是在伟大的大记忆景观的任何地方; 这取决于操作系统和编译器,而且对于结束的位置你没有任何控制或知识。
那么问自己,如果你不知道它在哪里,你怎么使用这个对象呢? 如果你不知道存储的价值在哪里,你如何从中读取价值呢? 这是什么参考为你做的。 他们是与对象保持联系的一种方式。 这是一个连接到气球的小string,是一个参考。
您可以使用参考来说“我想要触摸这个对象!”,或者“我想从这个对象读取一个值!”。
Object
是Class
定义的运行时表示。 而你使用这个对象的名称被称为reference
(因为它引用了内存中的实际对象位置)
例
MyClass ref = new MyClass();
在这里, MyClass是(包含) 类的定义。
新的MyClass()为这个类创build一个对象 (仅在执行期间完成,因此运行时代表)
ref是你用来处理类对象的名字,是引用 。
=========类和对象===========
人(更像是想象力)
对象=>例如:约翰,麦克(真人)
===========参考============
例如:
电视电视1; – (电视是一类,电视1是没有电视的遥控器)
电视电视2 =新电视(); – (现在tv2遥控器有一台电视机)
tv1 = tv2; – (现在tv1和tv2可以控制相同的电视机)
电视tv3 =新电视(); – (电视3是新的电视新遥控器)