Should I use static binding? - java

I am learning late binding and static binding. Now I am confused about these code.
Here is my analysis:
hello() is non-static method, so we should use the dynamic binding, that is Child.
But there is no hello() method in child class, so go to its super class. Find hello() and print the first line "Hello from parent call calssMethod".
Since the classMethod() is static, so we should use static binding of c, that is also Child. So the output is "classMethod in Child".
So the out put should be
Hello from parent call calssMethod
classMethod in Child
class Parent{
public static void classMethod() {
System.out.println("classMethod in Parent");
}
public void instanceMethod() {
System.out.println("InstanceMethod in Parent");
}
public void hello() {
System.out.println("Hello from parent call calssMethod");
classMethod();
}
}
class Child extends Parent{
public static void classMethod() {
System.out.println("classMethod in Child");
}
public void instanceMethod() {
System.out.println("InstanceMethod in Child");
}
}
public class AA {
public static void main(String[] args) {
Child c = new Child();
c.hello();
}
}
Now, here is the problem. The IDE shows that the output is:
Hello from parent call calssMethod
classMethod in Parent
What's the right analysis process?
What if I make hello() method static?

Class (static) methods aren't overridden as instance methods. When you call the method 'hello()', it will use the method of the parent. When you refer to the class method there, you're referring to the method defined in the class 'Parent'.
Besides that, you should declare your Child instance as 'Parent c = new Child()'. Because you aren't adding new methods to your subclass but rather changing the implementation, you don't lose access to the methods of the subclass. If you were to have to method that returns a Parent object but you return a Child object declared as you did, you'd get problems.
EDIT: To add to this, usually there are 2 reasons to use inheritance: specialisation and extension.
For specialisation, you use define your methods in your superclass and your subclasses differ in how they implement those methods. For example a superclass Animal with subclasses Cat and Dog. 'Animal' has a method makeSound(). You can imagine that both subclasses are going to have a different implementation.
For extension, you use a superclass as a base class containing everything that overlaps. Other than that, the subclasses might have very different implementations and uses. A lot of interfaces have this kind of use.

Whenever we call child class's object, firstly it always find parent class and execute it. As you have static classMethod in both classes so it always run parent's classMethod not child's. You can achieve required answer only by overriding it.
If you make hello() method static even then it will give you same output.

Related

Did this following code apply late binding onto a static method? Polymorphism Java

So I was playing around in Java to understand the concept of polymorphism, and I wrote this:
public class Practice
{
public static void main(String[] args)
{
Parent p = new Child();
p.instanceMethod();
}
}
class Child extends Parent {
public void instanceMethod(){
System.out.println("child's instance method");
staticMethod();
}
public static void staticMethod() {
System.out.println("child's static method");
}
}
class Parent {
public void instanceMethod(){
System.out.println("parent's instance method");
staticMethod();
}
public static void staticMethod() {
System.out.println("parent's static method");
}
}
So the output of this is:
child's instance method
child's static method
Why is the the static method called upon from the child's class and not from it's static type, Parent's class?
Is it because, it is first called by the instance method in child's class, so at that point its type is already fully dynamic, aka child's type?
static methods don't 'do' polymorphism. At all.
non-static (i.e. instance) methods do. The signature of the method is bound entirely statically; the actual prospect of finding which method to actually run in the type hierarchy is done entirely dynamically (late binding).
For static methods, the entire thing is entirely static.
So, let's go through this code:
p.instanceMethod()
The expression p is of type Parent. The compiler looks at the signatures available in Parent and all its supertypes and determines that the full method signature that this invocation of instanceMethod() is attempting to invoke is void instanceMethod(). This call (Parent::instanceMethod()V in bytecode speak) is encoded in the emitted .class file.
At runtime, the system checks the actual runtime type of what the p expression resolves to (which is the new Child() you did earlier), and does dynamic dispatch. The public void instanceMethod() of Child, which clearly overrides the one from Parent, is selected and executed, therefore, "child's instance method" is printed.
staticMethod() in Child
Next, let's look at that staticMethod invoke: at compile time, javac determines that this is clearly a reference to the staticMethod() that's right there, in Child. It encodes, in the bytecode an INVOKESTATIC bytecode to Child::staticMethod()V. Dynamic dispatch is not now or ever applied to static method calls.
At runtime.. that method is called.
Simple as that.
Perhaps you expected that a static method still first checks the call context but that's not how java works.

why cant subclass objects hold super class constructor

Can anybody explain me what is the reason for a sub class object is incapable of holding a super class constructor?
class Alpha
{
String getType1()
{
return "alpha";
}
}
class Beta extends Alpha
{
String getType1()
{
return "beta";
}
String acc()
{
return "acc";
}
}
public static void main(String[] args)
{
Alpha a1=new Beta();
System.out.println(a1.getType1());
}
Here the output is "beta"; but object a1 doesnt have the visibility to acc()?
Nothing surprising here:
System.out.println(a1.getType1());
You are calling a method that is defined in the super class; and overridden in the a subclass. You create an instance of the subclass; and the method that gets executed ... is the overridden version.
The fact that Beta contains another method which is not at all used in your example anyway doesn't come into play here at all. And even if getType1() would be calling acc() - that would still work. That is the essence of of polymorphism!
And just to be precise: none of the methods you have in your classes is a constructor!
i just found the answer here we need to know that when we create beta() internally it will call all its super class default constructors hence the JVM knows that there is more than one existing class but when i declare and initialze like:
Alpha a1=new Beta();
eventhough the JVM knows that beta class is existing but your restricting your access of a1 by saying it is of the type Alpha class hence it cannot access your subclass methods.
When you create a object of child class making reference to its parent class as you did, you only have visible to those methods which belongs to the parent class. but if you want to call the child method using reference of parent class then you have to declare the body of the method in parent class which you have in child class. then it will be visible and this concept is called method overriding.
If you don't need to create the object of your super class then you can declare class as abstract and then you can simply put that method as abstract keyword shown as below.
abstract class Alpha
{
String getType1()
{
return "alpha";
}
abstract String acc();
}
class Beta extends Alpha
{
String getType1()
{
return "beta";
}
#Overriding
String acc()
{
return "acc";
}
}
public static void main(String[] args)
{
Alpha a1=new Beta();
System.out.println(a1.getType1());
}
Child classes are privileged to access to default constructor of parent class until unless you have restricted it with private access modifier.
Your cases is an example of method overloading. Actual call to overloaded method is resolved at run time. Which method will be called, depends on the concrete object not type of object. Here your reference is of type Alpha but the object is of Type Beta. So method getType1() here will print beta which is correct behavior.

Static method in parent class does not allow child to add a non static method?

The below code does not compile:
public class Child extends Parent{
void foo() {
}
}
class Parent{
public static void foo(){}
}
Why can't I declare a non static method in my child class? Overriding is not allowed in this case as the method is static, so why is the compiler not allowing us to declare an instance method?
Because Child Classes inherent all methods and fields from the Parent Class. In this case there will be two Child#foo() methods in the Child class since it would not have been overridden if this had had compiled.
That method has the same signature as the static method, and since you can't override static methods (and it is still a part of Parent, which Child still gets), you can't declare another foo with the same signature in a child method.
To be more technical, the JLS specifies:
It is a compile-time error for the body of a class to declare as members two methods with override-equivalent signatures (§8.4.2).
If you changed the signature; that is, if you declared an argument in the child class' method, then it would be okay.
You can't change access of inherited methods while overriding them - static stays static.
Same thing applies when overloading methods in single class - you can use same method name but methods need to accept different parameters.
Because the child recognize foo() from parent and itself. So you can't not create with your current code. However, you can declare new foo() in your child like this:
public class Child extends Parent{
public static void foo() {
}
}
class Parent{
public static void foo(){
}
}
More detail here: You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

Why cannot we override static method in the derived class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can we override static method in Java?
We cannot override the static methods of the base class.
Actually I tried something like this:
// Base class
public class StaticExampleImpl {
protected String name="overriding";
public static void display(){
System.out.println("static method display : base class");
}
}
Then the derived class is as follows:
//derived class
public class StaticDemo extends StaticExampleImpl {
// cannot override the static methods...
//#Override
public static void display(){
System.out.println("child!!! static method display");
}
public static void main(String[] args) {
StaticDemo d=new StaticDemo();
d.display(); // derived class display is called rather than Base class.
}
}
So, when I uncomment the #Override method, it gives error as "Static methods cannot be overriden". But with commenting it works fine. So, when we create the Objects and call the static methods with the instances, those work fine. so what is the difference??
because static methods are not get inherited.
When you uncomment #Override it means you are trying to override the
static method which is not possible thats why you are getting an
error.
But when you comment //#Override it means you are declaring a new
method in child class.
Static methods does not belong to an instance of a class, it belongs to the actual class.
When you call d.display();, you are really calling the static method of the StaticDemo d reference's static method.
if you did :
StaticExampleImpl d2 = new StaticDemo();d2.display(), you will find that it calls the base class's display.
However, don't do this. It leads to confusing code, and is a bad way to implement inheritance poorly.
Overriding depends the an instance of a class. polymorphismis that you can subclass a class and the objects implementing those subclasses will have different behaviors for those method defined in the superclass (and overridden in the subclasses) .static methods does not belong to an instance of a class so the concept is not applicable.
Static methods cannot be inherited. If you want to call the 'base' class static method, you have to explicitely call StaticExampleImpl.display().
Static methods are bound to class they can't be inherited thats why you can't have base class static method in derived class.
If you are trying to override a static method, there is probably something wrong with your design.
OOP and Polymorphism allows you to do the following:
public class MyClass1 {
public String toString() { return "MyClass1 Instance"; }
}
public class MyClass2 extends MyClass1 {
#Override
public String toString() { return "MyClass1 Instance"; }
}
public void printSomething(MyClass1 myclass1){
System.out.println(myclass1);
}
Inside printSomething, the toString method which is going to be called is the one on the runtime type of myClass1: when you pass inside printSomething an instance of MyClass2, its compile-type will be MyClass1 but its runtime type will be MyClass2
It is clear that to use polymorphism you need objects instances, where the actual runtime type could different from the compile type. Static methods however do not belong to any object instance, but to the class. Why don't you explain us what you are trying to achieve?
The following code:
StaticExampleImpl one = new StaticExampleImpl();
StaticDemo two = new StaticDemo();
StaticExampleImpl three = two;
one.display();
two.display();
three.display();
Will yield the following output:
static method display : base class
child!!! static method display
static method display : base class
As you can see, the method does not get inherited. This is why they are called 'static methods': they are called statically, not dynamically, as instance methods would be. The compile-time type of the class is what matters when calling static methods, not the runtime type.
This is also why you shouldn't call static methods through object instances. Always call them like this:
StaticExampleImpl.display();
StaticDemo.display();
This completely takes away the confusion that might (will) come up when people expect inheritance to work for these methods.
any static block in java, may be static variables, methods are loaded when the class is loaded. You probably know about class loader in java. So thing is static block (methods, variables or anything is static) is loaded once. So you can’t actually override any static block.
Commenting #Override means that you are writing another static method in sub class, but not just overriding base class method.

calling parent class method from child class object in java

I have a parent class which has a method, in the child class I override that parent class's method. In a third class I make an object of child and by using that object I want call the method of parent class. Is it possible to call that parent class method ? If yes, then how?
If you override a parent method in its child, child objects will always use the overridden version. But; you can use the keyword super to call the parent method, inside the body of the child method.
public class PolyTest{
public static void main(String args[]){
new Child().foo();
}
}
class Parent{
public void foo(){
System.out.println("I'm the parent.");
}
}
class Child extends Parent{
#Override
public void foo(){
//super.foo();
System.out.println("I'm the child.");
}
}
This would print:
I'm the child.
Uncomment the commented line and it would print:
I'm the parent.
I'm the child.
You should look for the concept of Polymorphism.
Use the keyword super within the overridden method in the child class to use the parent class method. You can only use the keyword within the overridden method though. The example below will help.
public class Parent {
public int add(int m, int n){
return m+n;
}
}
public class Child extends Parent{
public int add(int m,int n,int o){
return super.add(super.add(m, n),0);
}
}
public class SimpleInheritanceTest {
public static void main(String[] a){
Child child = new Child();
child.add(10, 11);
}
}
The add method in the Child class calls super.add to reuse the addition logic.
First of all, it is a bad design, if you need something like that, it is good idea to refactor, e.g. by renaming the method.
Java allows calling of overriden method using the "super" keyword, but only one level up in the hierarchy, I am not sure, maybe Scala and some other JVM languages support it for any level.
Say the hierarchy is C->B->A with A being the base class.
I think there's more to fixing this than renaming a method. That will work but is that a fix?
One way is to refactor all the functionality common to B and C into D, and let B and C inherit from D: (B,C)->D->A Now the method in B that was hiding A's implementation from C is specific to B and stays there. This allows C to invoke the method in A without any hokery.
NOTE calling parent method via super will only work on parent class,
If your parent is interface, and wants to call the default methods then need to add interfaceName before super like IfscName.super.method();
interface Vehicle {
//Non abstract method
public default void printVehicleTypeName() { //default keyword can be used only in interface.
System.out.println("Vehicle");
}
}
class FordFigo extends FordImpl implements Vehicle, Ford {
#Override
public void printVehicleTypeName() {
System.out.println("Figo");
Vehicle.super.printVehicleTypeName();
}
}
Interface name is needed because same default methods can be available in multiple interface name that this class extends. So explicit call to a method is required.

Categories