我已经编程java 2年了,显然我遇到了一个问题,我无法理解并再次区分类,引用和对象(我不明白为什么我会忘记这些概念)。
让我们来解决问题,即我不确定类或引用是否相同,尽管我已经知道什么是对象。
有人能够以一种好的,可理解的和完整的方式区分什么是类,引用和对象?
我所知道的是,这个类更像是一个对象的模板(一个房子的蓝图,其中类是蓝图而房子是一个对象)。
答案 0 :(得分:125)
如果你喜欢住房隐喻:
您可以根据需要复制该引用,但只有一个房子 - 您只是复制其上有地址的卡,而不是房屋本身。
在Java中,您不能直接访问对象,只能使用引用。 Java不会相互复制或分配对象。但是您可以复制并分配对变量的引用,以便它们引用同一个对象。 Java方法总是按值传递,但值可以是对象的引用。所以,如果我有:
Foo myFoo = new Foo(); // 1
callBar(myFoo); // 2
myFoo.doSomething() // 4
void callBar(Foo foo) {
foo = new Foo(); // 3
}
然后让我们看看发生了什么。
new Foo()
告诉JVM使用Foo
蓝图构建一个新房子。 JVM这样做,并返回对房屋的引用。然后,将此引用复制到myFoo
。这基本上就像要求承包商为你建房子。他这样做,然后告诉你房子的地址;你写下这个地址。callBar
。我们接下来跳转到那个方法。Foo foo
。 Java是按值传递的,因此foo
中的callBar
是myFoo
引用的副本。可以把它想象给callBar
它自己的卡片上面有房子的地址。 callBar
对此卡做了什么?它要求建造一个新房子,然后用你给它的卡片写下新房子的地址。请注意callBar
现在无法到达第一个房子(我们在第1行建造的那个房子),但是这个房子没有改变,因为一张曾经在其上有地址的卡,现在还有一些其他的房子的地址就可以了。myFoo
来调用方法(doSomething()
)。这就像看卡片,去卡片上的地址,然后在那个房子里做点什么。请注意,myFoo
方法的callBar
地址卡未更改 - 请记住,我们提供了callBar
副本的参考资料。整个序列如下:
myFoo
。callBar
。在我们开始之前,我们会将myfoo
上写的地址复制到我们提供给callBar
的新卡片上。它称该卡为foo
。callBar
向JVM询问另一所房子。它创建它,并返回新房子的地址。 callBar
将此地址复制到我们提供的卡片上。答案 1 :(得分:12)
答案 2 :(得分:6)
在布鲁斯·埃克尔(Bruce Eckel)的“Thinking in Java”一书中,它被完美地描述了:
“你可能会想象一个电视(对象)和一个遥控器(参考)。只要你拿着这个参考,就可以连接到电视,但当有人说”改变频道“时或者“降低音量”,你操作的是参考,然后修改对象。如果你想在房间里移动并仍然控制电视,你可以随身携带遥控/参考,而不是电视。
此外,遥控器可以独立,没有电视。也就是说,仅仅因为你有一个引用并不意味着必然有一个对象连接到它。因此,如果要保留单词或句子,则创建一个String引用:
String s;
但是在这里你只创建了引用,而不是对象。如果您此时决定向s发送消息,则会收到错误,因为s
实际上并未附加到任何内容(没有电视)。因此,更安全的做法是在创建引用时始终初始化引用:
String s = "asdf";
但是,这使用了一个特殊的Java功能:可以使用带引号的文本初始化字符串。通常,您必须对对象使用更通用的初始化类型。
创建引用时,需要将其与新对象连接。通常,您可以使用new运算符执行此操作。关键字new表示“让我成为这些对象中的新对象。”因此,在上面的示例中,您可以说:
String s = new String("asdf");
这不仅意味着“让我成为一个新的字符串”,而且它还提供了有关如何通过提供初始字符串来生成字符串的信息。 当然,除了String之外,Java还附带了大量现成的类型。更重要的是,您可以创建自己的类型。实际上,创建新类型是Java编程中的基本活动。“
答案 3 :(得分:3)
假设您在那里写了两行代码:
Engine app1 = new Engine(); //LINE 1
Engine app2 = app1; //LINE 2
在第1行中,Engine是类,基本上是蓝图。
new Engine()是在堆上创建的实例。
您在代码中使用app1和app2引用实例。
所以app1和app2是引用。
答案 4 :(得分:2)
创建对象时,场景背后会发生的事情是保留一块内存来容纳该对象。这可能是伟大的大记忆景观中的任何地方;这取决于操作系统和编译器,你实际上并没有任何控制或知道它最终的位置。
问问自己,如果你不知道它在哪里,你如何使用该对象?如果您不知道该值的存储位置,如何从中读取值?这是参考资料为您做的。它们是与物体保持联系的一种方式。它是附在气球上的一个小字符串,是一个参考。
您使用该引用说“我想立即触摸此对象!”或“我想从此对象中读取值!”。< / p>
答案 5 :(得分:1)
Class是一个模板,你是对的。它是关于数据结构的一些知识。对象是内存中的结构实例。 Reference是该实例的内存地址。
如果Object
表示java标识符,则Object
是所有复杂Java类的基本类。
答案 6 :(得分:1)
班级: 结构或BluePrint
对象: 身体表现
参考: 对象地址
答案 7 :(得分:0)
Object
是Class
定义的运行时表示。并且使用对象的名称称为reference
(因为它引用了内存中的实际对象位置)
例如
MyClass ref = new MyClass();
此处, MyClass 是(包含)类定义。
new MyClass()为此类创建对象(仅在执行期间完成,因此运行时代表)
ref 是您用于处理类对象的名称,是引用。
答案 8 :(得分:0)
=========类和对象===========
Class =&gt;例如:人(更喜欢想象力)
对象=&gt;例如:约翰,迈克(真人)
===========参考============
例如:
电视tv1; - (电视是一类,tv1是没有电视的遥控器)
电视tv2 =新电视(); - (现在tv2遥控器有电视)
tv1 = tv2; - (现在tv1和tv2可以控制同一部电视)
电视tv3 =新电视(); - (tv3是新电视的新遥控器)
答案 9 :(得分:0)
类:用于将实际实体定义到编程环境中。
任何具有至少一个property
和相应behaviour
的现实生活实体都可以被视为一个类。让我们举一个 Car 的例子,它有一个属性accelerator
,它可以帮助汽车移动并控制它的速度。相应的行为是acceleration
,它与应用于加速器的推力成正比。
class Car {
private String tier;
private String tierFriction;
private double weight;
private double gasFedToEngine;
}
上面的类显示了Car的一些属性,它的加速度取决于它。行为(method in the class
)总是取决于属性(global attribute(s) of the class
)。现在,如果您想要更多详细信息,可以将Tier
定义为另一个实体,那么定义将类似于
class Tier {
private String tierMaterial;
private String tierFriction;
private double weight;
private double tierDiameter;
}
class Car {
private Tier tier; // getting all properties of Tier here itself
private double weight;
private double gasFedToEngine;
}
对象:用于定义实体的各种风格并分别对它们执行数据操作。
现在我们已经为我们的计划定义了一个实体,比如说我们有一个二手车的陈列室,有不同公司的汽车。所以每辆车都成为我们实体的object
。对象可以是奥迪,日产,法拉利等。所以在打开陈列室后,我们就像这样添加汽车
static List<Car> showroomCars = new ArrayList<Car>();
public boolean addCarToShowroom() {
Car carNissan = new Car(); // always creates a new objects and allocates some memory in heap
carNissan.setName("Nissan");
carNissan.setColor(RED);
carNissan.setWeight(300);
showroomCars.add(carNissan);
Car carAudi = new Car();
carAudi.setName("Audi");
carAudi.setColor(BLACK);
carAudi.setWeight(270);
showroomCars.add(carAudi);
}
所以现在两辆新车被添加到陈列室,一辆是日产,另一辆是奥迪,每辆都有自己特定的属性值。
Class
只提供定义,操作在Object
上完成,对于任何类进行操作,应该创建对象。每次为类创建一个对象时,其所有非satic(实例)变量都将使用各自的默认值加载到内存中。
参考:用于处理对象
当我们说Car carAudi = new Car();
时,我们为Car定义了一个新对象,并为该对象分配了一个内存位置。引用变量carAudi
保存该对象的内存地址。用户永远不会直接访问对象,也不会访问其内存位置。参考变量具有重要性的地方,它存储了hexadecimal
格式的内存位置。如果我们想对一个对象进行修改,请不要直接参考。
对象可以包含任意数量的引用,但引用一次只能指向一个对象。
class Car {
void test() {
Car car1 = new Car(); // (1)
Car car2 = new Car(); // (2)
car2 = car1;
/**
Says that car2 should point to where car1 points, so now both points to first object of Car
But for this car2 has to loose its current object-(2), making it an Abandoned object (An object with no active reference from the stack).
**/
}
}
答案 10 :(得分:0)
让我们以学生为例:
//We have a Student class. Below are some attributes which we will use:
class Student
{
string Name;
int Age;
string Address;
}
现在,“学生之上”确实不存在。这只是学生学习的蓝图。如果我们需要创建一个学生,则称其为创建对象,下面是创建一个学生的格式。
Student student=new Student();
现在,在内存中创建了1个学生对象,可用于设置任何姓名/年龄/地址并获得如下所示的相同信息:
static void Main(string[] args)
{
Student student = new Student();
student.Name = "Vivek";
student.Age = 24;
student.Address = "Address";
Console.Write("Student Name is " + student.Name + " whose age is " + student.Age + " and he/she stays at " + student.Address);
}
现在,假设您想向学生提供一些工作,您将如何做?
//By writing a function/method and write the code which student should handle as below:
class Student
{
public string Name;
public int Age;
public string Address;
public void Run()
{
//Write some code
}
public void Walk()
{
//Write some code
}
}
以上只是一个示例,因为学生不会在内存中运行,因此,您必须编写的代码仅是C#代码或用于编写代码的任何编程语言。就像使用C#进行一些操作一样。
现在,我想强调一下:
示例:您的定制汽车不会定制汽车的所有部件。您必须使用现有的部件,例如轮子/层/空调等。因此,类可以使用现有的类/结构/方法/字段等,以达到要求。正如您在下面看到的那样,该类正在使用其他类/ struct / methods / fields等来满足要求:
//String is also class which represents text as a sequence of UTF-16 code units
public string Name;
//Integer is a struct which represents a 32-bit signed integer
public int Age;
//String is also class which represents text as a sequence of UTF-16 code units
public string Address;
答案 11 :(得分:0)
Java 中的一切都与类对象和类相关联,包括属性和方法。例如:汽车是现实生活中的物体。汽车具有属性,例如重量和颜色,以及方法,例如驱动和制动。一个类就像一个对象构造函数或创建对象的“蓝图”。
引用是指示对象的变量和方法存储位置的地址。当您将对象分配给变量或将对象作为参数传递给方法时,您实际上并没有使用对象。