Why is dynamic polymorphism so useful?

Discussion in 'Java' started by failure_to@yahoo.co.uk, Dec 26, 2007.

  1. Guest

    hello

    1) With dynamic polymorphism, calls to actual methods are resolved at
    run time. So why is that so important? Why is that so much better
    than letting the compiler figure out which version of method to call
    ( based on the type of object being referred by reference variable )?
    Result would still be the same ... if superclass variable referred to
    child class object, then method of child class object would be
    called!

    2) Why isn't polymorphism also enabled for resolving calls to static
    methods? Wouldn't there be some benefits by allowing that?

    thank you
    , Dec 26, 2007
    #1
    1. Advertising

  2. wrote:
    > 1) With dynamic polymorphism, calls to actual methods are resolved at
    > run time. So why is that so important? Why is that so much better
    > than letting the compiler figure out which version of method to call
    > ( based on the type of object being referred by reference variable )?
    > Result would still be the same ... if superclass variable referred to
    > child class object, then method of child class object would be
    > called!


    > 2) Why isn't polymorphism also enabled for resolving calls to static
    > methods? Wouldn't there be some benefits by allowing that?


    These questions are, in the most literal meaning of the word, nonsense.
    Try starting over with a better textbook, because the one you're
    learning from isn't working. Honestly, I'm not trying to blow you off,
    but your misunderstanding of the situation is so severe that I'd have to
    write ten or twenty pages to create an answer for you -- and I'm not a
    teacher.
    --
    John W. Kennedy
    "The bright critics assembled in this volume will doubtless show, in
    their sophisticated and ingenious new ways, that, just as /Pooh/ is
    suffused with humanism, our humanism itself, at this late date, has
    become full of /Pooh./"
    -- Frederick Crews. "Postmodern Pooh", Preface
    John W. Kennedy, Dec 26, 2007
    #2
    1. Advertising

  3. Lew Guest

    wrote:
    > hello
    >
    > 1) With dynamic polymorphism, calls to actual methods are resolved at
    > run time. So why is that so important? Why is that so much better
    > than letting the compiler figure out which version of method to call
    > ( based on the type of object being referred by reference variable )?
    > Result would still be the same ... if superclass variable referred to
    > child class object, then method of child class object would be
    > called!


    Actually, not, because at compile time the actual type of the object isn't known.

    Look at it this way, there are two things in a program that have types: the
    variable and the object. Variables have compile-time type, objects have
    run-time type. Variables have scope, objects have lifetimes. A variable can
    go out of scope and disappear, but the object to which it pointed will live on.

    Classic example:

    List <String> messages = new ArrayList <String> ();

    The variable 'messages' has only the compile-time type List <String>. Thus it
    only can invoke methods known to the interface.

    The actual object has a run-time type of ArrayList. This can change during
    the program's lifetime:

    later:
    messages = new TreeList <String> ();

    Now the run-time of the object has changed, perhaps in response to some
    condition that doesn't always happen.

    The compile-time type remains List. No way the compiler can know ahead of
    time that at certain times the dispatch for add() will have to follow a
    different logic path. That happens through the object, not the variable, at
    run time, not compile time.

    > 2) Why isn't polymorphism also enabled for resolving calls to static
    > methods? Wouldn't there be some benefits by allowing that?


    I don't remember them off the top of my head, perhaps it was from the Java
    Language Specification (JLS) itself, but there are explanations you can
    quickly google up.

    My take on it is that you need an object to dispatch through, because it
    depends on run-time type. There is no object, nor run-time type to a class -
    a class is a class. All right, there is a kind of "object", but it's not at
    all the same kind as the Java language means by an "object".

    The class thing carries a bunch of information that pertain to that class.
    There's nothing to dispatch through - no change in a class's state that says,
    "OK, now we dispatch a method" - because there is no object of a subtype to
    say, "Use my stuff." There's just the class, itself.

    So you call a static method Foo.doGlobalThing() - based on what would you say,
    "dispatch to a subtype"? Nothing, that's what. You have to call the
    doGlobalThing() in the Foo class - you can't know what subtype might be
    intended. The notion of an override has no referent, therefore no meaning.

    --
    Lew
    Lew, Dec 26, 2007
    #3
  4. Roedy Green Guest

    On Tue, 25 Dec 2007 17:26:08 -0800 (PST),
    wrote, quoted or indirectly quoted someone who said :

    >1) With dynamic polymorphism, calls to actual methods are resolved at
    >run time. So why is that so important? Why is that so much better
    >than letting the compiler figure out which version of method to call
    >( based on the type of object being referred by reference variable )?
    >Result would still be the same ... if superclass variable referred to
    >child class object, then method of child class object would be
    >called!


    You can get a more accurate match. If a reference is an Object but
    the object itself is a Rabbit, you can get the specialised Rabbit
    method. Java does not know to use the specialised Rabbit method at
    compile time.

    There is extra overhead for runtime matching. Even without it, you
    can in your general method look for special cases and dispatch them to
    more special methods. To me, the problem does not come up often
    enough for it to be worth the overhead.

    Over time that tradeoff my change. Lots of thing we would not dream
    of doing before for programmer convenience become necessities with
    sufficient RAM and CPU power.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Dec 26, 2007
    #4
  5. Roedy Green Guest

    On Tue, 25 Dec 2007 17:26:08 -0800 (PST),
    wrote, quoted or indirectly quoted someone who said :

    >2) Why isn't polymorphism also enabled for resolving calls to static
    >methods? Wouldn't there be some benefits by allowing that?


    You would need a reference that could refer to several different
    class methods. That sounds a lot like a standard object pointer. So
    we are right back to ordinary instance methods.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Dec 26, 2007
    #5
  6. Eric Sosman Guest

    wrote:
    > hello
    >
    > 1) With dynamic polymorphism, calls to actual methods are resolved at
    > run time. So why is that so important? Why is that so much better
    > than letting the compiler figure out which version of method to call
    > ( based on the type of object being referred by reference variable )?
    > Result would still be the same ... if superclass variable referred to
    > child class object, then method of child class object would be
    > called!


    Please explain how the compiler can figure out which class'
    method to call in

    Number n = (Math.random() < 0.5)
    ? new Integer(42) : new Double(42.0);
    String s = n.toString(); // Integer's toString, or Double's?

    > 2) Why isn't polymorphism also enabled for resolving calls to static
    > methods? Wouldn't there be some benefits by allowing that?


    When calling a static method, what is the `this' object whose
    actual nature would determine the method to be called?

    --
    Eric Sosman
    lid
    Eric Sosman, Dec 26, 2007
    #6
  7. Wayne Guest

    Eric Sosman wrote:
    > Please explain how the compiler can figure out which class'
    > method to call in
    >
    > Number n = (Math.random() < 0.5)
    > ? new Integer(42) : new Double(42.0);
    > String s = n.toString(); // Integer's toString, or Double's?
    >


    The best way to learn is to write programs and examine the results.
    Here I created foo.java:

    class foo {
    public static void main (String[]args) {
    Number n = (Math.random() < 0.5)
    ? new Integer(42) : new Double(42.0);
    String s = n.toString();
    }
    }

    Compiled with "javac foo.java", then running "javap -s -c foo"
    produces:

    Compiled from "foo.java"
    class foo extends java.lang.Object{
    foo();
    Signature: ()V
    Code:
    0: aload_0
    1: invokespecial #1; //Method java/lang/Object."<init>":()V
    4: return

    public static void main(java.lang.String[]);
    Signature: ([Ljava/lang/String;)V
    Code:
    0: invokestatic #2; //Method java/lang/Math.random:()D
    3: ldc2_w #3; //double 0.5d
    6: dcmpg
    7: ifge 26
    10: new #5; //class java/lang/Integer
    13: dup
    14: bipush 42
    16: invokespecial #6; //Method java/lang/Integer."<init>":(I)V
    19: invokevirtual #7; //Method java/lang/Integer.intValue:()I
    22: i2d
    23: goto 39
    26: new #8; //class java/lang/Double
    29: dup
    30: ldc2_w #9; //double 42.0d
    33: invokespecial #11; //Method java/lang/Double."<init>":(D)V
    36: invokevirtual #12; //Method java/lang/Double.doubleValue:()D
    39: invokestatic #13; //Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
    42: astore_1
    43: aload_1
    44: invokevirtual #14; //Method java/lang/Object.toString:()Ljava/lang/String;
    47: astore_2
    48: return

    }

    ===================================================

    Even if you don't understand all of the JVM instructions you should be
    able to follow this code: call Math.random, compare the result to 0.5,
    if less then create a new Integer (lines 10-23), else create a new
    Double (lines 26-38). The value is converted to a String in lines 39-47.
    It should be clear from line 39 the type of the expression you questioned
    is...irrelevant! Note the "i2d" instruction on line 22. The compiler
    is pulling the primitive int from the Integer (line 19), converting to a
    double (line 22). On the other hand, if a Double is created, its value
    is extracted to a primitive (line 36).

    Then in either case a third object, a Double, is created from that
    double (line 39). However the compiler invokes Object.toString, not
    Double.toString (line 44) for reasons that elude me; perhaps an
    optimizing compiler would use the more specific method.

    When in doubt you can check the JVM specs (2nd ed is available
    on-line). Playing around like this is a terrific way to learn.

    >
    > When calling a static method, what is the `this' object whose
    > actual nature would determine the method to be called?
    >


    The keyword "this" is normally bound to the Object reference the
    method is invoked on. But for static methods, "this" keyword isn't
    set at all and can't be used.

    A mental model can simplify your thinking here (even if it is incorrect).
    Every class is represented by an Object, created in a special way by the
    ClassLoader, of type java.lang.Class. You can think of any methods
    and fields declared as static as methods and fields of that class Object
    (again, that's not really correct). Thus, when you create a class Foo
    and some Foo objects you also have a Class object named "Foo", where
    the system keeps the Foo class static fields (a.k.a. "class variables")
    and methods, along with the ability to create objects of type Foo.
    So when you invoke a static method the "this" reference, if it existed,
    would not refer to any Foo type object but rather to the Class object
    named Foo. Thus such a method has access to static fields and other
    static methods, but this Class object named Foo doesn't contain any
    instance methods or fields. (This mental model is too simple to
    explain how it really works but it should help with understanding
    this one aspect of static versus instance. Please don't shoot me.)

    Consider the method main: when starting the JVM, you specify a
    class, not a class and method. The JVM will create the Class
    object for the specified class but no other objects. So only
    a static method could be invoked at that time, which is why
    the main method must be static.

    While some languages only have (the equivalent of) instance fields
    and methods, Java provides you the choice. The annoying part
    is that Java uses the same operator to access static and instance
    fields and methods leading to some confusion. No doubt keeping
    the number of operators low(er) made the compilers easier to write.

    So if you want per-object properties use instance variables ("fields").
    If you want single "global" or "shared" properties use static
    variables (or fields). If you want polymorphism use instance methods.
    If you don't and you don't need access to instance fields, use
    static methods.

    >From your post I'm guessing you question the wisdom of providing

    non-polymorphic methods. You are not alone but personally I often
    find them useful, especially for collections of "utility" methods
    that don't need access to any instance fields. (Take a look at the
    utility classes in java.lang and java.util packages. You'll find
    most of the methods of these classes are declared static.)

    Hope this helps!

    -Wayne
    Wayne, Dec 26, 2007
    #7
  8. Wayne <> writes:

    > The best way to learn is to write programs and examine the results.
    > Here I created foo.java:
    >
    > class foo {
    > public static void main (String[]args) {
    > Number n = (Math.random() < 0.5)
    > ? new Integer(42) : new Double(42.0);
    > String s = n.toString();
    > }
    > }
    >
    > Compiled with "javac foo.java", then running "javap -s -c foo"
    > produces:

    ....
    > Note the "i2d" instruction on line 22. The compiler
    > is pulling the primitive int from the Integer (line 19), converting to a
    > double (line 22). On the other hand, if a Double is created, its value
    > is extracted to a primitive (line 36).


    I can see that the conditional expression caused some unexpected coercions.
    Try this instead:

    Number n;
    if (Math.random() < 0.5) {
    n = new Integer(42):
    } else {
    n = new Double(42.0);
    }

    or perhaps just

    Number n = (Math.random() < 0.5) ? (Number) new Integer(42)
    : (Number) new Doubler(42.0);


    > Then in either case a third object, a Double, is created from that
    > double (line 39). However the compiler invokes Object.toString, not
    > Double.toString (line 44) for reasons that elude me; perhaps an
    > optimizing compiler would use the more specific method.


    It calls Object.toString virtually, because that is the most specific
    toString that exists on the Number class.

    It would be possible to optimize, if an analysis showed that only
    Double values would ever become that value of Number type
    variable. That analysis would have to be absolutely certain, even in
    the presence of multiple threads simultaneously fiddling with other
    object's fields using reflection. A mistake in the analysis would make
    it into the class file, and the JVM would have no chance of correcting
    it. That is why most optimizations are better left for the runtime
    HotSpot optimizer, since it can optimize based on what is actually
    happening, and can backtrack and use the unoptimized version if
    the optimziation enabling conditions change.

    In some cases (e.g., the example using "if" above), you can't know at
    compile time what type of object it will be, so no compiler optimization
    is possible.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Dec 26, 2007
    #8
  9. Mark Rafn Guest

    Homework? Hate to encourage posting your class questions, but these come up
    occasionally to non-school seekers of language design.

    <> wrote:
    >1) With dynamic polymorphism, calls to actual methods are resolved at
    >run time. So why is that so important? Why is that so much better
    >than letting the compiler figure out which version of method to call
    >( based on the type of object being referred by reference variable )?


    1a) Because the compiler cannot know what the runtime environment will be, and
    what class implementations will be loaded.

    1b) The compiler DOES decide this. Not the java->bytecode compiler, but the
    bytecode->machine just-in-time compiler that implements the runtime. And it
    re-decides as things change.

    >Result would still be the same ... if superclass variable referred to
    >child class object, then method of child class object would be
    >called!


    It can change between compiliation and runtime. Heck, it can change during
    runtime.

    >2) Why isn't polymorphism also enabled for resolving calls to static
    >methods? Wouldn't there be some benefits by allowing that?


    How would it work? Static methods have no object reference, so there are
    never multiple different possibilities.
    --
    Mark Rafn <http://www.dagon.net/>
    Mark Rafn, Dec 26, 2007
    #9
  10. Lew Guest

    Lasse Reichstein Nielsen wrote:
    > Wayne <> writes:
    >
    >> The best way to learn is to write programs and examine the results.
    >> Here I created foo.java:
    >>
    >> class foo {
    >> public static void main (String[]args) {
    >> Number n = (Math.random() < 0.5)
    >> ? new Integer(42) : new Double(42.0);
    >> String s = n.toString();
    >> }
    >> }
    >>
    >> Compiled with "javac foo.java", then running "javap -s -c foo"
    >> produces:

    > ....
    >> Note the "i2d" instruction on line 22. The compiler
    >> is pulling the primitive int from the Integer (line 19), converting to a
    >> double (line 22). On the other hand, if a Double is created, its value
    >> is extracted to a primitive (line 36).

    >
    > I can see that the conditional expression caused some unexpected coercions.
    > Try this instead:
    >
    > Number n;
    > if (Math.random() < 0.5) {
    > n = new Integer(42):
    > } else {
    > n = new Double(42.0);
    > }
    >
    > or perhaps just
    >
    > Number n = (Math.random() < 0.5) ? (Number) new Integer(42)
    > : (Number) new Doubler(42.0);
    >


    The important point being that the compiler can have no way of knowing which
    result will pertain at run time. No need to read assembler for that; it's
    plenty clear from just the Java code.

    --
    Lew
    Lew, Dec 26, 2007
    #10
  11. Wayne Guest

    Lew wrote:
    > Lasse Reichstein Nielsen wrote:
    >> Wayne <> writes:
    >>
    >>> The best way to learn is to write programs and examine the results.
    >>> Here I created foo.java:
    >>>
    >>> class foo {
    >>> public static void main (String[]args) {
    >>> Number n = (Math.random() < 0.5)
    >>> ? new Integer(42) : new Double(42.0);
    >>> String s = n.toString();
    >>> }
    >>> }
    >>>
    >>> Compiled with "javac foo.java", then running "javap -s -c foo"
    >>> produces:

    >> ....
    >>> Note the "i2d" instruction on line 22. The compiler
    >>> is pulling the primitive int from the Integer (line 19), converting to a
    >>> double (line 22). On the other hand, if a Double is created, its value
    >>> is extracted to a primitive (line 36).

    >>
    >> I can see that the conditional expression caused some unexpected
    >> coercions.
    >> Try this instead:
    >>
    >> Number n;
    >> if (Math.random() < 0.5) {
    >> n = new Integer(42): } else {
    >> n = new Double(42.0);
    >> }
    >>
    >> or perhaps just
    >>
    >> Number n = (Math.random() < 0.5) ? (Number) new Integer(42)
    >> : (Number) new Doubler(42.0);
    >>

    >
    > The important point being that the compiler can have no way of knowing
    > which result will pertain at run time. No need to read assembler for
    > that; it's plenty clear from just the Java code.
    >


    Hmm. Could someone post an SSCCE using standard Java classes,
    where the polymorphism shows in the output of javap? All my
    attempts at using toString result in Object.toString method
    being invoked.

    -Wayne
    Wayne, Dec 27, 2007
    #11
  12. Lew Guest

    Wayne wrote:
    > Hmm. Could someone post an SSCCE using standard Java classes,
    > where the polymorphism shows in the output of javap? All my
    > attempts at using toString result in Object.toString method
    > being invoked.


    Perhaps something like a Collection add() where the implementation is
    ArrayList or LinkedList or TreeSet or HashSet, chosen at runtime?

    --
    Lew
    Lew, Dec 27, 2007
    #12
  13. Wayne Guest

    Wayne wrote:
    > Hmm. Could someone post an SSCCE using standard Java classes,
    > where the polymorphism shows in the output of javap? All my
    > attempts at using toString result in Object.toString method
    > being invoked.


    Or perhaps even better, is there a freely available debugger
    (say in Netbeans or Eclipse) that can display an object's
    vtable (or whatever its called in Java)? And to save me
    hours of learning what is that debugger's command(s) to
    do that?

    -Wayne
    Wayne, Dec 27, 2007
    #13
  14. Guest

    hello


    On Dec 27, 12:08 am, (Mark Rafn) wrote:
    > Homework? Hate to encourage posting your class questions, but these come up
    > occasionally to non-school seekers of language design.
    >
    > Mark Rafn <http://www.dagon.net/>


    Chances are you prob won't read this post, but still...

    I'd appreciate if you don't assume too much about the nature of my
    questions since people on this forum may start to believe you and
    decide not to help me and then I'm f*****. At least this way I can
    get a fair chance of getting people to help me when I can't figure out
    the stuff on my own. Try to see this from my perspective

    BTW-I'm not in any school and thus I'm learning programming by myself
    and for myself, and if I get stuck on some topic, this group is my
    best chance ( contrary to your belief, I don't have a professor I can
    run to for help )

    I hope I haven't offend you with my little rant, since that wasn't my
    intention


    thank you all for your kind help

    cheers
    , Dec 27, 2007
    #14
  15. Mark Rafn Guest

    >On Dec 27, 12:08 am, (Mark Rafn) wrote:
    >> Homework? Hate to encourage posting your class questions, but these come up
    >> occasionally to non-school seekers of language design.


    <> wrote:
    >Chances are you prob won't read this post, but still...
    >I'd appreciate if you don't assume too much about the nature of my


    I usually read direct followups to my posts. I didn't mean any offense,
    and I did, in fact, both state that it might not be homework AND give my
    answer. Mostly I wanted to let folks know that it might NOT be homework, to
    avoid the common "we don't answer homework" one-liners...

    Anyway, what did you think of the answers? Make sense? Raise other
    questions?
    --
    Mark Rafn <http://www.dagon.net/>
    Mark Rafn, Dec 28, 2007
    #15
  16. Lew Guest

    wrote:
    > At least this way I can
    > get a fair chance of getting people to help me when I can't figure out
    > the stuff on my own. Try to see this from my perspective


    You will note that your post got many useful answers by several people who
    made no overt assumptions about your purpose.

    --
    Lew
    Lew, Dec 28, 2007
    #16
  17. Guest

    hello


    * I must first point out that I realize ( even when I first started
    this thread ) that with the help of polymorphism we can get a generic
    interface and thus don¡¦t have to change a code when new subclass is
    introduced!




    1) Now what is most bugging me about polymorphism is the following:

    I also realize, that with polymorphism we can run a program and while
    program is already running, we can introduce a totally new class ( let
    us call this new class N_C ) and thanx to polymorphism this program
    may operate on instances of N_C without the need to recompile or even
    without the need to restart this program.


    But how to write a code for this program in such flexible way that
    program will KNOW that new class is present and operate on it is
    beyond me. Let me explain what I mean:

    Say we have superclass A and bunch of subclasses ( all of them
    override A¡¦s method a1() ). Now somewhere in this program is a code
    that calls a1() via reference variable ref_var:

    * A ref_var; // here we define ref_var

    * At some point in a program we assign to ref_var a reference to some
    object ( this object might be of class type A or one of its
    subclasses )

    *then we call ref_var.a1(); // which method to actually call is
    resolved at runtime


    Say we start this app and while app is already running, we write a new
    class called N_C.
    The already running app has to be flexible enough to enable an object
    of type N_C not only to be added to running app ( without even
    restarting this app ), but to actually use this object.
    But how do we do that? Let me explain it further:


    Say this running app has an object of type B, where B is subclass of
    A, and if I want ref_var to reference this object, then I do this by
    writing in program code the following line:

    B b = new B():
    ref_var = b;

    The above lines are hard coded into program. But how do we assign
    ref_var a reference to object of type N_C, if we introduce this new
    class to already running app --> somewhere in the program code the
    following two lines would have to be written:

    N_C n_c = new N_C();
    ref_ver = n_c;

    But problem is app is already running and we don¡¦t want to stop this
    app to write the above two new lines and yet we want this app to
    somehow use this new object ( by assigning ref_var a reference to
    n_c ). Now how can assign ref_var a reference to object of type N_C
    without adding the above two lines into code ?






    >
    > Anyway, what did you think of the answers? Make sense? Raise other
    > questions?
    > --
    > Mark Rafn <http://www.dagon.net/>


    Perhaps I shouldn't say this, cos you went through so much trouble in
    order to help me, but truth be told questions were a bit too technical
    for me and even if I did somewhat understand what ( some of ) you were
    saying, I didn¡¦t understand why would arguments you provided prove
    anything ( at least I didn¡¦t find them to prove anything, but then
    again, I'm not exactly ...). But I do know that in time ( when I get a
    bit better in programming ) these answers will be of great value



    I will give just a few examples:


    >> 1) With dynamic polymorphism, calls to actual methods are
    >> resolved at run time. So why is that so important? Why is that
    >> so much better than letting the compiler figure out which
    >> version of method to call

    >
    >> ( based on the type of object being referred by reference
    >> variable )?
    >> Result would still be the same ... if superclass variable
    >> referred to child class object, then method of child class
    >> object would be called!

    >
    >You can get a more accurate match. If a reference is an Object
    >but the object itself is a Rabbit, you can get the specialised
    >Rabbit method. Java does not know to use the specialised Rabbit
    >method at compile time.
    >


    Why couldn¡¦t java know at compile time what to do with rabbit method?
    Perhaps because creators of Java decided compiler doesn¡¦t have to know
    that, since, afteral, they were gonna implement dynamic binding, or is
    it in general not possible for compiler to know that, even if creators
    of Java wanted for compiler to know that?




    > Please explain how the compiler can figure out which class'
    > method to call in
    > Number n = (Math.random() < 0.5)
    > ? new Integer(42) : new Double(42.0);
    > String s = n.toString(); // Integer's toString, or Double's?
    >


    I don¡¦t understand how this proves anything? Perhaps if this was done
    at compile time, then internally ( I¡¦m talking out of my arse now )
    there could be another

    if ( n is integer then call n.toString(Integer n) )
    else ( else if n is double then call n.toString( Double n ) )

    statement that enable the compiler to "call" the appropriate method.




    >>
    >>Result would still be the same ... if superclass variable
    >>referred to child class object, then method of child class
    >>object would be called!

    >
    >It can change between compiliation and runtime. Heck, it can
    >change during runtime.
    >


    What can change?

    BTW - I do realize that compiler can¡¦t resolve method calls due to
    Java ability of introducing new classes to program ( without the need
    to recompile a program )„³ thus compiler has no way of knowing what
    classes may be added to program in the future ( the questions I
    originally asked ignored on purpose this Java ability )!


    uh
    , Dec 28, 2007
    #17
  18. Lew Guest

    wrote:
    > I also realize, that with polymorphism we can run a program and while
    > program is already running, we can introduce a totally new class ( let
    > us call this new class N_C ) and thanx to polymorphism this program
    > may operate on instances of N_C without the need to recompile or even
    > without the need to restart this program.
    >
    >
    > But how to write a code for this program in such flexible way that
    > program will KNOW that new class is present and operate on it is
    > beyond me.


    Java has basically three ways to accomplish this: classloaders, reflection and
    the debugger API.

    All three are advanced topics. Let me give just the briefest summary.

    Classloaders can be directed to reach out to a known source and load the
    bytecode for a class while the program is running.

    Reflection lets a program retrieve instances from classes not known until run
    time, perhaps ones that have been retrieved through a custom classloader.

    The debugger API has hooks that let a program substitute different class
    versions for each other while the program is running.

    Didn't catch who said:
    >> You can get a more accurate match. If a reference is an Object
    >> but the object itself is a Rabbit, you can get the specialised
    >> Rabbit method. Java does not know to use the specialised Rabbit
    >> method at compile time.


    wrote:
    > Why couldn’t java know at compile time what to do with rabbit method?


    That's "Java", not "java".

    This was explained a few times in this thread. It's not what "Java" knows,
    it's what the variable type is, that determines what methods the variable can
    call. Remember from upthread that variables have compile-time type, objects
    have run-time type.

    > Perhaps because creators of Java decided compiler doesn’t have to know
    > that, since, afteral, they were gonna implement dynamic binding, or is
    > it in general not possible for compiler to know that, even if creators
    > of Java wanted for compiler to know that?


    No need to get religious - the creators of Java have nothing to do with this.

    Java is defined by a set of rules, and those rules determine the behavior.
    The key is to remember that variables have only compile-time type - objects
    have run-time type. The variable knows how to ask for something in the
    compile-time type, e.g., "x.run()" for a variable "x" of type "Runnable".
    Since there is no information in the compiler about the run-time type of the
    actual object, it is only valid to say that "x" calls its "run()" method. The
    actual object at run time will pick up the request for a "run()" and simply
    use its own method to do it. That's all.

    >> Please explain how the compiler can figure out which class'
    >> method to call in
    >> Number n = (Math.random() < 0.5)
    >> ? new Integer(42) : new Double(42.0);
    >> String s = n.toString(); // Integer's toString, or Double's?
    >>

    >
    > I don’t understand how this proves anything? Perhaps if this was done
    > at compile time, then internally ( I’m talking out of my arse now )
    > there could be another


    The whole point is that the compiler only knows that the variable 'n' is a
    'Number'. No more is needed, actually.

    At run time, the object will pick up the call to toString(), and use its own
    version of toString() to fulfill the call, is all.

    > if ( n is integer then call n.toString(Integer n) )
    > else ( else if n is double then call n.toString( Double n ) )


    No need for that when the object itself already knows how to toString()
    itself. It's called separation of concerns, and encapsulation. The calling
    method doesn't need to care about the details - it just trusts the object to
    call its own method on its own.

    > statement that enable the compiler to "call" the appropriate method.


    Compilers don't call methods, objects do. Compilers just tell the object
    which method to call.

    >>> Result would still be the same ... if superclass variable
    >>> referred to child class object, then method of child class
    >>> object would be called!


    How would a compiler know what object is in play in the future?

    >> It can change between compiliation and runtime. Heck, it can
    >> change during runtime.
    >>

    >
    > What can change?


    The object that is asked to perform the method can change.

    > BTW - I do realize that compiler can’t resolve method calls due to
    > Java ability of introducing new classes to program ( without the need
    > to recompile a program )迳 thus compiler has no way of knowing what
    > classes may be added to program in the future ( the questions I
    > originally asked ignored on purpose this Java ability )!


    This has nothing to do with polymorphism. Polymorphism is simply that the
    object decides for itself how to execute a method.

    --
    Lew
    Lew, Dec 29, 2007
    #18
  19. Patrick May Guest

    writes:
    > 1) Now what is most bugging me about polymorphism is the following:
    >
    > I also realize, that with polymorphism we can run a program and
    > while program is already running, we can introduce a totally new
    > class ( let us call this new class N_C ) and thanx to polymorphism
    > this program may operate on instances of N_C without the need to
    > recompile or even without the need to restart this program.
    >
    > But how to write a code for this program in such flexible way that
    > program will KNOW that new class is present and operate on it is
    > beyond me. Let me explain what I mean:


    Here's a simple example:

    http://www.spe.com/Chain_of_Responsibility.html

    Does that help?

    Regards,

    Patrick

    ------------------------------------------------------------------------
    S P Engineering, Inc. | Large scale, mission-critical, distributed OO
    | systems design and implementation.
    | (C++, Java, Common Lisp, Jini, middleware, SOA)
    Patrick May, Dec 29, 2007
    #19
  20. Tim Smith Guest

    In article <>,
    Lew <> wrote:
    > > I can see that the conditional expression caused some unexpected coercions.
    > > Try this instead:
    > >
    > > Number n;
    > > if (Math.random() < 0.5) {
    > > n = new Integer(42):
    > > } else {
    > > n = new Double(42.0);
    > > }
    > >
    > > or perhaps just
    > >
    > > Number n = (Math.random() < 0.5) ? (Number) new Integer(42)
    > > : (Number) new Doubler(42.0);
    > >

    >
    > The important point being that the compiler can have no way of knowing which
    > result will pertain at run time. No need to read assembler for that; it's
    > plenty clear from just the Java code.


    It depends on how sneaky the compiler wants to be. If it notices that
    this code is only called once, couldn't it generate the random number at
    compile time, and then just compile the appropriate branch?

    --
    --Tim Smith
    Tim Smith, Dec 30, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. blank
    Replies:
    7
    Views:
    769
    blank
    May 16, 2005
  2. Sebastian Faust
    Replies:
    0
    Views:
    357
    Sebastian Faust
    Oct 21, 2003
  3. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    875
    Mark Rae
    Dec 21, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,804
    Smokey Grindel
    Dec 2, 2006
  5. Krivenok Dmitry
    Replies:
    13
    Views:
    1,423
    Axter
    Jun 1, 2006
Loading...

Share This Page