Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent to late static binding(PHP) in other popular languages

Tags:

java

c++

python

php

<?php
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // Here comes Late Static Bindings
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test(); // Outputs "B"
?>

I want to get an equivalent in Java...so something like

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

    public static void test(){
        who(); //<<< How to implement a static:: thing here???
    }
}

class B extends A {
     public static void who(){
        System.out.println("B");
     };

     public static void main(String[] args){
        B.test(); // Outputs "A" but I want "B"
     }
}

I want the who() call inside A::test to resolve as in PHP 5.3 by calling B::who.

EDIT: I know there is no "standard way" of doing this in most popular languages. I'm looking for hacks and such. Also, is this possible in C/C++, or any other popular OOP language?

This is not for any real design on anything. I'm just being curious.

like image 612
jetru Avatar asked Jul 16 '12 21:07

jetru


1 Answers

Not possible in Java. (At least not without ugly reflection hacks.)

I encourage you to rethink your design and rely on proper objects.

Related question:

  • Can I override and overload static methods in Java?

Edit: B.test() will (or can at least according to spec) be compiled into a call to A.test(), so there's no way to discover how the call was made from within A.test(). In other words, there's no way to let the behaviour of A.test depend on if it was called through A.test() or B.test().

Since you're asking out of curiosity, here's AFAIK the closest "solution".

  1. Overload test with a test(Class<?> c) which takes as argument the class which defines the intended who method.
  2. Hide (note that you can't override) test() in class B.
  3. And change the implementation of A.test slightly.

In code:

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

    public static void test() {
        test(A.class);
    }

    public static void test(Class<?> c) {
        //who(); //<<< How to implement a static:: thing here???
        try {
            c.getMethod("who").invoke(null); // Call static who on given class.
        } catch (Exception e) {
        }
    }

}

public class B extends A {
     public static void who(){
        System.out.println("B");
     }

     public static void test() {
         test(B.class);
     }

     public static void main(String[] args){
        A.test(); // Outputs "A"
        B.test(); // Outputs "B"
     }
}
like image 153
aioobe Avatar answered Oct 24 '22 20:10

aioobe