I create the object using two statements , is there any difference between the two ?
public interface vehicle
{
void accelerate () ;
}
class bmw implements vehicle
{
void accelerate ()
{
System.out.println (" top speed of 300kmph " ) ;
}
}
public class driver
{
public static void main (String qw [] )
{
vehicle v = new bmw () ; // statement 1
v.accelerate () ;
bmw b = new bmw() ; // statement 2
b.accelerate() ;
}
}
Both the statements are giving same output but I think there is some difference between the two .
Variable 'y' it's private so you can't access it directly from you subclass.
But you can organize the access to this variable creating public methods.
So when are you calling:
subclass.show ( 23 , 45 );
you are not accessing directly to 'y' attribute of 'A' class but only to a public method defined in it where you are using 'y'. You can do it because it's a method in 'A' class.
Trying to explain better:
Private modifier let your attribute in this case be not accesible from a subclass. So you can"t do this:
B b = new B();
b.y = 10;
Because you don't have direct access to this attribute.
So now you can define how subclass can access this private attribute with a public method. The best example will be a getter or setter: (this methods have to be defined in your superclass)
Public int getY(){
Return this.y;
}
Public void setY(int y){
This.y = y;
}
Now you can access to private attribute 'y' but you need to call this public method so now you can do:
B b = new B();
b.setY(10);
And you will change the value of 'y'.
Now, according to yuor code, you didn't made any setter or getter but you defined a method call 'show(int,int)' where you are changing the value of 'y'.
And this is working likely as setter methods.
So you can access directly this method like:
B b = new B();
b.show(5,10);
Because it's a public method. And inside of this method you are doing operationts on a private attribute.
So, finally, the private attribute 'y' belongs to 'A' superclass and can't be access directly by any subclass but you can manage operations defining public method in superclasw where you specific how other classes can access superclass private attribute.
I have this doubt because since y is a private variable then how can y belong to object subclass ?
'y' doesn't belong to subclass. As i said before you can access 'private' attributes only using public methods defined in superclass. So if i want to change value or show 'y' i can do it only if there is public methods in superclass that change or show 'y' value.
void show (int o ,int e )
{
x=o ; // I mean to say ,
int y ; // Is this implicitly declared above ?
y=e ;
System.out.println(" x = " + x);
System.out.println(" y = " + y);
}
Here you don't need to declare 'int y;' because this method is defined in superclass and so you have direct access to 'y'.
If you need more please comment.
yes, y will b printed because y is local and it has been initialized before printing . so there is no error.
In your second program, Y is private member of class A and it is not directly accesible in its child class. you have made object of sub class but you have not override show method of parent class.So the show method of parent class means A class will be executed, and there you will find Y.
Related
I'm reading the source code of ArrayList and this class has an inner class with the name SubList. I'm looking in a method of the inner class (SubList) and see the following methods:
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
What I see that line 3 & 4 uses this keyword in order to call/use ArrayList (outer class) method/attribute.
I want to understand is it must to use OuterClass.this or elementData() will be enough? I run an example long ago (more than a year) and I was able to call an outer class method from an inner class without using this keyword.
There is a Shadowing problem that can lead to unexpected behavior and runtime errors.
If a declaration of a type (such as a member variable or a parameter name or method name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. You cannot refer to a shadowed declaration by its name alone.
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
Output:
x = 23
this.x = 1
ShadowTest.this.x = 0
As you can see, to get the correct value of higher scope, you need to use only ShadowTest.this.
Thru time your code will mutate and you can miss the same name in the other scope, so you must use only OuterClass.this to access outer class scope, make code clear and bulletproof.
See the Java Tutorial.
I am thinking about this java oop problem . I don't exactly know exactly what is really happening there . Can someone make me understand ?
abstract class A {
public int proc (A p){
return 98;
}
}
class B extends A {
public int proc(A p) {
return 17;
}
}
class C extends A {
public int proc (C p) {
return 65;
}
}
public class HelloWorld{
public static void main(String []args){
C x = new C(); // here x is C type and is an instance of C ?
A y=new B(); // here y is A type and is an instance of B?
C z=new C(); // here z is C type and is an instance of C ?
System.out.println(y.proc(x)+z.proc(x)); /* y is A type so it is looking for proc function in A ,but doesn't return 98
, z is C type and it is looking for proc function in C and return 65 .*/
}
}
Can someone tell me how should I tackle theese instances ?
Y is an A but contains a reference to a B so when we call y.proc it is the proc in B that is called, and returns 17, not 98.
You need to look at the instance that is created and not the type of variable.
In Java, you can create base class objects which hold the child classes objects except for abstract classes.
A is an abstract class, you cannot instantiate it, but you can assign an object of the child class to it which holds the child class object's features.
You can think, we are assigning the reference of B to y which has a type of A.
System.out.println(y.proc(x));
The code above will print 17, which is the return value of the proc in class B returns.
Whenever you call the methods of y, the compiler will give you class B's methods automatically.
So, you are creating an instance of class B in the memory and assigning it to y which points to the same memory location.
For that reason, you can use the methods of class B.
Same goes for z as well.
Consider below code
class A
{
int x = 5;
void foo()
{
System.out.println(this.x);
}
}
class B extends A
{
int x = 6;
// some extra stuff
}
class C
{
public static void main(String args[])
{
B b = new B();
System.out.println(b.x);
System.out.println(((A)b).x);
b.foo();
}
}
Output of the program is
6
5
5
I understand the first two but can't get my head around the last one. How does b.foo() print 5. B class will inherit the foo method. But shouldn't it print what b.x would print? What exactly is happening here?
Yes, the B class inherits the foo method. But the variable x in B hides the x in A; it doesn't replace it.
This is an issue of scope. The foo method in A sees only the variables that are in scope. The only variable in scope is the instance variable x in A.
The foo method is inherited, but not overridden, in B. If you were to explicitly override foo with the same exact code:
class B extends A
{
int x = 6;
#Override
void foo()
{
System.out.println(this.x);
}
}
Then the variable that would be in scope when referred to by this.x would be B's x, and 6 would be printed. While the text of the method is the same, the reference is different because of scope.
Incidentally, if you really wanted to refer to A's x in the B class, you can use super.x.
Well, this is because of static binding.
1) Static binding in Java occurs during Compile time while Dynamic
binding occurs during Runtime.
2) private methods, final methods and static methods and variables
uses static binding and bonded by compiler while virtual methods are
bonded during runtime based upon runtime object.
3) Static binding uses Type(Class in Java) information for binding
while Dynamic binding uses Object to resolve binding.
4) Overloaded methods are bonded using static binding while overridden
methods are bonded using dynamic binding at runtime.
Fields are not overridable in Java and subclasses with same field names as the parent class shadow "only" the fields of the parent class.
So this.x refers to the x defined in the current class : A.
Whereas the result : 5.
To be more precise : the foo() method is inherited by the B subclass but it doesn't mean that the behavior of the inherited method will change about instance fields referenced since as said fields are not overridable : the this.x expression that refers the A.x field in the foo() method goes on referencing A.x.
It is exactly the same thing as for the two previous statements :
B b = new B();
System.out.println(b.x); // refers B.x -> 6
System.out.println(((A)b).x); // refers A.x -> 5
b.foo(); // refers under the hood A.x -> 5
The very good answer of rgettman shows how you can overcome the field hiding in the subclass.
A alternative to overcome the hiding relies on making the instance field private (which is recommended) and providing a method that returns the value.
In this way you benefit from the overriding mechanism and the field hiding is not an issue any longer for clients of the classes :
class A
{
private int x = 5;
int getX(){
return x;
}
void foo()
{
System.out.println(this.getX());
}
}
class B extends A
{
private int x = 6;
int getX(){
return x;
}
}
In JAVA, methods can be overridden while variables can't. So, as your method foo is not overridden in B, it takes the member variable from A.
When you call
b.foo();
It checks to see if B has overridden the method foo(), which it has not. It then looks one level up, to the superclass A and invokes that method.
You have then invoked A's version of foo() which then prints out
this.x
Now, A can not see B's version of x.
In order to solve this, you have to override the method in B
class B extends A
{
int x = 6;
#Override
void foo()
{
System.out.println(this.x);
}
}
Now, calling
b.foo();
will call B's version of foo() and you will get the expected result.
I have a Doubt
when we initialize our instance variables in Instance initialization block(s) in case of inheritance do they override the value of variable?
For example
class A{
int x;
}
class B extends A{
int x = 10;
}
public class C{
public static void main(String[] args){
A K = new B();
System.out.println(K.x);
}
}
o/p : 0
However when i use initialization blocks
class A{
int x;
{x = 15;}
}
class B extends A{
{x=20;}
}
public class C{
public static void main(String[] args){
A K = new B();
System.out.println(K.x);
}
}
OUTPUT 20
Why its so? why my initialization block(s) are affecting instance variables ? Moreover , i know that blocks are called when we make object but still the variable at output should correspond to variable type i.e A K (K should give value corresponding to class A)
You can override methods only, not variables. This code isn't "overriding" instance variables.
The first example has a different variables named x defined for A and B, making the variable an A means you see the variable defined for A (see the link provided by paulk23). In the second there is only one instance variable x which is visible to the subclass, the instance initializer assigns a value to an existing variable.
In the first example, you have two declarations of x, and in the second you only have one. In the second example, try changing B to:
class B extends A {
int x;
{ x=20; }
}
and you'll see the same behaviour as the first example: B defines a new variable that has an independent value from the one in A.
The code is like this :
class Base {
int x = 10;
public Base() {
this.printMessage();
x = 20;
}
public void printMessage() {
System.out.println("Base.x = " + x);
}
}
class Sub extends Base {
int x = 30;
public Sub() {
this.printMessage();
x = 40;
}
public void printMessage() {
System.out.println("Sub.x = " + x);
}
}
public class DispatchTest {
public static void main(String[] args) {
Base b = new Sub();
System.out.println(b.x);
}
}
The result is :
Sub.x = 0
Sub.x = 30
20
Can anybody please tell me how this code run?
Why doesn't the costructor of class Base run?
Because you created a new Sub object instance. The class Sub has the printMessage() method overriden, which means that the Base.printMethod() is not being executed.
The constructor of the Base class runs, but the this.printMessage() executes the printMessage method from the Sub class.
Immediatelly after the Sub's constructor has been invoked, the Base constructor is being called. It prints Sub.x = 0 because no x (in Sub) has been set so far. After that the value x gets assigned.
After the Base constructor is done, the rest of the Sub constructor is being executed. It prints calls the Sub's printMessage method again, but this time the value x has a value, and it prints Sub.x = 30.
The 20 comes from the System.out.println(b.x);.
You might wonder, why the value xis not assigned during the first printMessage call? Because you have x in your Sub class as well, so the x from the Base class is not visible!
Your SuperClass constructor is always called but "Polymorphic behaviour cannot be seen when accessing overridden member variables".
Base b = new Sub();
System.out.println(b.x);
Now if you access x(which is present in both subclass and superclass) it is actually the type of reference variable which determines the value.
Note: This behaviour is different with overridden methods,in this case it is actually the type of object which determines the method to be called not the type of reference variable.
The constructor
public Sub() {
this.printMessage();
x = 40;
}
is equivalent to
public Sub() {
super();
this.printMessage();
x = 40;
}
So when you create
Base b = new Sub();
Base's constructor gets executed followed by Sub's constructor. See JLS 8.8.7, which states
The first statement of a constructor body may be an explicit
invocation of another constructor of the same class or of the direct
superclass
Base's constructor is calling printMessage() which is overriden by Sub. When it gets called from Base's constructor printMessage() prints x of Sub which is not yet initialized. This is an anti pattern, so Sub.x = 0 gets printed (x is not yet initialized, and hence default value of int which is 0 )
Now once the Base's constructor finishes, Sub's constructor gets called and now the x is initialized to 30 why?
because
class Sub extends Base {
int x = 30;
public Sub() {
this.printMessage();
x = 40;
}
....
essentially means
class Sub extends Base {
int x;
public Sub() {
{
x=30;
}
this.printMessage();
x = 40;
}
....
hence this time printMessage() prints Sub.x = 30
finally 20 is printed because fields are NOT overriden.
When ever we are creating child class object then the following sequence of events will be executed automatically.
Step 1.Identification of instance members from parent to child and initialize them to default value.
after first step
Base instance variable is int x=0;
Sub instance variable is int x=0;
Step 2. Execution of instance variable assignments and instance blocks only in parent class
after second step
Base class instance variable is int x= 10;
Sub class instance variable is int x = 0;
Step 3.Execution of parent class constructor.
after third step
here you have a "printMessage()" invocation.It is overridden in child class Sub
So Sub class method is executes and prints Sub class's variable x value,which is now assigned as 0 only.
So the out put now "Sub.x = 0".
and Base class int x = 20;
Sub class int x = 0;
Step 4.Execution of instance variables and instance blocks in child class.
After 4th step
Base class int x=20;
Sub class int x=30;
Step 5.Execution of child constructor.
After 5th step.
In Sub class constructor you have "printMessage()" method invocation.So it will executes and prints output.
So the out put now "Sub.x = 30".
After the method invocation you have an assignment.
So now Base class int x=20;
Sub class int x=40;
For now your Sub class constructor created successfully.
Now you a print statement of variable x on type reference "Base".So now "Base" class variable x will be prints as output.
So the out put is "20".