Here is my question. I have a super class with an abstract method in it.
public abstract class Base{
public abstract Boolean foo();
}
public class sub extends Base{
#Override
public Boolean foo(){
System.out.printLn("This is foo in the sub class!");
}
}
so When I go to the main and try this code
Base b = new sub();
b.foo();
I got no error and message shows on my screen. My assumption is the compiler looks at the b object and sees it as a Base object then it goes to the foo from the Base object and sees there is no implementation afterwards it checks out the foo from the child and then it sees the method foo is implemented there so it shows the message. Am I right?
Compiler does not see if the method is implemented by subclass or not. It only checks whether method called by the a particular class type reference is present in the class itself or not. At runtime it decides which method to call means Base class version or Subclass version.
So you are only right upto "My assumption is the compiler looks at the b object and sees it as a Base object then it goes to the foo from the Base" statement.
Compiler does not do so much of processing. Here in your case
You have created the reference variable as of your superclass which will hold the object of child class.
Now when you are calling the method it is directly calling the method present in your subclass based on your object type.
I am adding you code with my comments for your reference.
1) Abstract class having only method declaration
public abstract class Base {
public abstract Boolean foo(); //method declaration
}
2) Child class extending your parent class where you have to implement the method,If you are declaring this class as concrete class.
public class sub extends Base {
#Override
public Boolean foo() {
System.out.printLn("This is foo in the sub class!");
}
}
3) Here you have declared reference variable of your parent type that is storing the object of you child class
Base b = new sub();
4) when this line will get executed compiler will check, what is the type of object and call that method on the basis of object type.It will not invoke methods on the type of reference variable.
b.foo();
Related
In Java, when a method is going to be executed, it's declaration is first searched for at the object's real class (that defines the real type of the object). If it's not found, then the superclass is checked. If isn't found there either, the next parent class is checked, and so on. However, look at the example below:
SuperClass s = new SubClass(list of parameter);
s.someMethodExistOnlyInSubClass();
This will give me a compile time error. I thought that, as mentioned above, it would first look for someMethodExistOnlyInSubClass() at SubClass, verify that it exists there and then execute it right away. If I use a variable of the type SuperClass to reference an instance of SubClass some parameters will go to SuperClass's constructor through a call to super() and the object will be instantiated there. In this context, to where have the remaining parameters gone?
By assigning a reference to an instance of SubClass to a variable of the type SuperClass, the variable is treated as if it were referencing an instance of SuperClass. Therefore, it will have no knowledge of any of the methods declared specifically in SubClass. Note, though, that the overrides performed in SubClass will still be effective.
In the context you described, to access someMethodExistOnlyInSubClass() you would have to cast s to the type SubClass. Look below:
((SubClass) s).someMethodExistOnlyInSubClass();
What you are trying to do will work only when the method is defined in both Parent class and subclass.
import java.util.*;
class Parent
{
public void sample()
{
System.out.println("Method of parent is getting Called");
}
}
class Subclass extends Parent
{
public void sample()
{
System.out.println("Method of Child class is getting Called");
}
}
public class Main
{
public static void main(String[] args){
Parent p = new Subclass();
p.sample();
}
}
OUTPUT : Method of Child class is getting Called
If the method exists only in Child class. You will have to create an instance of Child class itself.
Something like this :
import java.util.*;
class Parent
{
}
class Subclass extends Parent
{
public void sample()
{
System.out.println("Method of Child class is getting Called");
}
}
public class Main
{
public static void main(String[] args){
Subclass p = new Subclass();
p.sample();
}
}
Or you can type cast it as mentioned in the earlier post
Parent p = new Subclass();
((Subclass)p).sample();
An object is created based on its declaring class.
When you declare it as SuperClass s the object s wont have any method called someMethodExistOnlyInSubClass . So when you try to invoke this method, even before look at the subclass, you get a compile error.
The object s contrains only everything of the superclass, this object wont be aware of any subclass until u type cast the object to subclass.
Kindly excuse my question as I have tried to search the difference between using super keyword vs class name to call a method from super class but am unable to find an answer.
My question is I am trying to learn Java as a study course and am using an example from the link: http://www.javatpoint.com/super-keyword using Example # 3 and here is the code I have written:
I have created a super class named Vehicle
public class Vehicle {
Vehicle() {
System.out.println("Vehicle constructor created");
}
public void speed() {
int a = 20;
System.out.println(a);
}
}
and then created a sub class named Bike with the following code:
public class Bike extends Vehicle {
int speed;
Bike(int speed1) {
this.speed = speed1;
System.out.println(speed1);
super.speed();
}
public static void main(String args[]) {
Bike b = new Bike(10);
}
}
In the sub class under Bike constructor I am using super.speed() to call speed method from super (Vehicle) class. Now if I change this line to Vehicle.speed() I get an error stating that I need to make my speed method as static.
I do not want to make my method as static and want to know about the difference between both of them.
Cheers,
Calling a method using class name directly means that you want to call a static method, which is not related to any object of the class but the class it self.
That is why the compiler tells you that the method must be static.
As for your question, when you create an object of a child class (Bike class in this example) an object of its parent is always created, on the base of which the particular child object is created.
Its like, when ever you create a Bike, a backing Vehicle is always created, based on which the Bike is created. Otherwise the Bike wouldn't be a Vehicle.
So calling a method by super means, you're telling the compiler to call this method on the class which was used as base(parent) for making this Bike class, from which I'm calling this method.
when you're calling the method by class name, you're telling the compiler to call this method of Vehicle class which is not related to any Vehicle object/instance (and obviously not related to any child (e.g. Bike object or instance as well)
Methods that aren't static can only be called on a specific instance of an object. That is why calling Vehicle.speed() would only work if the speed method were static. The reason you can call super.speed() is because in the constructor, you have already constructed the vehicle object, and are basically calling the method on the object you are constructing.
For the above example, I would say that calling super.speed() is the best approach.
Also, as you haven't overriden the super implementation of the speed method, you can just as easily call this.speed() or speed(). That approach would mean that if you ever decided that the Bike needs different functionality in the speed method, your specific implementation would be called as opposed to the default.
The two constructs are not equivalent.
When calling Vehicle.speed() the compiler is looking for a static method named speed() in the class named Vehicle. A static method doesn't belong to any instance of the class. You cannot use any instance variable inside a static method. You haven't defined a static method named speed() in your Vehicle class and therefore there's no such thing as Vehicle.speed(). Hence, you get a compilation error.
When calling super.speed(), you don't look for a static method as in the previous case: The actual method that is going to be called when using the super syntax is an instance method (named speed() in your case) defined in the superclass of the current object. That is, super.speed() is the instance method defined in the super class of the current object (unlike this.speed() which is the instance method named speed() defined in the actual class of the current object). In other words, it is going to call the method speed() defined in the class Vehicle, but the this parameter is going to be the one referenced by b, the current object.
You need instance to calls instance(non-static) method.
super is parent class's instance. Simply put class name is not an instance(it' a static context for entire class).
[super is parent class's instance ?]
Jon skeet said no such thing as a "parent instance", but i doubt the term of instance.
super's variable is initialized first and then the turns of child to decide whether share the same variable/method(i.e. return this.i; in this kind of method will return super.i, not this.i, when call by child) or override it.
import java.util.Random;
class Love {
int i = 1;
int hole() {
return this.i;
}
}
class Main extends Love {
void wrapper() {
System.out.println(super.i); //1
System.out.println(this.i); //2
super.i = new Random().nextInt(50) + 2; //to avoid compiler pre-optimizing hard coded return value in hole(), so we set again.
System.out.println(super.i); //23
i = 3; //2nd attempt override
this.i = 3; //3rd attempt override
System.out.println(hole()); //23, super "instance" keep its own version of this.i
}
int i = 2; //1st attempt oveeride
public static void main(String[] args) {
new Main().wrapper();
}
}
So it's obvious when child override, super still keep its own version, so IMHO super can roughly treat like a parent instance, just the difference with normal instance are it's a keyword with some restriction of usage (e.g. super.super.i is not allow, direct print super not allow). One more difference is the variable value will sync in each instance due to child might share it as mentioned above.
You can try to print super.variable_name inside static method, it will output super is a non-static variable:
$ javac Bike.java
Bike.java:132: error: non-static variable super cannot be referenced from a static context
System.out.println(super.dummy);
^
Bike.java:132: error: cannot find symbol
System.out.println(super.dummy);
^
symbol: variable dummy
2 errors
$
So it's make sense super as a non-static variable can access non-static method speed() in your example.
If you want to use method directly with class name then you have to specify method as static
public static void speed() {
int a = 20;
System.out.println(a);
}
or
you can create an object of class Vehicle and access speed method in your subsclass like this
Bike(int speed1) {
this.speed = speed1;
System.out.println(speed1);
Vehicle vehicle = new Vehicle();
vehicle.speed();
}
hi super is a keyword which is used to access the super class methods in sub class.
This super keyword is used mainly when methods are overridden.
example
class A
{
method m()
}
class B extends A
{
method m()
method m1()
{
super.m()
}
}
class C
{
public static void main(String args[])
{
B b = new B();
b.m() // calls method m() in class B
b.m1() // calls method m() in class A because method m is pointing to super class method
}
}
I have an abstract class called A and class that extends from it called B. In the A class I have a concrete implementation of a method and also I have abstract methods. In class B I have overridden all abstract methods and a method of its own.
public abstract A{
public boolean myConcreteMethod(){
//implementation
}
public abstract void abstractMethod();
}
public class B extends A{
#Override
public void abstractMethod(){
//implementation
}
public String aMethodBelongsToB(){
//implementation
}
}
Now when I instantiate an object of B like following:
A test = new B();
I am unable to access
test.aMethodBelongsToB();
Am I doing something wrong here? Any help would be greatly appreciated.
You don't have the B reference.so, you cannot call it's methods.You have to make it
B test = new B();
Now, B can access methods of A. Since B is A in OOP terminology. IS-A relationship!
When you instantiate class B, you're using a reference variable to the type of A. From this reference, you can only access methods declared in A. That reference can also point to other classes that inherit from A, that would not have the methods declared in B, so the compiler doesn't let you call methods only declared in a subclass from a reference to a superclass.
When you assign a B value to a variable of type A, the Java language says that it is not possible to call the B-specific methods. Either do this:
B test = new B();
test.aMethodBelongsToB();
or this:
A test = new B();
((B) test).aMethodBelongsToB();
Note: since we are casting test to B can now call the B-specific methods ... on the result of the typecast subexpression.
It is always the declared type of the variable/expression that determines what method (signatures) are available to be called. The actual object reference only determines which actual method is called (if there is method overriding). To understand why, consider this:
public class C extends A{
#Override
public void abstractMethod(){
//implementation
}
...
}
and this (which is not valid Java ...):
A test;
if (something) {
test = new B();
} else {
test = new C();
}
test.aMethodBelongsToB(); // INVALID
If that last statement was legal (and it isn't!!) what should happen there if something is false?
If I create an object of sub class then will the super class object also be created from which the sub class is inherited? If not then how by creating a sub class of Thread class (in multi-threading) calls the Thread class constructor and creates a Thread object?
An instance of the subclass is an instance of the superclass. Only one object is created, but as part of that creation, constructor calls are chained together all the way up to java.lang.Object. So for example:
public class Superclass {
// Note: I wouldn't normally use public variables.
// It's just for the sake of the example.
public int superclassField = 10;
public Superclass() {
System.out.println("Superclass constructor");
}
}
public class Subclass extends Superclass {
public int subclassField = 20;
public Subclass() {
super(); // Implicit if you leave it out. Chains to superclass constructor
System.out.println("Subclass constructor");
}
}
...
Subclass x = new Subclass();
System.out.println(x instanceof Subclass);
System.out.println(x instanceof Superclass);
System.out.println(x.superclassField);
System.out.println(x.subclassField);
The output of this is:
Superclass constructor
Subclass constructor
true
true
10
20
... because:
The first thing any constructor does is call either another constructor in the same class, or a superclass constructor. So we see "Superclass constructor" before "Subclass constructor" in the output.
The object we've created is (obviously) an instance of Subclass
The object we've created is also an instance of Superclass
The single object we've created has both fields (superclassField and subclassField). This would be true even if the fields were private (which they usually would be) - the code in Subclass wouldn't be able to access a private field declared in Superclass, but the field would still be there - and still accessible to the code within Superclass.
The fact that we've got a single object with all the state (both superclass and subclass) and all the behaviour (any methods declared within Superclass can still be used on an instance of Subclass, although some may be overridden with more specializd behaviour) is crucial to understanding Java's approach to polymorphism.
Youre only creating one object when you create a subclass of another. It is an instance of both the subclass and all its parents. Example, I create a cat object. It is a cat, and at the same time a feline, mammal, and animal, and an Object.
When you create an object, it gets one piece of memory with one set of variables to hold the all of its data.
The subclass will contain fields from the child and any fields from its ancestors. So it's a single object that acts like the child and its ancestors. There is no parent class object created when you create a subclass.
No there Is only one Object there. There Is a misconception that constructor is for creating an object. But It actually for initializing an object. So when we created child class object along with the child class constructor the parent class constructor also executed because of the first line of the child class constructor either this() or super(). Now, look at the following code.
Public class P{
public P(){
System.out.println(this.hashCode()); // Parent class Constructor
}
}
public class C extends P{
public C(){
System.out.println(this.hashCode()); // Child Class constructor
}
}
public class Test{
public static void main(String [] args){
C c = new C();
System.out.println(c.hashCode());
}
}
If you run the code you can see There is only one HashCode. and an object just has one hashCode. If the parent class object would be created then there must be another hashCode for that object.
Here I am abbreviating with an example that
If a child class object is created, does it automatically create super class object?
class P{
P(){
System.out.println(this.hashCode()); // it will print 2430287
}
}
class C extends P{
C(){
System.out.println(this.hashCode()); // it will also print 2430287
}
}
public class Test{
public static void main(String... args){
C obj = new C();
System.out.println(c.hashCode()); //Again, it will print 2430287
}
}
If you compile and run this code you will find same Object hashCode is getting printed. So, this means there is only one object is created.
Now, how is the parent class object being initialized?
In this example only one object is created which is an instance of the child class, but there are two constructors (parent and child) being executed. But the constructor are just in context of child class only.
Nope.
It will not create instance of parent class. But certainly it will create an instance.And the object reference passed to child class. Hence instance is created at parent class and invoked by child class constructor. and child class methods operates.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Use of ‘super’ keyword when accessing non-overridden superclass methods
I'm new to Java and have been reading a lot about it lately to get more knowledge and experience about the language. I have a question about inherited methods and extending classes when the compiler inserts automatic code.
I've been reading that if I create class A with some methods including lets say a method called checkDuePeriod(), and then create a class B which extends class A and its methods.
If I then call the method checkDuePeriod() within class B without using the super.checkDuePeriod() syntax, during compilation will the compiler include the super. before checkDuePeriod() or will the fact that the compiler includes the super() constructor automatically when compiling the class imply the super. call of the methods that class B calls from class A?
I'm a little confused about this. Thanks in advance.
The super class's implementation of regular methods is not automatically invoked in sub classes, but a form of the super class's constructor must be called in a sub class's constructor.
In some cases, the call to super() is implied, such as when the super class has a default (no-parameter) constructor. However, if no default constructor exists in the super class, the sub class's constructors must invoke a super class constructor directly or indirectly.
Default constructor example:
public class A {
public A() {
// default constructor for A
}
}
public class B extends A {
public B() {
super(); // this call is unnecessary; the compiler will add it implicitly
}
}
Super class without default constructor:
public class A {
public A(int i) {
// only constructor present has a single int parameter
}
}
public class B extends A {
public B() {
// will not compile without direct call to super(int)!
super(100);
}
}
If you call checkDuePeriod() in B without super., means you want to invoke the method that belongs to the this instance (represented by this within B) of B. So, it equivalent to saying this.checkDuePeriod(), so it just doesn't make sense for the compiler to add super. in the front.
super. is something that you must explicitly add to tell the compiler that you want to call the A's version of the method (it is required specially in case B has overridden the implementation provided by A for the method).
Call of super() as a default constructor (constructor with no args) can be direct or non direct but it garants that fields of extendable class are properly initialized.
for example:
public class A {
StringBuilder sb;
public A() {
sb = new StringBuilder();
}
}
public class B extends A {
public B() {
//the default constructor is called automatically
}
public void someMethod(){
//sb was not initialized in B class,
//but we can use it, because java garants that it was initialized
//and has non null value
sb.toString();
}
}
But in case of methods:
Methods implement some logic. And if we need to rewrite logic of super class we use
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
//new check goes here
}
}
and if we want just implement some extra check, using the value returned from checkDuePeriod() of superclass we should do something like this
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
if(super.checkDuePeriod()){
//extra check goes here
}else{
//do something else if need
}
return checkResult;
}
}
First about the Constructors:
- When ever an object of a class is created, its constructor is initialized and at that time immediately the constructor of its super-class is called till the Object class,
- In this process all the instance variables are declared and initialized.
- Consider this scenario.
Dog is a sub-class of Canine and Canine is a sub-class of Animal
Now when Dog object is initialized, before the object actually forms, the Canine class object must be form, and before Canine object can form the Animal class object is to be formed, and before that Object class object must be form,
So the sequence of object formed is:
Object ---> Animal ---> Canine ---> Dog
So the Constructor of the Super-Class is Called before the Sub-Class.
Now with the Method:
The most specific version of the method that class is called.
Eg:
public class A{
public void go(){
}
}
class B extends A{
public static void main(String[] args){
new B().go(); // As B has not overridden the go() method of its super class,
// so the super-class implementation of the go() will be working here
}
}