views:

158

answers:

5

In Python, class methods can be inherited. e.g.

>>> class A:
...  @classmethod
...  def main(cls):
...   return cls()
...
>>> class B(A): pass
...
>>> b=B.main()
>>> b
<__main__.B instance at 0x00A6FA58>

How would you do the equivalent in Java? I currently have:

public class A{
    public void show(){
        System.out.println("A");
    }
    public void run(){
        show();
    }
    public static void main( String[] arg ) {
        new A().run();
    }
}
public class B extends A{
    @Override
    public void show(){
        System.out.println("B");
    }
}

I'd like to call B.main() and have it print "B", but clearly it will print "A" instead, since "new A()" is hardcoded.

How would you change "new A()" so that it's parameterized to use the class it's in when called, and not the hard-coded class A?

A: 

I think this isn't possible. Here's why:

In Java, the implementation of a method is determined by the instance's run-time type. So, to execute B.show(), you need to have an instance of B. The only way I could see to do this, if the method that constructs the instance is supposed to be inherited, is to use Class.newInstance() to construct an instance of a type that's not known at runtime.

The problem with that is that within a static method, you have no reference to the containing class, so you don't know whose newInstance method to call.

Why do you want to do this, though? There may be some better way to achieve whatever it is you want to achieve.

danben
A: 

In your example I wouldn't put your main method inside of A. This is setup as the entry point into the system (you can't be in B if you are specifically entering into A).

In the example below I created class A, B, and C. Class C instantiates A and B and runs them. Notice that in C I created an A, a B, and another A that I instantiate as a B. My output is: A B B

Hopefully this makes sense.

public class A { 
public void show(){ 
    System.out.println("A"); 
  } 

public void run(){ 
    show(); 
  }  
} 

public class B extends A { 
 @Override 
 public void show(){ 
    System.out.println("B"); 
    } 
 } 

public class C {
public static void main(String[] args) {
    A a = new A();
    B b = new B();
    A anothera = new B();

    a.show();
    b.show();
    anothera.show();
   }
}
SOA Nerd
+1  A: 

Your class B does not have a main method and static methods are not inherited.

fastcodejava
`B` does have a `main`; the one inherited from `A`.
T.J. Crowder
Be careful static methods are not truly inherited.
Matt
+1  A: 

The only way I can see this happening is to find whatever is calling A.main( String[] arg ) and change it to call B.main instead.

B.main:

   public static void main( String[] arg ) {
        new B().run();
    }

How is your program started? Is there a batch file, shortcut, etc? Something you can change? Where does A.main get called?

Skip Head
This is effectively what I'm doing, by giving class B it's own main(). I was just hoping I could have it inherit the main() from A, since they're identical, other than the class used to instantiate.
Chris S
+1  A: 

Static methods in java are not classmethods they are staticmethods. In general it is not possible to know which class reference the static method was called from.

Geoff Reedy
Thanks, I was afraid of that.
Chris S