Jump to content

Difference between reference type and object type

- - - - -

  • Please log in to reply
11 replies to this topic

#1
scottbomb

scottbomb

    Newbie

  • Members
  • PipPip
  • 21 posts
I'm currently studying inheritance. I get the concept that I can write a class that inherits methods and variables from a parent class. However, I'm stuck on something.

Up until now, when creating an object, I'm used to writing it like this:

someDerivedClass myObject = new someDerivedClass()

But now, the professor has introduced something like this:

someParentClass myObject = new someDerivedClass()

this.getClass() returns "someDerivedClass". Cool. But what does writing "someParentClass" before myObject do differently than when it had the other (someDerivedClass) in front of it?

#2
nicckk

nicckk

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 629 posts
This is called polymorphism. Usually, all classes extend Object - therefore they are of type Object. In your example, someParentClass is the superclass and someDerivedClass is the subclass. All someDerivedClass objects are someParentClass objects, however not all someParentClass objects are someDerivedClass objects.

Having a reference variable(someParentClass myObject) can be useful to be able to point to any of the subclasses. For example, instead of having the reference variables Deer d, Cat c, Shark s you can create an Animal,lets call it Animal a, and have it point to d,c, or s. In code it could look like this.

Deer d = new Deer();

Cat c = new Cat();

Shark s = new Shark();


Animal a;

a = d; //Valid, because a Deer is an Animal object

a= c; //Valid, because a Cat is an Animal object

a = s; //Valid, because a Shark is an Animal object

 

s = a; //Invalid. An Animal is not a Shark


When calling a method of myObject, it will call the method provided in the class of the actual object. In your example it calls the getClass() method in someDerivedClass because myObject points to a someDerivedClass object.

Hopefull this makes sence to you; Polymorphism was one of the harder things for me to understand.

#3
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
May also be interesting to read: http://forum.codecal...owncasting.html

#4
scottbomb

scottbomb

    Newbie

  • Members
  • PipPip
  • 21 posts
So he's sneaking in the next chapter (polymorphism - which we haven't started yet but I have read ahead some). This is going to take some more reading and mental digestion but you guys have shown me where to start. Thanks!

#5
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
I'm also on this part. I think if you create an object from using the subclass, you won't be able to use the methods in the parent/super class (im not sure bout this, someone confirm or correct this).

#6
scottbomb

scottbomb

    Newbie

  • Members
  • PipPip
  • 21 posts
No, the derived class (aka child or sub) inherits all the methods of the base (aka parent) class. However when one is writing a constructor in the subclass, or overriding a method of the base class, we use super to invoke those parts of the main class we want. Perhaps I can post an example later when I get home.

#7
ZekeDragon

ZekeDragon

    Writes binary right handed and hex left handed

  • Moderators
  • 2,103 posts
Incorrect, every subclass will always have access to the parent's public and protected members, methods, and nested classes, but not private methods. Consider these three classes:
class ParentClass // extends java.lang.Object

{

    // ALL CLASSES IMPLICITLY EXTEND OBJECT!

    // This means that all objects have access to the

    // Object class methods, such as toString and hashCode.

    public void parentMethod()

    {

        System.out.println("Printing from the parent.");

    }

}


class ChildOne extends ParentClass

{

    public void childOneMethod()

    {

        System.out.println("Printing from child one.");

    }

}


class ChildTwo extends ParentClass

{

    public void childTwoMethod()

    {

        System.out.println("Printing from child two.");

    }


    // What follows is called "Overriding", which is when a child class

    // implements a method of the same name and supplied arguments as

    // a method in the parent class. You cannot override private methods,

    // as the compiler will never allow access to private methods in the

    // parent, nor can you override final methods, the compiler will cause

    // a compile error.

    public void parentMethod()

    {

        childTwoMethod();

    }

}

When you override a method like ChildTwo does, you can now modify the behavior of any method that takes ParentClass as an argument! Consider the following method, that just runs parentMethod:
    public static void someMethod(ParentClass someObject)

    {

        someObject.parentMethod();

    }
You can pass any ParentClass object, or better, any subclass of the ParentClass object as the argument to someMethod. Let's try it.
    public static void main(String[] args)

    {

        ChildOne one = new ChildOne();

        ChildTwo two = new ChildTwo();

        someMethod(one);

        someMethod(two);

    }
You'll notice this will first print the version of parentMethod in the ParentClass object, since ChildOne does not override parentMethod, but then it will print from the ChildTwo derived class since ChildTwo does override parentMethod. And that is polymorphism!

EDIT: To add, and to more thoroughly answer scottbomb's question, you may always assign values from derived (child) classes to references to parent classes. Remember that when you're using objects in Java, your program will never create objects on the Stack, instead they're created on the Heap and the new keyword returns a reference to the Heap-allocated object's location. The Object, therefore, is a particular instance to a class, and the reference is the named type itself that your program code manipulates.

Edited by ZekeDragon, 23 April 2011 - 01:59 PM.

Wow I changed my sig!

#8
An Alien

An Alien

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 260 posts
Sorry for hijacking your thread, Scottbomb, but I have a question for Zeke's example.

The code creating the two child objects, what if I modify it and do this:
 public static void main(String[] args)

    {

        ParentClass one = new ChildOne();

        ParentClass two = new ChildTwo();

        someMethod(one);

        someMethod(two);

    }
will the output be the same?

#9
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
No, it won't output the same, because ChildTwo has overridden the parentMethod(). ChildOne didn't.
ChildOne will do
System.out.println("Printing from the parent.");
While ChildTwo does
childTwoMethod();  //--> System.out.println("Printing from child two.");


#10
scottbomb

scottbomb

    Newbie

  • Members
  • PipPip
  • 21 posts
Very interesting. I'm starting to understand polymorphism, and my textbook is now getting into the upcasting and downcasting. The cat tutorial was also helpful but I think I need to read it again.

Interestingly, I copied/pasted all the code here and it works exactly as described, except that An Alien's version of the main method:
    public static void main(String[] args)

    {

        ParentClass one = new ChildOne();

        ParentClass two = new ChildTwo();

        someMethod(one);

        someMethod(two);

    }

...does seem to do the same thing as the original posted by Zeke.
    public static void main(String[] args)

    {

        ChildOne one = new ChildOne();

        ChildTwo two = new ChildTwo();

        someMethod(one);

        someMethod(two);

    } 

Wim DC, I am curious about your answer to An Alien. You said

wim DC said:

No, it won't output the same, because ChildTwo has overridden the parentMethod(). ChildOne didn't.
ChildOne will do
System.out.println("Printing from the parent.");
While ChildTwo does
childTwoMethod();  //--> System.out.println("Printing from child two.");

The output from JCreator for both versions:
Printing from the parent.

Printing from child two.


Process completed.

Did I miss something there? [STRIKETHROUGH]I'm just trying to figure out how it outputs the same thing when they're both written slightly differently. Perhaps the is the upcasting/downcasting phenomenon I'm wresting with. [/STRIKETHROUGH]

Edit: After further review, I can see now why the results are the same (because they use the methods from the child classes). I guess I'm now wondering why I would want to use the variable type of the parent class in this manner. Much more to learn! :)

Edited by scottbomb, 26 April 2011 - 08:43 AM.


#11
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
Okay, when you extend a class, like the name says it, it will extend to the allready present code.
The class being extended is ParentClass

class ParentClass // extends java.lang.Object

{

    public void parentMethod()

    {

        System.out.println("Printing from the parent.");

    }

}


If you create a class ChildOne that extends ParentClass, ChildOne will take over all that code:
ZekeDragon created this ChildOne class:

class ChildOne [B]extends ParentClass[/B]

{

    public void childOneMethod()

    {

        System.out.println("Printing from child one.");

    }

}

It extends ParentClass, so you could actually see it as:

class ChildOne [strike][B][COLOR="red"]extends ParentClass[/COLOR][/B][/strike]

{

    public void childOneMethod()

    {

        System.out.println("Printing from child one.");

    }


    [B][COLOR="blue"]public void parentMethod()

    {

        System.out.println("Printing from the parent.");

    }[/COLOR][/B]

}


That makes it pretty normal that if you do one.parentMethod(), it will display "printing from the parent"

ChildOne one = new ChildOne();

one.parentMethod();


OUTPUT:

Printing from the parent


And then we got ChildTwo, defined as:

class ChildTwo extends ParentClass

{

    public void childTwoMethod()

    {

        System.out.println("Printing from child two.");

    }


    public void parentMethod()

    {

        childTwoMethod();

    }

}

Which, as ZekeDragon mentioned has 'Overridden' the parentMethod(). It's common to also have an annotation there to make it more clear, like followed:

class ChildTwo extends ParentClass

{

    public void childTwoMethod()

    {

        System.out.println("Printing from child two.");

    }


    [B]@Override[/B]

    public void parentMethod()

    {

        childTwoMethod();

    }

}

That annotation doesn't really change anything, it just makes it more clear for the user so he/she knows that method is overridden.

Now, just like ChildOne, this ChildTwo extends, takes over, all the ParentClass' code, So you could see it as:

class ChildTwo [B][COLOR="red"][strike]extends ParentClass[/strike][/COLOR][/B]

{

    public void childTwoMethod()

    {

        System.out.println("Printing from child two.");

    }


    public void parentMethod()

    {

        childTwoMethod();

    }


    [B][COLOR="blue"]public void parentMethod()

    {

        System.out.println("Printing from the parent.");

    }[/COLOR][/B]

}

Now, you see there is a conflict there, ChildTwo now has 2 methods with the same name and parameters: parentMethod().
Because parentMethod is declared in both classes, Java will use the "lowest" (okay, can't find a better word than 'lowest') one, and ignore the parentMethod from ParentClass.
So actually you can see "overriding" as "overwriting".

In the end ChildTwo looks like:

class ChildTwo [B][COLOR="red"][strike]extends ParentClass[/strike][/COLOR][/B]

{

    public void childTwoMethod()

    {

        System.out.println("Printing from child two.");

    }


    public void parentMethod()

    {

        childTwoMethod();

    }

}

With only his own parentMethod.

I hope it nows makes more sence that

ChildTwo two = new ChildTwo();

two .parentMethod();

outputs:

OUTPUT:

Printing from child two.



-------------------------------------------------------------------------


Now, you see that when I created my objects, I used the same class both Left and Right Where ZekeDragon used ParentClass left.

me:

ChildOne one = new ChildOne();

ZekeDragon:

ParentClass one = new ChildOne();

And both code worked.

The difference lies in the availability of the methods.
While me and ZekeDragon's 'one' object, both are actually ChildOne objects. ZekeDragon can only use it as if it was an object of ParentClass.
Which means, that I would have access to

    public void childOneMethod()

    {

        System.out.println("Printing from child one.");

    }

And ZekeDragon can't access that one, because it's declared as a ParentClass object.


ChildOne one = new ChildOne();

ParentClass one2 = new ChildOn();


one.childOneMethod(); //No problem here

one2.childOneMethod(); //Big problem here



#12
scottbomb

scottbomb

    Newbie

  • Members
  • PipPip
  • 21 posts
Excellent, thanks again! You guys are great.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users