About Question enthuware.ocajp.i.v7.2.1198 :

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

Post Reply
UmairAhmed
Posts: 9
Joined: Mon Apr 28, 2014 9:16 am
Contact:

About Question enthuware.ocajp.i.v7.2.1198 :

Post by UmairAhmed »

Hi,

Need your urgent help if you can :idea:
class CorbaComponent{
String ior;
CorbaComponent(){ startUp("IOR"); }
void startUp(String s){ ior = s; }
void print(){ System.out.println(ior); }
}

class OrderManager extends CorbaComponent{
OrderManager(){ }
void startUp(String s){ ior = getIORFromURL(s); }
String getIORFromURL(String s){ return "URL://"+s; }
}

public class Application{
public static void main(String args[]){ start(new OrderManager()); }
static void start(CorbaComponent cc){ cc.print(); }
}
The instance variable has been initialized with the value URL:// IOR ... but after that I couldn't get this
static void start(CorbaComponent cc){ cc.print(); }
method start() has been called with and reference of OrderManager object has been passed to it as an argument. Right ? So
start(CorbaComponent cc)
, i mean how CorbaManager reference is passed , what am i missing here.

Can you please explain how it went further processing after the method Start() is called from main method.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

Code: Select all

public static void main(String args[]){ 
 start(new OrderManager()); <--------- OrderManager IS-A CorbaComponent because it extends CorbaComponent therefore this actually invokes the static start(CorbaComponent cc) below

}

static void start(CorbaComponent cc){  <------- This method is invoked from main
 cc.print(); 
}
HTH,
Paul.
If you like our products and services, please help us by posting your review here.

heleneshaikh
Posts: 24
Joined: Wed Sep 02, 2015 3:43 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by heleneshaikh »

Hello,

Am I right about the order of execution? For some reason, my compiler doesn't go through every step. Thank you very much in advance.

class CorbaComponent{
String ior;
CorbaComponent(){ startUp("IOR"); } //3
void startUp(String s){ ior = s; }
void print(){ System.out.println(ior); } //8
}

class OrderManager extends CorbaComponent{
OrderManager(){ } //2
void startUp(String s){ ior = getIORFromURL(s); } //4 (overridden method)
String getIORFromURL(String s){ return "URL://"+s; } //5
}

public class Ape {
public Ape() { //1
}

public static void main(String[] args) {
start(new OrderManager()); } //6

static void start(CorbaComponent cc){ cc.print(); } //7
}

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

You will need to add extra print statements and run the program to see which line is being printed first.
If you like our products and services, please help us by posting your review here.

heleneshaikh
Posts: 24
Joined: Wed Sep 02, 2015 3:43 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by heleneshaikh »

Thanks for the tip, everything's clear!

Kevin30
Posts: 28
Joined: Sun Oct 25, 2015 10:14 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by Kevin30 »

Hi,

I still don't get it. Please help.

So, the code is:

Code: Select all

class CorbaComponent{
    String ior;
    CorbaComponent(){ startUp("IOR"); }
    void startUp(String s){ ior  =  s; }
    void print(){ System.out.println(ior); }
}

class OrderManager extends CorbaComponent{
   OrderManager(){  }
   void startUp(String s){  ior = getIORFromURL(s);   }
   String getIORFromURL(String s){  return "URL://"+s; }
}

public class Application{
   public static void main(String args[]){ start(new OrderManager()); }
   static void start(CorbaComponent cc){ cc.print(); }
}
I understand that in method in the main-method, the method start() is called and a new reference-variable cc is created in method start():
Corbacomponent cc = new OrderManager();

I also understand that in overridden methods, such as cc.print(), the compiler first checks if the class from the reference-variable has this method [answer: yes, class CorbaComponent has a method print()]. And second, that the actual method that gets executed in runtime is on the basis of the method of the object [and yes, class OrderManager also has a method print() because it inherits it from the class CorbaComponent].

However, before we get get to overridden method cc.print(), first some other things happen:

So, starting at the beginning, you start in the main-method where 'new OrderManager()' is a call to the construct of class Ordermanager. This, in turn, calls its superclass-constructor CorbaComponent(). There, method startUp() is called and String "IOR" is passed as argument. So far, it is clear.

Here is where I get confused. We are now in class CorbaComponent so I would think that therefore "IOR" gets passed to 'String s' in method startUp in class CorbaComponent. I don't see why OrderManager's startUp() is called.

Your words are: "The method selection is done on the basis of the actual class of the object (which is OrderManager here)." when deciding which method is called with "IOR" as parameter - CorbaComponent's startUp or OrderManager's startUp.

But in my view, what happens with String "IOR" in method startUp() has nothing to do with object cc that is created in method start() [which is even a different method from startUp] and also has nothing to do with the polymorphism that happens with cc.print(). So basically I don't see why String s = "IOR" is treated polymorphically.

Can you please explain why I am wrong, or what I am missing?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

You need to understand the execution of the main method step by step -
public static void main(String args[]){
start(new OrderManager());
}
Before the static start method of Application class can be invoked, the JVM has to create an OrderManager object because of the call to "new OrderManager()" as an argument to the start method.

1. When you do new OrderManager();, the constructor of OrderManager invokes super class's constructor. ( If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. )
2. The super class's constructor i.e. CorbaComponent's constructor contains a call to method startUp("IOR");
3. Since the object's actual class is OrderManager, the JVM invokes startUp method of OrderManager instead of CorbaComponent.
4. OrderManager's startUp calls ior = getIORFromURL(s);

Now, once the OrderManager is created, the JVM invokes Application's start method and passes the reference of the OrderManager object created above. The start method then invokes print on this OrderManager object, which prints the value of ior .
If you like our products and services, please help us by posting your review here.

Kevin30
Posts: 28
Joined: Sun Oct 25, 2015 10:14 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by Kevin30 »

Thank you for your explanation! I understand it now.

maltine
Posts: 2
Joined: Wed Jul 08, 2020 8:12 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by maltine »

It's so wird how the object can use the OrderManager startUp() from the super class CorbaComponent constructor. :?

enthunoob
Posts: 60
Joined: Thu Apr 15, 2021 12:21 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by enthunoob »

I'm confused how it even compiles as a sub-object is passed when the argument type is of the parent class. Why is a typecast not necessary here?

Code: Select all

public class Application{
   public static void main(String args[]){ start(new OrderManager()); }
   static void start(CorbaComponent cc){ cc.print(); }
}
For example:

public class Application{
   public static void main(String args[]){ start((CorbaComponent) new OrderManager()); }
   static void start(CorbaComponent cc){ cc.print(); }
}
Is my following assumption correct: it is only needed if a parent class is passed as an argument and the receiving method is expecting a child class.

For example:

Code: Select all

public class Application{
   public static void main(String args[]){ start((OrderManager) new CorbaComponent()); }
   static void start(OrderManager cc){ cc.print(); }
}
Last edited by admin on Thu Apr 15, 2021 10:30 pm, edited 1 time in total.
Reason: Added [code] [/code] to format code

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

You can always pass a subclass obj wherever a superclass object is needed without any cast. That's the basic building block of polymorphism. Think of it like this - if you need a Food, you will be ok if you are given Bread or Rice because you don't care what type of Food you get as long as it is Food.

Similarly, in the above code, if a method expect to receive a CorbaComponent, any object of type CorbaComponent will do include OrderManager because OrderManager is-a CorbaComponent.

Since this is such a fundamental aspect of OOP, I would suggest you to go through a good book first before attempting mock exams.
If you like our products and services, please help us by posting your review here.

enthunoob
Posts: 60
Joined: Thu Apr 15, 2021 12:21 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by enthunoob »

Thanks for the reply. I did a bit more study on it, and as a beginner I would like to share my findings/what caused the confusion for me.

Main points:
- up-and downcasting IS NOT CHANGING the object. The object itself STAYS whatever it was instantiated as. When object is instantiated as Rice, it stays of Rice type, even if it is upcasted to Food-type. As it is not possible to CHANGE the object itself, for example Food f = new Food(); can NOT be downcasted to a Rice.
- An object consists of an instantiated thing and a type. Two very different things (!!) that belong to every created object. Instantiated thing cant be changed/casted(!). Type can be. The type determines the accessibility of the methods. Type can be changed with casting.

So:
- upcasting is always possible and does not require a (Superclass)-cast. Food f = (Food) new Rice() --> (Food) is redundant here. (And actuallly, as you are also saying, upcasting is not really casting, cause any subclass object is already a type of the superclass object).
- you can never CHANGE an object itself. Even if an object is upcasted to the superclass, it will always STAY >the type< of the subclass. For example f.toString will print RiceClassName@somehexcode. (replace >the type< for >an instance< for less confusion)
- therefor it is also not possible to downcast a superclass to a (or any another) subclass of Food. For example Food f = new Food(); f = (Rice) f; will not compile or it will give a class cast exception. Rice is a type of food, but you can't change food into rice. food is instantiated as food. f can be Rice only if you create a new object (reference) for it. f = new Rice() would work. You can say Rice IS a Food thing, in human terms, so why can't I tell Java to change my Food object into a Rice object? That's just not how it works. Food stays food. The created object was of type Food. And not of type Rice. So downcasting is not applicable here.

It makes more sense when comparing to any other object in Java, try ---> Object o = new Object; String s = (String) o; --> This obviously won't work. It would mean that any object can be upcasted to type Object and then (if it wasn't another sub-object of Object yet) downcasted to any other type of object. An Object instantiated as Object stays an Object. Up- and downcasting only changes the accessibility of the methods, not the object itself. In the background, whatever it is up- or downcasted* to, the object stays what it was instantiated as. (*Note that downcasting of an instance of an Object is actually not possible.)

After all this, I think the term 'polymorphism'/many forms also confused me. Because with casting you are not creating more forms, but you are actually LIMITING the form of the object. As in Food f = new Rice(); still gives you a Rice object, but without acces to the methods of the Rice class. It is now of type Food so only those methods (methods of class Food) are accessible. The methods in the Rice class can not be accessed anymore (=limited). (Besides of course the methods in the Food class that the Rice class overrides, those are still accessible. Or better said: any overridden methods still belong to the superclass, even though the method declaration is written in a subclass.) And as a Food f = new Food cannot be downcasted to a type of Rice, it is not possible to let it temporarily have another form in order to have acces to more methods. So, in this logic, not really poly huh (hence my other confusion).

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

Thanks for sharing your thought process. Everyone has to make a mental model of a concept so that they can understand, remember, and apply it.
I am not evaluating and checking every statement that you have made for correctness but, in general, your model is quite good!
If you like our products and services, please help us by posting your review here.

baichen7788
Posts: 23
Joined: Fri Mar 26, 2021 7:25 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by baichen7788 »

the code fail to compile.
is it because OrderManager does not have print method?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

What does the error message say when you try to compile it?
If you like our products and services, please help us by posting your review here.

baichen7788
Posts: 23
Joined: Fri Mar 26, 2021 7:25 am
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by baichen7788 »

what about cc.print() method ?
Does the print() method do anything?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

Depends on the class of the object to which cc is pointing to.
If you like our products and services, please help us by posting your review here.

enthunoob
Posts: 60
Joined: Thu Apr 15, 2021 12:21 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by enthunoob »

After having read a good fundamentals book (sorry for above noobish question) I now concur with maltine above that it is weird that a super constructor can call a subclass overridden instance method when that subclass doesn't exist yet, as it's superclass did not even finish constructing yet. Thus, I assumed the method would not have been overridden yet and therefor that it would call the super classes instance method instead of the ('later overriding') subclasses method. However, ofcourse I should have known that overriding is done at compile time and that method instance calling is not dependent on whether an instance is already created or not.
Please let me know if I understood that correctly.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

Actually, the instance is created as well as initialized to default values even before the constructor is invoked (explained in Section 12.2.1 Object initialization revisited of the Fundamentals book). The constructor just gives the programmer an opportunity to initialize the values as per the business logic before the instance is made usable by the program.
So, the method is already overridden by the time the constructor is executed and so, when the super class's constructor tries to invoke a regular method, the subclass's version of that method is invoked.
If you like our products and services, please help us by posting your review here.

enthunoob
Posts: 60
Joined: Thu Apr 15, 2021 12:21 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by enthunoob »

the instance is created as well as initialized to default values even before the constructor is invoked. ... So, the method is already overridden by the time the constructor is executed
I don't remember coming across a section about the creation of the methods, only about the initialization order of static and instance fields, combined with sub and superclass (fe in section 9.3.4 Order of initialization summarized). Please note I mean to ask about the moment methods are 'created' (and/or overridden/hidden), not fields.

The book you are referring to is a different book then I read as section 12.2.1 is about StringBuilder. The one I read was written by Hanuman Deshmukh and called OCAJP Associate Java 8 Programmer Certification Fundamentals : 1z0-808, version 28. Which one are you referring from?

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

I was referring to Java 11 version of the book. In the Java 8 version (which you are referring to), please see section 9.3.1 Object initialization revisited.

Not sure what you mean by "when methods are 'created' (and/or overridden/hidden)".
Method are overridden when you define a subclass and write a method in the subclass with the same signature as the method in the super class. There is nothing like "creating a method". I mean, methods are not created in the way instances are created. At the most, you can say a method is created when you write its code in the java file for that class.
If you like our products and services, please help us by posting your review here.

admin
Site Admin
Posts: 10036
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by admin »

Just in case you are coming from a language such as Dart, where methods of a class are first class objects, then this is not how it is in Java. In Java, methods are not independent objects, which can be created or destroyed at will. Methods are mere code instructions associated with any given class. At the most, you can think that they are created when the class is loaded.
If you like our products and services, please help us by posting your review here.

tangjm
Posts: 5
Joined: Mon Jan 17, 2022 12:32 pm
Contact:

Re: About Question enthuware.ocajp.i.v7.2.1198 :

Post by tangjm »

I guess what's puzzling about this case is how polymorphism applies when no instance has finished being created. When the 'startUp' method is invoked, we're still in the process of initialising both the superclass and subclass. I was thinking about what the reference of the implicit 'this' could be in the context of the superclass constructor and whether it could shed some light on this puzzle. As an aside, what does 'this' actually denote? The instance of the CorbaComponent being created? The instance of the OrderManager that's being created? But, in the end, I realised this couldn't make a difference due to polymorphism.

Post Reply

Who is online

Users browsing this forum: No registered users and 30 guests