What Are Classes, References, and Objects

What are classes, references, and objects?

If you like housing metaphors:

  • a class is like the blueprint for a house. Using this blueprint, you can build as many houses as you like.
  • each house you build (or instantiate, in OO lingo) is an object, also known as an instance.
  • each house also has an address, of course. If you want to tell someone where the house is, you give them a card with the address written on it. That card is the object's reference.
  • If you want to visit the house, you look at the address written on the card. This is called dereferencing.

You can copy that reference as much as you like, but there's just one house -- you're just copying the card that has the address on it, not the house itself.

In Java, you can not access objects directly, you can only use references. Java does not copy or assign objects to each other. But you can copy and assign references to variables so they refer to the same object. Java methods are always pass-by-value, but the value could be an object's reference. So, if I have:

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

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

Then let's see what's happening.

  1. Several things are happening in line 1. new Foo() tells the JVM to build a new house using the Foo blueprint. The JVM does so, and returns a reference to the house. You then copy this reference to myFoo. This is basically like asking a contractor to build you a house. He does, then tells you the house's address; you write this address down.
  2. In line 2, you give this address to another method, callBar. Let's jump to that method next.
  3. Here, we have a reference Foo foo. Java is pass-by-value, so the foo in callBar is a copy of the myFoo reference. Think of it like giving callBar its very own card with the house's address on it. What does callBar do with this card? It asks for a new house to be built, and then uses the card you gave it to write that new house's address. Note that callBar now can't get to the first house (the one we built in line 1), but that house is unchanged by the fact that a card that used to have its address on it, now has some other house's address on it.
  4. Back in the first method, we dereference myFoo to call a method on it (doSomething()). This is like looking at the card, going to the house whose address is on the card, and then doing something in that house. Note that our card with myFoo's address is unchanged by the callBar method -- remember, we gave callBar a copy of our reference.

The whole sequence would be something like:

  1. Ask JVM to build a house. It does, and gives us the address. We copy this address to a card named myFoo.
  2. We invoke callBar. Before we do, we copy the address written on myfoo to a new card, which we give to callBar. It calls that card foo.
  3. callBar asks the JVM for another house. It creates it, and returns the new house's address. callBar copies this address to the card we gave it.
  4. Back in the first method, we look at our original, unchanged card; go to the house whose address is on our card; and do something there.

What is difference between references and objects in java?

References are names. Objects are stuff. You can have different names for stuff, even for stuff that doesn't actually exist.

You can declare names, without actually giving them any "real" meaning, like this:

GUI g1;

You can assign meaning (real stuff to refer to) to names with the = operator:

GUI g1 = some_gui;

Names can change their meaning over time. The same name can refer to different things at different points in history.

GUI g1 = some_gui;

doSomething();

g1 = some_other_gui;

There are also synonyms: multiple names can refer to the same thing:

GUI g2 = g1;

That's pretty much what references do. They are names meant to refer to stuff.

Stuff can be created:

new GUI();

Stuff can be created and named on the spot for later reference (literally!):

GUI g1 = new GUI();

And stuff can be referred to, using its name (or any of its names!):

g1.doSomething();
g2.doSomethingAgain();

Different stuff of the same kind (Class) can be created, and named differently:

GUI g1 = new GUI();
GUI g2 = new GUI();
GUI g3 = new GUI();

GUI g1_synonym = g1;

:)

Is reference variable and Object created from a class using new keyword in Java, one and the same thing?

An object is the thing that holds the values. You create it using new Coder(). It has no name.

A reference variable is a thing that points to that object. You can think of it as a name that you give it.

If you just create new Coder() and never let anything point to it it will be pointless and eventually garbage collected, because there's no way to reference it.

If you do

Coder coder1 = new Coder();

then coder1 is a reference to the object. You can use it to call methods on the object like coder1.toString().

You can even create another reference that points to the same object:

Coder coder2 = coder1;

It might look like you now have 2 Coder objects, but you don't. There's still only one. You have 2 references to it (or "names" if you will). coder1.toString() will do the exact same thing as coder2.toString(), because they reference the same object.

Will an object reference to an object of a class A having another object of class B as its instance variable, also point to the object of type B?

Given the provided code, r.v will remain null by default, since you are not assigning anything to it.

In order for v to hold a reference to an object of class B, you'll have to add somewhere v = new B ();.

For example, you can add that statement in A's constructor:

public class A {
B v;

public A ()
{
this.v = new B ();
}
}

If classes hold an object reference as their value, why doesn't the new keyword overwrite them?

It's probably easier to understand if you forget all that "pass by reference" vs "pass by value" - they're poor terms of phrase, as you're finding out because they tend to make you conceive that the Book memory data is either being copied when it is passed to the method, or the original is passed. "Pass by copy of reference" and "pass by original reference" might be better - class instances are always passed by reference

I find it more helpful to think of nearly every variable in a program as being a reference in its own right, and "pass by value/reference" refers to whether a new reference is created or not when calling a method.

So you have your line:

Book book1 = new Book("Fight club");

Immediately after we execute this line, there is one variable name in your program, book1, and it refers to some block of data at memory address 0x1234 that contains "Fight club"

ChangeBookName(book1, "The Wolfman");

We call the ChangeBookName method and c# establishes another reference, called book, because that is what it says in the method signature, also pointing to address 0x1234.

You have two references, one block of data. The book reference will be lost when the method ends- it's lifetime is only between the { } of the method

If you use this additional book reference to change something about the data:

book.Name = "The wolfman";

Then the first reference, book1 will see the change- it points to the same data, the data changes.

If you point this additional book reference to a whole new block of data elsewhere in memory:

 book = new Book("The wolfman");

You now have two references, two blocks of data - book1 points to "fight club" at 0x1234, and book points to "the wolfman" at 0x2345. The wolfman data and the book reference will be lost when the method ends

The crucial point here about having two references to one block of data is that you can change some property of the data and both references see it? But if you point one of the references to a new block of data the original reference remains pointing to the original data

If you want a method to be able to swap out the block of data for a whole new block of data and also have the original reference experience the change, you use the ref keyword. Conceptually this causes C# not to make a copy of the reference at all, but reuse the same reference (albeit with a different name)

void ChangeBookForANewOne(ref Book tochange){
tochange = new Book("Needful things");
}

Book b = new Book("Fight club");
ChangeBookForANewOne(b);

All through this code there is only one reference to one block of data. Changing the block of data for a new one inside the method causes the change to be remembered when the method exits

We seldom do ref; if you want to change your book for a new one you should really return it from the method and change reference b to be the newly returned book. People use ref when they want to return more than one thing from a method but really that's an indicator that you should be using a different class as the return type


The same notions are true for value types (usually primitive things like int) but the slight difference is that if you pass an int to a method then you end up with two variable names but also two ints in memory; if you increment the int inside the method the original int doesn't change because the additional variable established for the lifetime of the method call is a different data in memory - the data really is copied and you have two variables and two numbers in memory. Ref style behaviour is more useful and more common for things like this, with things like int.TryParse - it returns a true or false indicating whether parsing succeeded but in order to return the parsed value to you it needs to use the original variable you passed in, not a copy of it.

To do this, TryParse uses a variation of ref called out - a marker on a method variable that indicates "this method will definitely assign a value to the variable you pass in; if you were to give it a variable already initialized to a value it would definitely be overwritten". In contrast, ref indicates "you can pass a variable in that is initialized to a value, I might use the value and I might overwrite it/point it to a new data in memory". If you have a method that doesn't need to take a value but definitely overwrites, like my ChangeForANewBook before, you should really use out - in 100% of cases ChnageForANewBook overwrites what was passed in, which could cause unintended data loss for a developer. Marking it as out would mean C# would make sure only blank references are used/passed in, helping prevent unintended data loss

Storing References to Objects of Different Classes

if you mean that the objects you store are instances of those two classes, you should make those classes inherit from a (custom?) class or interface and use that class/interface as the type to store in your array.



Related Topics



Leave a reply



Submit