protocols, inheritance and polymorphism

Steven Bethard steven.bethard at gmail.com
Wed Nov 24 07:35:20 CET 2004


Donn Cave wrote:
> Rather than embrace
> subtype polymorphism through inheritance, however, I see it
> as evidence that no one has figured out how to make static
> typing really work with OOP.

I'm not sure I follow your argument here.  Java interfaces provide the 
same sort of protocol-based typing as Python does (though of course you 
have do declare interfaces everywhere to make them work this way). 
Going back to my earlier Python example:

 >>> def process_rules(rules):
...     for rule in rules:
...         print rule.name
...

the corresponding Java might look something like:

public interface Rule {
     public Object getName();
}

public class RuleProcessor {
     public void processRules(Iterable<Rule> rules){
         for (Rule rule: rules) {
             System.out.println(rule.getName())
         }
     }
}

Note that because Java is statically typed, you have to declare all the 
appropriate interfaces: Iterable is in java.lang, and Rule is declared 
above.  In Python, the interfaces are implied by the use, and left 
undeclared.

Of course, you have to declare your interfaces in a suitably generic 
manner.  I could have written this replacing Iterable<Rule> with 
Collection<Rule> or List<Rule>, but Iterable<Rule> is the type that 
makes the fewest commitments about the parameter and still allows me to 
iterate over the Rule objects.  Similarly, I could have written getName 
to return a String, but by declaring getName with Object as a return 
type, I make only the necessary commitment that getName returns a value.

The annoying thing, of course, is what you do when suddenly *one* use of 
a Rule does require, say, a String result of getName:

public class OtherRuleProcessor {
     public void processRules(Iterable<Rule> rules){
         for (Rule rule: rules) {
             String[] s = rule.getName().split('\\s')
         }
     }
}

Do I now declare a new interface for this Rule and add another 
implements clause to all my classes that implement the original Rule as 
well?  Do I make the original Rule interface less general by changing 
the return type from Object to String?  It can get nasty rather quickly...

Python, of course, avoids this by not declaring types. =)

Steve



More information about the Python-list mailing list