Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

static methods

Hi,

I read
http://www.jchq.net/certkey/0102certkey.htm
as

A Static methods cannot be overriden in a child class but they can be hidden.. I was not clear on that. Any ideas, resources, links, sample code highly appreciated. thanks in advance.
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

>>>B redefines getMyName() to return the string "B" instead of "A" but if you call getName() on an instance of B, it will still return "A" because a static method cannot be overwritten

so it is still legal to overwrite right eventhough it is useless to do that. please advise
Avatar of gordon_vt02
gordon_vt02

Yes, it is normally useless to overwrite static methods like that and I can't think of many use cases where it would be necessary that you couldn't accomplish with abstract methods or interfaces, but it is legal to do so.
Avatar of gudii9

ASKER

I was going through following link
>>>http://www.jchq.net/certkey/0104certkey.htm
which says like

If you consider overriding the simple replacement of a method ina child class it is easy to believe at static methods can be overriden. Indeed I have had many emails from people that include code that appears to illustrate how static methods can be overriden. However this does not take into account the more subtle aspect of overriding which is the runtime resolution of which version a method will be called. The following code appears to illustrate how static methods can be overriden.

class Base{
    static   void amethod(){
    System.out.println("Base.amethod");

    }
}

public class Cravengib extends Base{
    public static void main(String arg[]){
    Cravengib cg = new Cravengib();
    cg.amethod();
    }
    static void amethod(){
    System.out.println("Cravengib.amethod");
    }
   
}
If you compile and run this code you will find it outputs the text Cravengib.amethod, which appears to be a nice illustration of overriding. However there is more to overriding than simple replacement of one method by another in a child class. There is also the issue of runtime resolution of methods based on the class type of the reference. and this can be illustrated by making the type of the reference (the part on the left hand side of the instance initialisation) to the type of the class that is being instantiated.










I was thinking it is just opposite of what we discussed. please advise
Avatar of gudii9

ASKER

I was more confused on following lines....


In the previous example, because the method called amethod is associated with the class, and not with any particular instance of the class it does not matter what the type of class being created it, just the type of the reference.. Thus if you change the line before the callng of amethod to read

Base cg= new Cravengib()

You will find that when you run the program you get an output of

Base.amethod

The reference cg is a reference (or pointer) of type Base to an instance in memory of the class Cravengib. When a call is made to a static method, the JVM does not check to see what the type is that is being pointed to i,t just calls the one instance of the method that is associated with the Base class.

By contrast when a method is overriden the JVM checks the type of the class that is being pointed to by the reference and calls the method associated with that type.





please advise


Static methods are associated with the class they are defined in, so:

A.staticMethod() is associated with the Class A and
B.staticMethod() is associated with the Class B

When you create a non-static method in the class, it is associated with each instance of that class.  When you call a non-static method, the JVM determines the actual type of the class and calls the method associated with that type -- which is why method overriding works.  When you call a static method of an instance, the JVM actually treats it as though you called <Class>.staticMethod();

In the attached code, you'll see that I've called the static method from an instance of the class (base.staticMethod() instead of Base.staticMethod()).  As noted, that is legal but not recommended and most IDEs will give you a warning message if you use the method that way.

I hope this helps clear things up.
public class Base {
    public static void staticMethod() {
        System.out.println("Base.staticMethod");
    }

    public void nonStaticMethod() {
        System.out.println("Base.nonStaticMethod");
    }
}

public class Cravengib extends Base {
    public static void staticMethod() {
        System.out.println("Cravengib.staticMethod");
    }

    @Override
    public void nonStaticMethod() {
        System.out.println("Cravengiv.nonStaticMethod");
    }
}

public class StaticTester {
     public static void main(String[] args) {
          Base base = new Base();
          Cravengib cravengib = new Cravengib();
          StaticTester tester = new StaticTester();

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Base.nonStaticMethod
          tester.callMethods(base);

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Cravengib.nonStaticMethod
          tester.callMethods(cravengib);

          // The following calls use the definition of
          // staticMethod() in the Cravengib class because
          // the JVM knows the type of cravengib is Cravengib
          // and it uses the static method definition associated
          // with that class instead of with the Base class.

          // Prints:
          // Cravengib.staticMethod
          // Cravengib.staticMethod
          Cravengib.staticMethod();
          cravengib.staticMethod();
     }

     public StaticTester() {
     }

     public void callMethods(Base base) {
          // The following two calls are equivalent because
          // the staticMethod() method is associated with the
          // class Base, not the instance of the class, "base."
          // The JVM does NOT check the type of "base," when
          // the method is called.  These two calls are
          // interchangeable, although it is best practice to
          // use only the first form so users are aware you
          // are calling a static method.
          Base.staticMethod();
          base.staticMethod();

          // When you call an instance method, the JVM has to
          // determine the actual class of "base" to support
          // polymorphism and inheritance.  For example, if
          // Base were an interface, there would be no actual
          // code to execute for instanceMethod() without
          // knowing which implementation of the interface was
          // provided.
          base.instanceMethod();
     }
}

Open in new window

Avatar of gudii9

ASKER

i tried to run above code like


class Base {
    public static void staticMethod() {
        System.out.println("Base.staticMethod");
    }

    public void nonStaticMethod() {
        System.out.println("Base.nonStaticMethod");
    }
}

 class Cravengib extends Base {
    public static void staticMethod() {
        System.out.println("Cravengib.staticMethod");
    }

    @Override
    public void nonStaticMethod() {
        System.out.println("Cravengiv.nonStaticMethod");
    }
}

public class StaticTester {
     public static void main(String[] args) {
          Base base = new Base();
          Cravengib cravengib = new Cravengib();
          StaticTester tester = new StaticTester();

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Base.nonStaticMethod
          tester.callMethods(base);

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Cravengib.nonStaticMethod
          tester.callMethods(cravengib);

          // The following calls use the definition of
          // staticMethod() in the Cravengib class because
          // the JVM knows the type of cravengib is Cravengib
          // and it uses the static method definition associated
          // with that class instead of with the Base class.

          // Prints:
          // Cravengib.staticMethod
          // Cravengib.staticMethod
          Cravengib.staticMethod();
          cravengib.staticMethod();
     }

     public StaticTester() {
     }

     public void callMethods(Base base) {
          // The following two calls are equivalent because
          // the staticMethod() method is associated with the
          // class Base, not the instance of the class, "base."
          // The JVM does NOT check the type of "base," when
          // the method is called.  These two calls are
          // interchangeable, although it is best practice to
          // use only the first form so users are aware you
          // are calling a static method.
          Base.staticMethod();
          base.staticMethod();

          // When you call an instance method, the JVM has to
          // determine the actual class of "base" to support
          // polymorphism and inheritance.  For example, if
          // Base were an interface, there would be no actual
          // code to execute for instanceMethod() without
          // knowing which implementation of the interface was
          // provided.
          base.instanceMethod();
     }
}




is gives error like

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
      The method instanceMethod() is undefined for the type Base

      at StaticTester.callMethods(StaticTester.java:75)
      at StaticTester.main(StaticTester.java:32)


please advise
Avatar of gudii9

ASKER

>>>


 @Override
    public void nonStaticMethod() {
        System.out.println("Cravengiv.nonStaticMethod");
    }



override is just for information. It does not really do anything here right. please advise
>           base.instanceMethod();

there is no method called instanceMethod()
Avatar of gudii9

ASKER

looks like Base class is already there..

i changed like

class Base44 {
    public static void staticMethod() {
        System.out.println("Base.staticMethod");
    }

    public void nonStaticMethod() {
        System.out.println("Base.nonStaticMethod");
    }
}

 class Cravengib extends Base44 {
    public static void staticMethod() {
        System.out.println("Cravengib.staticMethod");
    }

    @Override
    public void nonStaticMethod() {
        System.out.println("Cravengiv.nonStaticMethod");
    }
}

public class StaticTester {
     public static void main(String[] args) {
          Base44 base = new Base44();
          Cravengib cravengib = new Cravengib();
          StaticTester tester = new StaticTester();

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Base.nonStaticMethod
          tester.callMethods(base);

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Cravengib.nonStaticMethod
          tester.callMethods(cravengib);

          // The following calls use the definition of
          // staticMethod() in the Cravengib class because
          // the JVM knows the type of cravengib is Cravengib
          // and it uses the static method definition associated
          // with that class instead of with the Base class.

          // Prints:
          // Cravengib.staticMethod
          // Cravengib.staticMethod
          Cravengib.staticMethod();
          cravengib.staticMethod();
     }

     public StaticTester() {
     }

     public void callMethods(Base44 base) {
          // The following two calls are equivalent because
          // the staticMethod() method is associated with the
          // class Base, not the instance of the class, "base."
          // The JVM does NOT check the type of "base," when
          // the method is called.  These two calls are
          // interchangeable, although it is best practice to
          // use only the first form so users are aware you
          // are calling a static method.
          Base44.staticMethod();
          base.staticMethod();

          // When you call an instance method, the JVM has to
          // determine the actual class of "base" to support
          // polymorphism and inheritance.  For example, if
          // Base were an interface, there would be no actual
          // code to execute for instanceMethod() without
          // knowing which implementation of the interface was
          // provided.
          base.instanceMethod();
     }
}



stil output says


Exception in thread "main" java.lang.Error: Unresolved compilation problem:
      The method instanceMethod() is undefined for the type Base44

      at StaticTester.callMethods(StaticTester.java:75)
      at StaticTester.main(StaticTester.java:32)


please advise
see my previous comment
I just put instanceMethod() in there as a placeholder, it doesn't actually exist.  You can comment out that line.  And, yes, @Override is informational but is good practice when overriding methods because it will let you know about situations where you have the wrong method signature, a misspelling, or the parent class/interface's contract has changed and you are no longer overriding a method you thought you were.
Avatar of gudii9

ASKER

>>

what is meaning of place holder. when i comment it worked fire.

when i ran like



>>>>

class Base44 {
    public static void staticMethod() {
        System.out.println("Base.staticMethod");
    }

    public void nonStaticMethod() {
        System.out.println("Base.nonStaticMethod");
    }
}

 class Cravengib123 extends Base44 {
    public static void staticMethod() {
        System.out.println("Cravengib.staticMethod");
    }

    @Override
    public void nonStaticMethod() {
        System.out.println("Cravengiv.nonStaticMethod");
    }
}

public class StaticTester {
     public static void main(String[] args) {
          Base44 base = new Base44();
          Cravengib123 cravengib = new Cravengib123();
          StaticTester tester = new StaticTester();

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Base.nonStaticMethod
          tester.callMethods(base);

          // Prints:
          // Base.staticMethod
          // Base.staticMethod
          // Cravengib.nonStaticMethod
          tester.callMethods(cravengib);

          // The following calls use the definition of
          // staticMethod() in the Cravengib class because
          // the JVM knows the type of cravengib is Cravengib
          // and it uses the static method definition associated
          // with that class instead of with the Base class.

          // Prints:
          // Cravengib.staticMethod
          // Cravengib.staticMethod
          //Cravengib123.staticMethod();
        //  cravengib.staticMethod();
     }

     public StaticTester() {
     }





Below program

>>>class Base{
    static   void amethod(){
    System.out.println("Base.amethod");

    }
}

public class Cravengib extends Base{
    public static void main(String arg[]){
    Cravengib cg = new Cravengib();
    cg.amethod();
    }
    static void amethod(){
    System.out.println("Cravengib.amethod");
    }
   
}
>>>If you compile and run this code you will find it outputs the text Cravengib.amethod,



supposed to print
Cravengib.amethod
     public void callMethods(Base44 base) {
          // The following two calls are equivalent because
          // the staticMethod() method is associated with the
          // class Base, not the instance of the class, "base."
          // The JVM does NOT check the type of "base," when
          // the method is called.  These two calls are
          // interchangeable, although it is best practice to
          // use only the first form so users are aware you
          // are calling a static method.
          Base44.staticMethod();
          base.staticMethod();

          // When you call an instance method, the JVM has to
          // determine the actual class of "base" to support
          // polymorphism and inheritance.  For example, if
          // Base were an interface, there would be no actual
          // code to execute for instanceMethod() without
          // knowing which implementation of the interface was
          // provided.
       //   base.instanceMethod();
     }
}



it only gave output as

Base.staticMethod
Base.staticMethod
Base.staticMethod
Base.staticMethod


why

Cravengib.staticMethod
Cravengib.staticMethod

not printed.


also

>>>>


following code appears to illustrate how static methods can be overriden.

class Base{
    static   void amethod(){
    System.out.println("Base.amethod");

    }
}

public class Cravengib extends Base{
    public static void main(String arg[]){
    Cravengib cg = new Cravengib();
    cg.amethod();
    }
    static void amethod(){
    System.out.println("Cravengib.amethod");
    }
   
}
If you compile and run this code you will find it outputs the text Cravengib.amethod,



should have printed Base.amethod

according to top program ie

   protected static String getMyName() {
        return "A";
    }

    public String getName() {
        return getMyName();
    }
}

public class B extends A {
    public static String getMyName() {
        return "B";
    }
}

public class Main {
    public static void main(String[] s) {
        A a = new A();
        B b = new B();
       
        System.out.println(a.getName()); // prints "A"
        System.out.println(b.getName()); // prints "A"
    }
}





 explanation right...


please advise


I explained that in my first comment
Avatar of gudii9

ASKER

>>>There are two classes, A and B, with B extending A.  A defines a getName() method that calls the static method getMyName().  B redefines getMyName() to return the string "B" instead of "A" but if you call getName() on an instance of B, it will still return "A" because a static method cannot be overwritten.  If you were to call B.getMyName() directly, it would return 'B."



public class A {
    protected static String getMyName() {
        return "A";
    }

    public String getName() {
        return getMyName();
    }
}

public class B extends A {
    public static String getMyName() {
        return "B";
    }
}

public class Main {
    public static void main(String[] s) {
        A a = new A();
        B b = new B();
       
        System.out.println(a.getName()); // prints "A"
        System.out.println(b.getName()); // prints "A"
    }
}




why it 'prints "A" ' but not prints "B" as given by above explanation.





class Base{
    static   void amethod(){
    System.out.println("Base.amethod");

    }
}

public class Cravengib extends Base{
    public static void main(String arg[]){
    Cravengib cg = new Cravengib();
    cg.amethod();
    }
    static void amethod(){
    System.out.println("Cravengib.amethod");
    }
   
}
If you compile and run this code you will find it outputs the text Cravengib.amethod, which appears to be a nice illustration of overriding.

If Static methods cannot be overriden how 'Cravengib.amethod' is printed. please advise. I am still confused.





> why it 'prints "A" ' but not prints "B" as given by above explanation.

because getName()( is a method of A. So its calls the static method in A

> If Static methods cannot be overriden how 'Cravengib.amethod' is printed. please advise. I am still confused.

because (as I mentioned earlier) you are calling it via an instance of the class
You should not call static methods that way
Avatar of gudii9

ASKER

case 1:

>>>> why it 'prints "A" ' but not prints "B" as given by above explanation.

because getName()( is a method of A. So its calls the static method in A


case 2:
> If Static methods cannot be overriden how 'Cravengib.amethod' is printed. please advise. I am still confused.

because (as I mentioned earlier) you are calling it via an instance of the class
You should not call static methods that way



in both cases i am calling using instance of class right. Then why it printed A in case 1 but Cravengib.amethod in case 2.