Dynamic Language Behavior in Java

Post date: Oct 7, 2010 8:17:42 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.