In the following example, I don't understand why Base b1 = new Derived();
System.out.println(b1); prints out x=10, z=20. My understanding is that since b1 has a static type of Base, it don't have access to the fields in Derived, so z shouldn't haven been printed out. Can someone please help to explain? Many thanks!
class Base {
int x;
public Base1() { x = 10; }
public Base1(int x) { this.x =x; }
public String toString() {
return "x=" + x ;
}
}
class Derived1 extends Base1 {
int z = x * 2;
public Derived1() {}
public Derived1(int x, int z) {
super(x);
this.z = this.z + z;
}
public String toString() {
return "x=" + x + ", z=" + z;
}
}
The object is a Derived, not a Base. Your interface to the object from b1 is Base. Base has toString, so you can access toString. The implementation you access is the one the object has, which is provided by Derived, which uses z. The implementation of Derived#toString can access z because its reference to the object is via a Derived reference (this), not a Base reference.
As Oli points out in a comment, this is fundamental to polymorphism — having the behavior of the object depend on the object rather than the interface to the object.
If the internals of the object were dictated by the interface we had to it, we'd be in a fair bit of trouble trying to implement interfaces! :-)
Straight from http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
A subclass inherits all of the public and protected members of its
parent, no matter what package the subclass is in. If the subclass is
in the same package as its parent, it also inherits the
package-private members of the parent. You can use the inherited
members as is, replace them, hide them, or supplement them with new
members
In your code you call the default constructor to create a new Derived1 object : Base b1 = new Derived();and this in turn calls the default constructor of the parent class where there you happen to set x = 10. After that, you go to this line int z = x * 2;
Related
I couldn't understand the behavior of the below code.
My expectation was that it should print 100 in both println() methods. Why the result is different?
If I uncomment getX() method in inner class, then the output of println() methods are the same which is 100.
I couldn't figure out the reasoning of different behavior. Please help me to understand.
public class Foo {
public static void main(String[] args) {
MyOuter outerObj = new MyOuter();
MyOuter.MyInner innerObj = outerObj.new MyInner();
innerObj.setX();
System.out.println("x: " + innerObj.getX()); //x: 3
System.out.println("x: " + outerObj.getX()); //x: 100
}
}
class MyOuter {
private int x = 3;
public int getX() { return x; }
class MyInner extends MyOuter {
public void setX(){ x = 100; }
// public int getX() { return x; }
}
}
From MyInner's perspective, there are two private int x fields in play here:
One field super.x that is inherited from MyOuter, but inaccessible because it is declared as private, and MyInner as an inheriting object cannot access this field.
One field MyOuter.this.x from the sorrounding MyOuter-instance (since MyInner is a (non-static) inner class, it is always bound to an instance of the surrounding MyOuter), that is accessible.
The method setX() in MyInner cannot access the inherited field super.x, thus it accesses the field MyOuter.this.x and sets its values to 100. A consecutive call on the surrounding MyOuter's getX() will return 100.
The call innerObj.getX() (which is inherited from MyOuter and can access super.x) returns the value of the inherited field super.x (still having its initial value of 3).
If we remove the extends MyOuter from and include the getX()-method in MyInner, the code behaves as expected.
The fact that MyInner cannot access the inherited field private x is confusing at first, but the behaviour is actually in line with the behaviour of the keyword protected in the context of static mehthods in inheriting classes as discussed in this post by Hariharan
In the following code, I don't understand why when a1.k() is called, this.x in class C returns 100 instead of 1. My understanding is that this refers to the current object, but the static type of the current variable a1 is A. So shouldn't this.x returns 1, which is the variable for A type?
I mean a1.x should return 1, right? Many thanks!
class A {
public int x = 1;
public String k() { return "A" + this.x; }
}
class B extends A {
public int x = 10;
...
}
class C extends B {
public int x = 100;
public String k() { return "C" + this.x; }
}
class TestABC {
public static void main(String[] args) {
A a1 = new C();
C c1 = new C();
System.out.println(a1.k());
}
}
When you call a1.k() you dynamically dispatch to the k method that is defined by the actual object whose reference is in a1. In this case, it is a C not an A or a B, and hence the k method is the override defined in C.
The static type (of a1 for example) is used for static resolution; e.g. resolving static methods, overload signatures, and fields. But for instance method invocation, the ultimate selection of the method to be invoked is dynamic.
I know the k() in class C should be called, instead of the k() in class A. But why this.x returns 100? I thought the instance variable is bounded to the static type.
Well it is. But it is the static type that determines which x is used by this.x in the k() call is the static type of this in the C.k method body!
This feature is called Dynamic Polymorphism. The methods being called is not dependent of type of its declaration but by the type being assigned to it (definition).
For this the classes must inherit and also override the methods in the parent class.
Here C,B extends A and overrides the method k;
if you try to call some C specific methods or variable it will throw error. (Since A doesn't know about that)
A is holding reference to C (pointing to C)
a1.k is actually C constructed Object and its new C().k() where x is 100 in C.
class Base{
int x=10;
public int getx(){return x;}
}
class Sub extends Base{
int x=100;
public int getx(){return x;}
}
class Test
{
public static void main (String[] args)
{
Base b = new Base();
Sub s = new Sub();
System.out.println("sub: getx:"+s.getx()+" .x:"+s.x+" Class: "+s.getClass().getName());
System.out.println("base: getx:"+b.getx()+" .x:"+b.x+" Class: "+b.getClass().getName());
Base btoS = new Sub();
System.out.println("btos: getx"+btoS.getx()+" .x:"+btoS.x+" Class: "+btoS.getClass().getName());
}
}
Results in
sub: getx:100 .x:100 Class: Sub
base: getx:10 .x:10 Class: Base
btos: getx100 .x:10 Class: Sub
Since you declare a1 as new C(), a1 will be seen as an object instance of class C, which overrides the fields of its parent class B and A. So why you would do things like A a1 = new C(); (or you might see a lot of such implementation), there is a recommendation saying "programming to interface rather than the actual implementation.", and I think this explains better.
So, I have these 3 classes in Java.
When I run the program I get:
20,
15,
10,
My question is, why do I get this instead of:
15,
20 (doesn't public int getX(); in class B get us to 15+5=20?),
10
for example?
Can you please explain to me , step by step, what really happens in this program because I am very confused with the output(and the sequence).
public class A {
private int x = 15;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public void printX() {
System.out.println(this.getX());
}
}
Child:
public class B extends A {
private int x = 5;
#Override
public int getX() {
return super.getX() + x;
}
#Override
public void setX(int x) {
super.setX(x);
super.printX();
}
#Override
public void printX() {
System.out.println(super.getX());
}
}
and
public class C {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getX());
a.setX(10);
a.printX();
}
}
This is happening because you instantiate a as a B object - A a = new B(). It doesn't matter that the explicit type of a is A; it's more generic (abstract) than its real type B (because B inherits from A), therefore polymorphism calls B methods (more specific) in first order. The same applies to fields.
After calling a.getX() class B references to A's getX(), which returns its 15 (superclass method has no reference to the object it was called from in this case), then 5 (B's x) is added, resulting in 20.
The subsequent calls behave in a similar manner.
I have given a basic example similar to your problem go through it you will get your answer. This is the concept of runtime polymorphism
Inheritance creates typecompatibility. It allows a super class reference to refer to the object of sub class. (Reverse is not true).
A super class reference, that refers to object of sub class, can only be used to access the inherited and overrridden methods of sub class. The members newly defined in sub class are not accessible using reference of super class.
class A
{
void f1()//this holds address of object of B
{
System.out.println("A f1");
}
void f2()
{
System.out.println("A f2");
}
}//A
class B extends A
{
void f3()//new method
{
System.out.println("B f3");
}
void f2()//this holds address of object of B
{
System.out.println("B f2 starts");
f3(); //this.f3()
System.out.println("B f2 ends ");
}
}//B
class TypeCmptbl
{
public static void main(String args[])
{
A ref; //reference of A
ref = new B();//Object of B
//ref.inherited() allowed
ref.f1();
//ref.overridden() allowed
ref.f2();
//ref.newMembersOfChild() not allowed
//ref.f3();
}//main
}
Consider the statement
ref.f2();
Here ref is a reference of class A and it has address of object of class B f2() is a overridden method.
When compiler detects such a statement then it doesn't bind the function call with any definition. It only validates the call.
Binding of such calls is left for the runtime environment. At program runtime system identifies the datatype of the object and binds the function call with the function definition provided by the class of object. This type of binding between the function call and function definition is called as "runtime polymorphism" .
Your question is related to the runtime polymorphism in java note that methods are bind at runtime, and the variables are bind at Compile time
In your example
public class C {
public static void main(String[] args) {
A a=new B();
System.out.println(a.getX());
a.setX(10);
a.printX();
}
}
// reference is of A but the object is of B, so at runtime JVM see that memory is of B so the B's method is called, this is runtime Polymorphism
when the below statement is called , the getX() of class B is invoked.
System.out.println(a.getX());
#Override
public int getX() {
return super.getX() + x; // this will add 15 from class A + 5 in this method.
}
the above statement displays 20
when the below statement is called,
a.setX(10);
#Override
public void setX(int x) {
super.setX(x); // observe this method, this prints 15
super.printX(); // this prints 10
}
//super.setX(x); it will call
public void setX(int x) {
this.x=x; // 10 <--- 15 so 15 is displayed
}
here this.x refers the value which is passed through a.setX(10).
A a = new B();
So the concrete type of a is B.
System.out.println(a.getX());
You're calling getX() on an object of type B. So the following method is called, because the concrete type of a is B, and B has overridden the getX() method defined by A:
public int getX() {
return super.getX() + x;
}
It adds B's x (whose value is 5), with the result of super.getX(). This method, in A, is defined as
public int getX() {
return x;
}
So it returns A's x, which is initialized to 15.
The result is thus 5 + 15 = 20.
The rest can be explained the same way. Remember that fields are not accessed in a polymorphic way. Only methods are. So, inside the code of A, when you see x, it always mean "the value of the field x in A". Inside the code of B, when you see x, it always mean "the value of the field x in B".
When you say:
A a = new B();
it means Object of A is instantiated with class B. So, in the memory, a space is reserved for your object 'a' which contains all the methods and properties of class B (not A).
So, when the first print statement is executed, it executes the getX() method of the class B and not the getX() method of class A.
For other methods called by your object 'a', the methods of the class B are called.
This is also known as dynamic binding, as JVM allocates the memory to the object 'a' at the run time and not compile time.
For more details on dynamic binding check these links:
http://www.tutorialspoint.com/java/java_overriding.htm
http://www.tutorialspoint.com/java/java_polymorphism.htm
I also suggest you to instal eclipse on your machine and run your code in the debug mode.
This is the best way you can study your code.
In this code I allocate one only object, but in some way I store 2 copies of x (one for the base class and one for the subclass). How is it possible if the object is only one? Where is the space found to store two x vars? Does it mean in reality two objects are createed?
class App {
class Base {
public int x;
public Base() {
x = 2;
}
int method() {
return x;
}
}
class Subclass extends Base {
public int x;
public Subclass() {
x = 3;
}
int method() {
return x;
}
}
public static void main(String[] args) {
new App().run();
}
public void run() {
Base b = new Subclass();
System.out.println(b.x);
System.out.println(b.method());
}
}
One x belongs to the superclass and the other to the subclass. The fact that they have the same name is of no importance and you can access both by qualifying your access expression with the class:
((Base)b).x
((Subclass)b).x
(note that the cast in the first line is not necessary; I've put it in for symmetry)
In java you can not overload variables.,Though they are with the same name,their classes are different.
According to this tutorial(in section "What You Can Do in a Subclass"), when you declare a field in the subclass with the same name as the one in the superclass, in this case x, the one in the superclass will be hidden, which means that there're actually two xs in the subclass, one for itself, the other for its superclass, only baring the same name x. You can reference to the one in the derived class using derivedObject.x and the one in the subclass using ((Base)derivedObject).x(or super.x if within the derived class)
I am having a base class C with fields X, Y and Z.
C1 extends C and is having an extra field, T.
In the C1 constructor, I do call the super (C) constructor with some hard coded values for the fields X, Y and Z. Then I set T.
Are there any patterns to automatically validate all the fields of C1 by doing something in the C constructor ? So I am trying to push the automatic validation to the base class.
Please note that calling the super constructor should be done before any statement in the C1 constructor. I started with some abstract validate() method, but I am not I am on the right track.
Thanks.
As a matter of principle, C should not know about C1's properties, because C1 is a specialization of C. However, what you can do is make an abstract validate() method in C, that must be implemented by C1. Then, in C's constructor, you can call the abstract method. Since, C1 will have to implement the validate(), it can then add it's property/field validation there.
Although it is against all OO principles, you could take advantage of Java's reflection property. Via reflection you can find out which methods and fields a class has. So you could pass the subclass object to the base class and the base class could check for all fields and validate them. If you do this at the end of the subclass constructor, you could let the validation method return a value to see if the values are valid or not.
I want to state that I don't think it's the right way to go but it should work
I would say that the super class should validate itself. An object needs to enforce its own contract. Any validation of C's values should be done in its own constructor. Likewise, the subclass should validate itself.
public class A {
private int x;
public A(int x) {
if (x < 0) throw new IllegalArgumentException("x cannot be negative");
this.x = x;
}
}
public class B extends A {
private String y;
public B(int x, String y) {
super(x);
if (y == null) throw new IllegalArgumentException("y cannot be null");
this.y = y;
}
}
class C{
Object x, y, z;
public C(Object x, Object y, Object z){
this.x = x;
this.y = y;
this.z = z;
}
public boolean validate(){ /**do stuff**/}
}
class D{
public D(/**args**/){
super(/**args**/);
if(validate()){
/**do stuff**//
}
}
}