什么是类,引用和对象?

时间:2012-02-10 07:59:51

标签: java oop class object reference

我已经编程java 2年了,显然我遇到了一个问题,我无法理解并再次区分类,引用和对象(我不明白为什么我会忘记这些概念)。

让我们来解决问题,即我不确定类或引用是否相同,尽管我已经知道什么是对象。

有人能够以一种好的,可理解的和完整的方式区分什么是类,引用和对象?

我所知道的是,这个类更像是一个对象的模板(一个房子的蓝图,其中类是蓝图而房子是一个对象)。

12 个答案:

答案 0 :(得分:125)

如果你喜欢住房隐喻:

  • 就像房子的蓝图。使用这个蓝图,你可以建造任意数量的房屋。
  • 您构建的每个房屋(或在OO术语中实例化)都是对象,也称为实例
  • 当然,每个房子都有一个地址。如果你想告诉某人房子的位置,你可以给他们一张上面写有地址的卡片。该卡是对象的参考
  • 如果您想参观这所房子,请查看卡片上写的地址。这称为解除引用

您可以根据需要复制该引用,但只有一个房子 - 您只是复制其上有地址的卡,而不是房屋本身。

在Java中,您不能直接访问对象,只能使用引用。 Java不会相互复制或分配对象。但是您可以复制并分配对变量的引用,以便它们引用同一个对象。 Java方法总是按值传递,但值可以是对象的引用。所以,如果我有:

Foo myFoo = new Foo();     // 1
callBar(myFoo);            // 2
myFoo.doSomething()        // 4

void callBar(Foo foo) {
    foo = new Foo();       // 3
}

然后让我们看看发生了什么。

  1. 第1行发生了一些事情。new Foo()告诉JVM使用Foo蓝图构建一个新房子。 JVM这样做,并返回对房屋的引用。然后,将此引用复制到myFoo。这基本上就像要求承包商为你建房子。他这样做,然后告诉你房子的地址;你写下这个地址。
  2. 在第2行中,您将此地址提供给另一种方法callBar。我们接下来跳转到那个方法。
  3. 在这里,我们有一个参考Foo foo。 Java是按值传递的,因此foo中的callBarmyFoo引用的副本。可以把它想象给callBar它自己的卡片上面有房子的地址。 callBar对此卡做了什么?它要求建造一个新房子,然后用你给它的卡片写下新房子的地址。请注意callBar现在无法到达第一个房子(我们在第1行建造的那个房子),但是这个房子没有改变,因为一张曾经在其上有地址的卡,现在还有一些其他的房子的地址就可以了。
  4. 回到第一种方法,我们取消引用myFoo来调用方法(doSomething())。这就像看卡片,去卡片上的地址,然后在那个房子里做点什么。请注意,myFoo方法的callBar地址卡未更改 - 请记住,我们提供了callBar 副本的参考资料。
  5. 整个序列如下:

    1. 让JVM建房子。它确实给了我们地址。我们将此地址复制到名为myFoo
    2. 的卡片中
    3. 我们调用callBar。在我们开始之前,我们会将myfoo上写的地址复制到我们提供给callBar的新卡片上。它称该卡为foo
    4. callBar向JVM询问另一所房子。它创建它,并返回新房子的地址。 callBar将此地址复制到我们提供的卡片上。
    5. 回到第一种方法,我们看看我们原来的,未更改的卡片;去我家卡上的地址;并在那里做点什么。

答案 1 :(得分:12)

编码时,构建

  

实例(发生,复制)

  

对象

表示

  

并保持

  

参考

,所以你可以调用它的方法。

此外,还有一些OOP基础知识:ClassesObjectInstanceReference

答案 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)

ObjectClass定义的运行时表示。并且使用对象的名称称为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)

  • 在现实世界中,对象是在这个宇宙中可以看到和触摸的物质。
  • 在编程中,对象是相同的,但是它们就像存储任何对象一样被存储或捕获在内存中。它将在RAM(内存)中创建。因此,作为人类,我们将无法看到或触摸它,但它确实存在于内存中的某个地方。
  • 因此,我们不在乎系统如何创建或销毁对象,而是将了解如何使用编程来处理它。
  • 为了创建对象,编程语言提供了我们可以用来处理这些对象的语法格式。
  • 现在,如果要创建自定义的新车,那么如何定义要创建的对象,然后必须向制造商提供要求?。
  • 以相同的方式编程,使用类。该类是一个蓝图,它将定义对象的外观/它将存储的所有数据以及它将执行的所有操作。它在内存中不存在,仅用于定义创建对象的要求。

让我们以学生为例:

//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#进行一些操作一样。

现在,我想强调一下:

  • 如果您在现实世界中看到。学生不仅包含姓名/地址/年龄,而且还具有其他属性,如母亲姓名/父亲姓名/护照等。除了常规属性外,我们还可以添加身体部位,例如大脑/心脏/腿等。
  • 因此,如果您向Class Student添加所有属性,则它会变得更加复杂。

示例:您的定制汽车不会定制汽车的所有部件。您必须使用现有的部件,例如轮子/层/空调等。因此,类可以使用现有的类/结构/方法/字段等,以达到要求。正如您在下面看到的那样,该类正在使用其他类/ 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 中的一切都与类对象和类相关联,包括属性和方法。例如:汽车是现实生活中的物体。汽车具有属性,例如重量和颜色,以及方法,例如驱动和制动。一个类就像一个对象构造函数或创建对象的“蓝图”。

引用是指示对象的变量和方法存储位置的地址。当您将对象分配给变量或将对象作为参数传递给方法时,您实际上并没有使用对象。