Java Type System: Why do these assignments, method calls and type casts fail?












0














Let's say I have the following interface and classes defined:





public interface I { void a(); }

public class A implements I {
public void a() { System.out.println("A"); }
}

public class B implements I {
public void a() { System.out.println("B"); }
public void b() { System.out.println("C"); }
}


And then I run the following code:



public class Main {
public static void main(String args) {
A a = new A();
B b = new B();
I i;
i = a;
i.a(); // prints "A"
i = b;
i.a(); // prints "B"
i.b(); // 1st problem: i can't seem to find method b. Why?
b = i; // 2nd problem: b can't be assigned to i although i references an object of class B?
b = (B)i; // why does this work fine...
a = (A)i; // 3rd problem: ...but this here doesn't?
}
}


So here are my questions:



First Problem



Why can't i.b() be called?



i points to the same object as b, an object of class B which does have a method b.



So why does i.a() call the right method (the one that prints out "B") but i.b() doesn't resolve at all?



Does the fact that i was declared as being of type I (an interface) have anything to do with that? Does this mean that in an assignment X x = new Y() where Y extends X, one can only ever call methods on x that are already declared in X, and not just specific to Y?



Second Problem



Why can't b be assigned to i although i references an object of class B? b and i already reference the same object, don't they? So why does it cause an error if I try to assign b to i - the end result of which should be identical to the state of the program before that assignment, unless I'm missing something significant.



Third Problem



Why can I cast i to type B now although I couldn't assign b to i earlier, and why doesn't casting i to A work?



I'm assuming my confusion is somehow rooted in an unclear distinction between the reference variables and the objects they're referencing, as well as the differences between the types of these variables and objects. I just can't quite explain these occurrences - and in particular the first problem confuses me a lot.










share|improve this question





























    0














    Let's say I have the following interface and classes defined:





    public interface I { void a(); }

    public class A implements I {
    public void a() { System.out.println("A"); }
    }

    public class B implements I {
    public void a() { System.out.println("B"); }
    public void b() { System.out.println("C"); }
    }


    And then I run the following code:



    public class Main {
    public static void main(String args) {
    A a = new A();
    B b = new B();
    I i;
    i = a;
    i.a(); // prints "A"
    i = b;
    i.a(); // prints "B"
    i.b(); // 1st problem: i can't seem to find method b. Why?
    b = i; // 2nd problem: b can't be assigned to i although i references an object of class B?
    b = (B)i; // why does this work fine...
    a = (A)i; // 3rd problem: ...but this here doesn't?
    }
    }


    So here are my questions:



    First Problem



    Why can't i.b() be called?



    i points to the same object as b, an object of class B which does have a method b.



    So why does i.a() call the right method (the one that prints out "B") but i.b() doesn't resolve at all?



    Does the fact that i was declared as being of type I (an interface) have anything to do with that? Does this mean that in an assignment X x = new Y() where Y extends X, one can only ever call methods on x that are already declared in X, and not just specific to Y?



    Second Problem



    Why can't b be assigned to i although i references an object of class B? b and i already reference the same object, don't they? So why does it cause an error if I try to assign b to i - the end result of which should be identical to the state of the program before that assignment, unless I'm missing something significant.



    Third Problem



    Why can I cast i to type B now although I couldn't assign b to i earlier, and why doesn't casting i to A work?



    I'm assuming my confusion is somehow rooted in an unclear distinction between the reference variables and the objects they're referencing, as well as the differences between the types of these variables and objects. I just can't quite explain these occurrences - and in particular the first problem confuses me a lot.










    share|improve this question



























      0












      0








      0







      Let's say I have the following interface and classes defined:





      public interface I { void a(); }

      public class A implements I {
      public void a() { System.out.println("A"); }
      }

      public class B implements I {
      public void a() { System.out.println("B"); }
      public void b() { System.out.println("C"); }
      }


      And then I run the following code:



      public class Main {
      public static void main(String args) {
      A a = new A();
      B b = new B();
      I i;
      i = a;
      i.a(); // prints "A"
      i = b;
      i.a(); // prints "B"
      i.b(); // 1st problem: i can't seem to find method b. Why?
      b = i; // 2nd problem: b can't be assigned to i although i references an object of class B?
      b = (B)i; // why does this work fine...
      a = (A)i; // 3rd problem: ...but this here doesn't?
      }
      }


      So here are my questions:



      First Problem



      Why can't i.b() be called?



      i points to the same object as b, an object of class B which does have a method b.



      So why does i.a() call the right method (the one that prints out "B") but i.b() doesn't resolve at all?



      Does the fact that i was declared as being of type I (an interface) have anything to do with that? Does this mean that in an assignment X x = new Y() where Y extends X, one can only ever call methods on x that are already declared in X, and not just specific to Y?



      Second Problem



      Why can't b be assigned to i although i references an object of class B? b and i already reference the same object, don't they? So why does it cause an error if I try to assign b to i - the end result of which should be identical to the state of the program before that assignment, unless I'm missing something significant.



      Third Problem



      Why can I cast i to type B now although I couldn't assign b to i earlier, and why doesn't casting i to A work?



      I'm assuming my confusion is somehow rooted in an unclear distinction between the reference variables and the objects they're referencing, as well as the differences between the types of these variables and objects. I just can't quite explain these occurrences - and in particular the first problem confuses me a lot.










      share|improve this question















      Let's say I have the following interface and classes defined:





      public interface I { void a(); }

      public class A implements I {
      public void a() { System.out.println("A"); }
      }

      public class B implements I {
      public void a() { System.out.println("B"); }
      public void b() { System.out.println("C"); }
      }


      And then I run the following code:



      public class Main {
      public static void main(String args) {
      A a = new A();
      B b = new B();
      I i;
      i = a;
      i.a(); // prints "A"
      i = b;
      i.a(); // prints "B"
      i.b(); // 1st problem: i can't seem to find method b. Why?
      b = i; // 2nd problem: b can't be assigned to i although i references an object of class B?
      b = (B)i; // why does this work fine...
      a = (A)i; // 3rd problem: ...but this here doesn't?
      }
      }


      So here are my questions:



      First Problem



      Why can't i.b() be called?



      i points to the same object as b, an object of class B which does have a method b.



      So why does i.a() call the right method (the one that prints out "B") but i.b() doesn't resolve at all?



      Does the fact that i was declared as being of type I (an interface) have anything to do with that? Does this mean that in an assignment X x = new Y() where Y extends X, one can only ever call methods on x that are already declared in X, and not just specific to Y?



      Second Problem



      Why can't b be assigned to i although i references an object of class B? b and i already reference the same object, don't they? So why does it cause an error if I try to assign b to i - the end result of which should be identical to the state of the program before that assignment, unless I'm missing something significant.



      Third Problem



      Why can I cast i to type B now although I couldn't assign b to i earlier, and why doesn't casting i to A work?



      I'm assuming my confusion is somehow rooted in an unclear distinction between the reference variables and the objects they're referencing, as well as the differences between the types of these variables and objects. I just can't quite explain these occurrences - and in particular the first problem confuses me a lot.







      java types casting variable-assignment






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 at 11:56

























      asked Nov 12 at 11:45









      Chris Offner

      114




      114
























          3 Answers
          3






          active

          oldest

          votes


















          0














          For the first problem:
          You can use the interface reference to call only the methods it declares



          For the second problem:
          You can use interface reference to invoke methods in the classes that implement the interface. However, there is no use to assign interface reference to a class reference since interface reference doesn't have any methods that can be invoked.



          for the third problem:
          You have assigned previously



                  i=b 


          and hence



               b=(B)i 


          works fine.



          However,
          a=(A)i
          wouldn't work because i stores b and not a






          share|improve this answer































            0














            First of all, learn Java (and/or OO (object oriented)) programming...




            1. Variable i is a reference to an object instance that implements interface I. Method b() was not declared in interface I, thus it is not visible through i.b().

              To be able to call it, i needs to be casted, EG: ((B) i).b()

            2. Variable b is a reference to an object that is an instance of class B, and cannot be assigned to any reference that itself is not declared as an instance of B.

              Again, a cast needed, EG: b = (B) i

            3. Class B is not a child of class A. They both implement interface I, but A is not parent of B.






            share|improve this answer





















            • What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
              – Chris Offner
              Nov 12 at 12:48










            • Yes, it is an object, or an instance of a class...
              – Usagi Miyamoto
              Nov 12 at 14:08



















            0














            It's not a problem at all but It's behavior of inheritance and polimorphism.



            Please note that when you



            I i = new A();


            Left hand side (I) will tells compiler which all methods it can call using that reference.



            Right hand side (A) will tells the Runtime which method should execute using that method call



            So in your case



            1 Problem



            you can not call b() since b() is not there in inteface I



            2 Problem



            you are casting interface to object b and then calling b() so its working fine.






            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261487%2fjava-type-system-why-do-these-assignments-method-calls-and-type-casts-fail%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              For the first problem:
              You can use the interface reference to call only the methods it declares



              For the second problem:
              You can use interface reference to invoke methods in the classes that implement the interface. However, there is no use to assign interface reference to a class reference since interface reference doesn't have any methods that can be invoked.



              for the third problem:
              You have assigned previously



                      i=b 


              and hence



                   b=(B)i 


              works fine.



              However,
              a=(A)i
              wouldn't work because i stores b and not a






              share|improve this answer




























                0














                For the first problem:
                You can use the interface reference to call only the methods it declares



                For the second problem:
                You can use interface reference to invoke methods in the classes that implement the interface. However, there is no use to assign interface reference to a class reference since interface reference doesn't have any methods that can be invoked.



                for the third problem:
                You have assigned previously



                        i=b 


                and hence



                     b=(B)i 


                works fine.



                However,
                a=(A)i
                wouldn't work because i stores b and not a






                share|improve this answer


























                  0












                  0








                  0






                  For the first problem:
                  You can use the interface reference to call only the methods it declares



                  For the second problem:
                  You can use interface reference to invoke methods in the classes that implement the interface. However, there is no use to assign interface reference to a class reference since interface reference doesn't have any methods that can be invoked.



                  for the third problem:
                  You have assigned previously



                          i=b 


                  and hence



                       b=(B)i 


                  works fine.



                  However,
                  a=(A)i
                  wouldn't work because i stores b and not a






                  share|improve this answer














                  For the first problem:
                  You can use the interface reference to call only the methods it declares



                  For the second problem:
                  You can use interface reference to invoke methods in the classes that implement the interface. However, there is no use to assign interface reference to a class reference since interface reference doesn't have any methods that can be invoked.



                  for the third problem:
                  You have assigned previously



                          i=b 


                  and hence



                       b=(B)i 


                  works fine.



                  However,
                  a=(A)i
                  wouldn't work because i stores b and not a







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 12 at 12:09

























                  answered Nov 12 at 11:59









                  Mohan

                  348111




                  348111

























                      0














                      First of all, learn Java (and/or OO (object oriented)) programming...




                      1. Variable i is a reference to an object instance that implements interface I. Method b() was not declared in interface I, thus it is not visible through i.b().

                        To be able to call it, i needs to be casted, EG: ((B) i).b()

                      2. Variable b is a reference to an object that is an instance of class B, and cannot be assigned to any reference that itself is not declared as an instance of B.

                        Again, a cast needed, EG: b = (B) i

                      3. Class B is not a child of class A. They both implement interface I, but A is not parent of B.






                      share|improve this answer





















                      • What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
                        – Chris Offner
                        Nov 12 at 12:48










                      • Yes, it is an object, or an instance of a class...
                        – Usagi Miyamoto
                        Nov 12 at 14:08
















                      0














                      First of all, learn Java (and/or OO (object oriented)) programming...




                      1. Variable i is a reference to an object instance that implements interface I. Method b() was not declared in interface I, thus it is not visible through i.b().

                        To be able to call it, i needs to be casted, EG: ((B) i).b()

                      2. Variable b is a reference to an object that is an instance of class B, and cannot be assigned to any reference that itself is not declared as an instance of B.

                        Again, a cast needed, EG: b = (B) i

                      3. Class B is not a child of class A. They both implement interface I, but A is not parent of B.






                      share|improve this answer





















                      • What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
                        – Chris Offner
                        Nov 12 at 12:48










                      • Yes, it is an object, or an instance of a class...
                        – Usagi Miyamoto
                        Nov 12 at 14:08














                      0












                      0








                      0






                      First of all, learn Java (and/or OO (object oriented)) programming...




                      1. Variable i is a reference to an object instance that implements interface I. Method b() was not declared in interface I, thus it is not visible through i.b().

                        To be able to call it, i needs to be casted, EG: ((B) i).b()

                      2. Variable b is a reference to an object that is an instance of class B, and cannot be assigned to any reference that itself is not declared as an instance of B.

                        Again, a cast needed, EG: b = (B) i

                      3. Class B is not a child of class A. They both implement interface I, but A is not parent of B.






                      share|improve this answer












                      First of all, learn Java (and/or OO (object oriented)) programming...




                      1. Variable i is a reference to an object instance that implements interface I. Method b() was not declared in interface I, thus it is not visible through i.b().

                        To be able to call it, i needs to be casted, EG: ((B) i).b()

                      2. Variable b is a reference to an object that is an instance of class B, and cannot be assigned to any reference that itself is not declared as an instance of B.

                        Again, a cast needed, EG: b = (B) i

                      3. Class B is not a child of class A. They both implement interface I, but A is not parent of B.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 12 at 12:14









                      Usagi Miyamoto

                      4,34711024




                      4,34711024












                      • What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
                        – Chris Offner
                        Nov 12 at 12:48










                      • Yes, it is an object, or an instance of a class...
                        – Usagi Miyamoto
                        Nov 12 at 14:08


















                      • What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
                        – Chris Offner
                        Nov 12 at 12:48










                      • Yes, it is an object, or an instance of a class...
                        – Usagi Miyamoto
                        Nov 12 at 14:08
















                      What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
                      – Chris Offner
                      Nov 12 at 12:48




                      What is an 'object instance'? Isn't it just an object? I.e. an instance of a class?
                      – Chris Offner
                      Nov 12 at 12:48












                      Yes, it is an object, or an instance of a class...
                      – Usagi Miyamoto
                      Nov 12 at 14:08




                      Yes, it is an object, or an instance of a class...
                      – Usagi Miyamoto
                      Nov 12 at 14:08











                      0














                      It's not a problem at all but It's behavior of inheritance and polimorphism.



                      Please note that when you



                      I i = new A();


                      Left hand side (I) will tells compiler which all methods it can call using that reference.



                      Right hand side (A) will tells the Runtime which method should execute using that method call



                      So in your case



                      1 Problem



                      you can not call b() since b() is not there in inteface I



                      2 Problem



                      you are casting interface to object b and then calling b() so its working fine.






                      share|improve this answer


























                        0














                        It's not a problem at all but It's behavior of inheritance and polimorphism.



                        Please note that when you



                        I i = new A();


                        Left hand side (I) will tells compiler which all methods it can call using that reference.



                        Right hand side (A) will tells the Runtime which method should execute using that method call



                        So in your case



                        1 Problem



                        you can not call b() since b() is not there in inteface I



                        2 Problem



                        you are casting interface to object b and then calling b() so its working fine.






                        share|improve this answer
























                          0












                          0








                          0






                          It's not a problem at all but It's behavior of inheritance and polimorphism.



                          Please note that when you



                          I i = new A();


                          Left hand side (I) will tells compiler which all methods it can call using that reference.



                          Right hand side (A) will tells the Runtime which method should execute using that method call



                          So in your case



                          1 Problem



                          you can not call b() since b() is not there in inteface I



                          2 Problem



                          you are casting interface to object b and then calling b() so its working fine.






                          share|improve this answer












                          It's not a problem at all but It's behavior of inheritance and polimorphism.



                          Please note that when you



                          I i = new A();


                          Left hand side (I) will tells compiler which all methods it can call using that reference.



                          Right hand side (A) will tells the Runtime which method should execute using that method call



                          So in your case



                          1 Problem



                          you can not call b() since b() is not there in inteface I



                          2 Problem



                          you are casting interface to object b and then calling b() so its working fine.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 12 at 12:20









                          Jayanth

                          2,3871820




                          2,3871820






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53261487%2fjava-type-system-why-do-these-assignments-method-calls-and-type-casts-fail%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Xamarin.iOS Cant Deploy on Iphone

                              Glorious Revolution

                              Dulmage-Mendelsohn matrix decomposition in Python