Blog‎ > ‎

Dynamic Language Behavior in Java

posted Oct 7, 2010, 1:17 PM by Lewis Baumstark   [ updated Oct 7, 2010, 3:00 PM ]
One of the cool things about Ruby is that it lets you re-define ("override") methods attached to objects, not just at the class level (as we typically think of with Java, C#, C++, etc.):

Ruby object-overriding example

# simple example of overriding the to_s method on an object in Ruby
s = String.new("billy bob")
puts s  # will print "billy bob"
def s.to_s
    "john boy"
end
puts s # will print "john boy"

I've known all along that Java had this notion of an anonymous inner class, i.e., a situation where a non-instantiable entity (either an interface or an abstract class) can be instantiated directly as long as you immediately define its abstract methods.  For example:

Java Anonymouse Inner Class Example

public interface IChatty {
    String talk();
}

...

// somewhere else we actually work with the IChatty interface
IChatty talker = new IChatty() {
    public String talk()
    {
        return "Hello World!";
    }
};

System.out.println(talker.talk());  // will print "Hello World!" to the console

What I didn't realize until I tried it out today is that this works for regular Java classes, too:

Java Override-Method-at-Object-Creation Example

class Abc {
    public int getX() { return 32; }
}

...

// somewhere else we actually work with the class Abc:
Abc abc = new Abc() {
    public int getX() { return 64; }
};

System.out.println(abc.getX()); // will print "64" (not 32) to the console


Cool, huh?

Of course, it's still not as powerful as Ruby.  Java can only re-define an object's method once: at object-creation time.  Ruby can re-define a method on an object as many times as needed.  But it still strikes me as interesting that this is allowed; presumably, it's a feature of Java's all-methods-are-virtual semantics.
Comments