I have 2 classes:
public class A
{
int n = 10;
public int getN()
{
return n;
}
}
public class B extends A
{
int n = 20;
public int getN()
{
return n;
}
}
public class Test
{
public static void main(String[] args)
{
B b = new B();
System.out.println(b.getN()); //--> return 20
System.out.println(((A)b).getN()); //--> still return 20.
//How can I make it return 10?
}
}
All methods in Java are always virtual. That is, there is no way of invoking the "super"-version of the method from the outside. Casting to A won't help as it doesn't change the runtime type of the object.
This is probably your best alternative / workaround:
class A {
int n = 10;
public int getN() {
return n;
}
public final int getSuperN() { // "final" to make sure it's not overridden
return n;
}
}
class B extends A {
int n = 20;
public int getN() {
return n;
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
System.out.println(b.getN()); // --> return 20
System.out.println(((A)b).getN()); // --> still return 20.
System.out.println(b.getSuperN()); // --> prints 10
}
}
you can't make the value be "10" because the instance of the object was for class B, and when you do the cast the only thing that are you doing is changing the define class not setting values for the object B, in other words if you need to get 10 its' something like this
b = new A();
That thing won't work due to polymorphism. Class B is still class B even if you cast it into its super class.
I think you'll need something like this:
public class B extends A
{
int n = 20;
/**
* #return the super n
*/
public int getSuperN()
{
return super.n;
}
}
What you see is polymorphism in action. Since b is a B, that method (which returns 20) is always called (regardless if you cast it to an A).
Related
This question already has answers here:
Is there a way to override class variables in Java?
(17 answers)
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I am not able to understand the following output.
I don't know why the output is 10, I think the line A a = new B() creates a new instance of class B, I think the result should be 20
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
Why this works like this .. please explain.
First, see Hiding Fields (emphasis added)
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different
In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.
If you expect true overrides, try using methods.
class A {
public int get() {
return 10;
}
}
class B extends A {
#Override
public int get() {
return 20;
}
}
See
A a = new B();
System.out.print(a.get()); // 20
If you really want to see both at once, see this example.
class A {
int i = 10;
}
class B extends A {
int i = 20;
#Override
public String toString() {
return String.format("super: %d; this: %d", super.i, this.i);
}
}
And
A a = new B();
System.out.print(a); // super: 10; this: 20
In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.
If you want 20 as an output you may use getter methods over those instance variables.
class A {
int i = 10;
int getI() {
return i;
}
}
class B extends A {
int i = 20;
int getI() {
return i;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getI());
}
}
Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.
Because you define 2 variables: one in the subclass B, and one with the same name in superclass A.
A a = new B();
a.i; // refers to A.i
If you cast the A to a B, it will access B.i:
System.out.println(((B)a).i);
I think you need to use 1 variable:
class A {
int i;
public A() {
i = 10;
}
}
class B extends A {
public B() {
i = 20;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i); // will print 20
}
Member variable i is already defined in class A.
In order to achieve what you are looking for, change the class B as shown below:
class B extends A {
public B() {
i = 20;
}
}
abstract class A {
int met(A a) {
return 0;
}
int met(B b) {
return 1;
}
int met(C c) {
return 2;
}
}
class B extends A {
int met(A a) {
return 3;
}
int met(B b) {
return 4;
}
int met(C c) {
return 5;
}
}
class C extends B {
int f() {
return ((A)this).met((A)this);
}
}
public class teste {
public static void main(String args[]) {
C x = new C();
System.out.println(x.f());
}
}
The program will return 3 and I was expecting 0. Why does the first cast in the method f do nothing and the second one works? Is it because in the A and B classes the met methods are overloaded and therefore static binding is used?
That's just the way polymorphism works. Just consider this example:
A a = new C();
a.met(a);
This would as expected call the correct method B#met(...). The method-tables for an object don't just change because you change the type of the variable you stored the Object in, since the binding between an Object and it's methods is stronger than the one between the storage-type and the methods related to it. The second type works, because the type of the input is casted to A and thus the method recognizes it as A (the type of the input-storage has stronger binding than the Object type).
Trying to pass a java test I faced the following question
class A {
int f() { return 1; }
}
class B extends A {
int f() { return 2; }
}
class C extends B {
int f() { return 3; }
int test() {
return super.f() +
((A)this).f();
}
}
Can't figure out why ((A)this).f() returns 3 but not 1?
This is dynamic dispatch, the static type of the object ((A)this, which is A) does not matter, only the dynamic type, and that is C.
Similarly, if you do
A a = this;
a.f();
The same value (3) will be returned.
I'm new in programming and I would like to know where did I go wrong in instantiating an object. Below is the code:
public class Testing{
private int Sample(int c)
{
int a = 1;
int b = 2;
c = a + b;
return c;
}
public static void main(String []args)
{
Sample myTest = new Sample();
System.out.println(c);
}
}
There is no Sample class in your code . The one which you have declared is a private method .
// private method which takes an int as parameter and returns another int
private int Sample(int c)
{
int a = 1;
int b = 2;
c = a + b;
return c;
}
With the current snippet , You need to instantiate the Testing class and make use of the Sample method. Notice your class definition is preceded by the keyword class , in this case class Testing.
public class Testing{
private int Sample(int c)
{
int a = 1;
int b = 2;
c = a + b;
return c;
}
public static void main(String []args)
{
Testing t = new Testing(); // instantiate a Testing class object
int result = t.Sample(1); // use the instance t to invoke a method on it
System.out.println(result);
}
}
But that doesn't really make sense, your Sample method always returns 3 .
Are you trying to do something like this :
class Sample {
int a;
int b;
Sample(int a, int b) {
this.a = a;
this.b = b;
}
public int sum() {
return a + b;
}
}
public class Testing {
public static void main(String[] args) {
Sample myTest = new Sample(1, 2);
int sum = myTest.sum();
System.out.println(sum);
}
}
I doubt you actually want to create an object.
From your code snippet, I understand that you want to run a 'method' named Sample which adds two numbers. And in JAVA you don't have to instantiate methods. Objects are instances of class. A method is just a behavior which this class has.
For your requirement, you don't need to explicitly instantiate anything as when you run the compiled code JAVA automatically creates an instance of your class and looks for main() method in it to execute.
Probably you want to just do following:
public class Testing{
private int sample(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int c = sample(1, 2);
System.out.println(c);
}
}
Note: I changed Sample to sample as it's generally accepted practice to start a method name with lower-case and class name with an upper-case letter, so Testing is correct on that front.
You instantiating correctly with new keyword ,But your calss name and method invoking is wrong
Testing myTest = new Testing();
int result =myTest.Sample(1); //pass any integer value
System.out.println(result );
Sample is not a class, it is just a method. You cannot create instances of it.
You only run it -
int sample = Sample(3);
If you wish for sample to be a class, define it as a class.
In your case, the method is not static is so you cannot directly access it from the Static method Main. Make it static so you could access it. Or just create a new instance of Testing and use it -
Testing testing = new Testing();
int sample = testing.Sample(3);
Sample method returns integer, so get the result and use it anywhere.
public static void main(String []args)
{
int myTest = Sample(4555);//input may be any int else
System.out.println(myTest);
}
This is how you should be doing this.
public class Testing{
public int Sample(int c)
{
int a = 1;
int b = 2;
c = a + b;
return c;
}
public static void main(String []args)
{
// Creating an Instance of Testing Class
Testing myTest = new Testing();
int c =0;
// Invoking the Sample() function of the Testing Class
System.out.println(myTest.Sample(c));
}
Well , it's easy. To you instantiate an object in Java you should to use class name and to do with that it class received a valor. For exemplo :
...Car c1 = new Car();
Why does below code prints "1" ?
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class Base {
A getObject() {
System.out.println("Base");
return new B();
}
}
public class CovariantReturn extends Base {
B getObject() {
System.out.println("CovariantReturn");
return new B();
}
/**
* #param args
*/
public static void main(String[] args) {
Base test = new CovariantReturn();
System.out.println(test.getObject() instanceof B);
System.out.println(test.getObject().x);
}
}
Because you are referring to fields, which are not affected by polymorphism. If you instead used getX(), it would've returned 2.
What you are asking is, the value of field x defined in class A (because Base.getObject() returns A). Even though CovariantReturn overrides the method to return B, you are not referring to your object as CovariantReturn.
To expand a bit on how fields are not affected by polymorphism - field access is realized at compile time, so whatever the compiler sees, that's what's accessed. In your case the method defines to return A and so A.x is accessed. On the other hands methods are invoked based on the runtime type. So even if you define to return A but return an instance of B, the method you invoke will be invoked on B.
#kris979 Though you are returning B, i think what makes the difference is that the return type is of A. Hence value of x in A i.e. 1 is printed.
As Bozho pointed out - instance variable are never affected by polymorphism. Let me give you a quick small example.
class Base {
int i = 1;
void method() {
System.out.println("in base");
}
}
class Sub extends Base {
int i = 2;
void method() {
System.out.println("in sub");
}
}
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
obj.method();
System.out.println(obj.i);
}
}
This code will print - in sub and 1