Java Type System: Why do these assignments, method calls and type casts fail?
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
add a comment |
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
add a comment |
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
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
java types casting variable-assignment
edited Nov 12 at 11:56
asked Nov 12 at 11:45
Chris Offner
114
114
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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
add a comment |
First of all, learn Java (and/or OO (object oriented)) programming...
- Variable
i
is a reference to an object instance that implements interfaceI
. Methodb()
was not declared in interfaceI
, thus it is not visible throughi.b()
.
To be able to call it,i
needs to be casted, EG:((B) i).b()
- Variable
b
is a reference to an object that is an instance of classB
, and cannot be assigned to any reference that itself is not declared as an instance ofB
.
Again, a cast needed, EG:b = (B) i
- Class
B
is not a child of classA
. They both implement interfaceI
, butA
is not parent ofB
.
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
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
add a comment |
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
add a comment |
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
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
edited Nov 12 at 12:09
answered Nov 12 at 11:59
Mohan
348111
348111
add a comment |
add a comment |
First of all, learn Java (and/or OO (object oriented)) programming...
- Variable
i
is a reference to an object instance that implements interfaceI
. Methodb()
was not declared in interfaceI
, thus it is not visible throughi.b()
.
To be able to call it,i
needs to be casted, EG:((B) i).b()
- Variable
b
is a reference to an object that is an instance of classB
, and cannot be assigned to any reference that itself is not declared as an instance ofB
.
Again, a cast needed, EG:b = (B) i
- Class
B
is not a child of classA
. They both implement interfaceI
, butA
is not parent ofB
.
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
add a comment |
First of all, learn Java (and/or OO (object oriented)) programming...
- Variable
i
is a reference to an object instance that implements interfaceI
. Methodb()
was not declared in interfaceI
, thus it is not visible throughi.b()
.
To be able to call it,i
needs to be casted, EG:((B) i).b()
- Variable
b
is a reference to an object that is an instance of classB
, and cannot be assigned to any reference that itself is not declared as an instance ofB
.
Again, a cast needed, EG:b = (B) i
- Class
B
is not a child of classA
. They both implement interfaceI
, butA
is not parent ofB
.
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
add a comment |
First of all, learn Java (and/or OO (object oriented)) programming...
- Variable
i
is a reference to an object instance that implements interfaceI
. Methodb()
was not declared in interfaceI
, thus it is not visible throughi.b()
.
To be able to call it,i
needs to be casted, EG:((B) i).b()
- Variable
b
is a reference to an object that is an instance of classB
, and cannot be assigned to any reference that itself is not declared as an instance ofB
.
Again, a cast needed, EG:b = (B) i
- Class
B
is not a child of classA
. They both implement interfaceI
, butA
is not parent ofB
.
First of all, learn Java (and/or OO (object oriented)) programming...
- Variable
i
is a reference to an object instance that implements interfaceI
. Methodb()
was not declared in interfaceI
, thus it is not visible throughi.b()
.
To be able to call it,i
needs to be casted, EG:((B) i).b()
- Variable
b
is a reference to an object that is an instance of classB
, and cannot be assigned to any reference that itself is not declared as an instance ofB
.
Again, a cast needed, EG:b = (B) i
- Class
B
is not a child of classA
. They both implement interfaceI
, butA
is not parent ofB
.
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
add a comment |
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 12 at 12:20
Jayanth
2,3871820
2,3871820
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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