5

Ever since I've started lurking on stackoverflow, I keep coming across programming concepts such as abstract classes, virtual functions, contracts, interfaces, etc., from a questions about other languages such as C++, Java, and C#.

As far as I can tell, most of these things are related to object oriented programming but aren't typically mentioned in Python tutorials because Python uses a combination of duck typing and magic to make such concepts redundant.

Nevertheless, I'd still like to know what they are.
What are abstract classes, virtual functions, contracts, interfaces, etc. (explained from a Python standpoint?) What other programming/OOP concepts should I know about that Python typically doesn't use or require you to know?

2
  • 2
    You should narrow down the scope of your question.
    – Matthieu
    Commented Jan 21, 2012 at 15:27
  • 2
    You should use Google, also. All the terms are pretty well defined in numerous places.
    – S.Lott
    Commented Jan 21, 2012 at 17:40

3 Answers 3

12

Abstract classes

Abstract classes are classes where some methods on the class are missing implementations. Python can (sort of) have these, but they're not quite as explicit as languages like Java, where the program will refuse to build. Typically, you inherit from an abstract class, and fill in the missing pieces, possibly using non-abstract methods from the abstract base class. Consider this class, in Python:

class Foo(object):
    def bar(self):
        # code code code

    def baz(self):
        raise NotImplementedError()

This class is kind of like an abstract class: we can't (realistically) call baz. (We can, but we'll get only exceptions.) Unlike Java or C++, where an abstract class is one that can't be instantiated, we can instantiate Foo. Python provides the abc module if you want more "abstract" classes.

Virtual Functions

Virtual functions are functions that, when called from a reference or pointer to a base class, will call the derived version of that function. In C++, if I have:

Foo *foo = ClassDerivedFromFoo();
foo->bar();

If bar isn't virtual, Foo::bar will get called. If it is, ClassDerivedFromFoo::bar will get called, if it exists. (The most-derived version will get called.)

In Python, an over-simplification would be that one can think of all functions as being virtual. This isn't quite correct: an instance's functions are really just attributes on that instance, and you can easily "monkey-patch" them to be an arbitrary function.

Contract

A contract is an agreement between a function and a caller of a function as to things that happen during the execution of a function. It's essentially the guarantees a function makes. To my knowledge, none of Python/Java/C++ enforce these explicitly. See Design by contract.

Interface

In a loose sense, an interface is the API (note that the "I" is interface) some piece of code (a module, class, function, etc.) exposes: it consists of what function calls are available, what types of data do they take and return, and what should that data be composed of.

Java has a special meaning for interface: An interface is a class-like description that contains member functions that contain no body. A class that contains all of those functions then, "implements" that interface. The interface can be used as a base class of sorts.

Python has similar, but much more abstract concepts. Take the enumerate function. It takes an "iterable", and returns the items from that iterable paired with increasing integers. (If you feed it ['a', 'b', 'c'] it spits out (0, 'a'), (1, 'b'), (2, 'c'). My example was a list, but it'll happily take any iterable: sets, dictionaries, generators, tuples, etc. As long as the item meets the interface of an iterable. This interface isn't (in Python) recorded explicitly, but as long as the object you pass in acts like an iterable, everything should just work. (This is duck typing.)

The Java "interface" idea is closely related to the general idea of abstract base classes, and some of the things the abc module can do might be interesting in regards to interfaces, as well.

1
  • Abstract classes are classes where some methods on the class are missing implementations. Not really (talking about C++)... An abstract class contains a pure virtual function which can very well be implemented in the level of the abstract class... The point is that it has to be reimplemented in any children class for this class to be able to be instantiated
    – JohnP
    Commented Jul 20, 2012 at 3:37
6

Most of the concepts you mention are not used in Python because those are concepts related to static binding while python uses dynamic binding.

Abstract classes are clases which should not be used directly, but have to be inherited. They are useful when you provide an implementation for some methods, but you are missing one or more. Since python either has or not a method, but cannot have it undefined, it doesn't make sense.

Virtual functions are a C++ concept. Each class has a ptable with pointers to the functions, so that when you call a function the compiler writes a pointer with what it should execute. If you declare a virtual function you add a level of indirection; the compiler doesn't write the address to execute, but at runtime it goes to the class ptable, looks up the pointer and executes that. This allows you to use polymorphism (this is a generic concept, it means a function is different depending on what object calls it, it exists in python, look it up in the wikipedia) so that if the declared object is of class CHILD that has a virtual function from PARENT it uses the function from CHILD and not PARENT (even if it is a pointer declared as PARENT). There is a small price that you have to keep a few pointers and a couple more CPU operations, but it is really inconsequential

Interface is basically a set operations that can be applied to an object. In languages like Java you declare an interface and a class implements it. Then you can just use objects that implement the interface indistinctly, you just call the functions and the appropriate function is called. In python you don't have such concept because you just call a function and if it exists in the object it is called.

Contracts is a runtime guarantee established in the documentation. For instance, in Java there is a contract that if compare() returns 0 then equals() should return true. There is no enforcement (unless you write tests for your class), but it is assumed that if you have the compare() method and it has returned 0 equals will return true. If you write a class that breaks the contract and somebody uses, it has a behaviour that is unexpected. This is useful in python; for instance, you can write a sort method that expects a list of objects with 2 functions comparable and equals, with the conditions I mentioned for java. Then the function can receive any array of objects that follow the contract, without knowing anything at all about the objects except that. If you pass objects that break the contract, it is not guaranteed what will happen; you may get the wrong order or the function may loop continously.

5
  • 1
    Good answer. I would add two things. 1) Abstract classes are emulated in Python by creating a class with methods which do nothing but raise NotImplementedError. Such classes can be instantiated but are useless in practice--they are provided as templates for subclasses.
    – Francis Avila
    Commented Jan 21, 2012 at 4:10
  • 2
    2) Python doesn't have native language support for interfaces but are still useful enough for large projects that there are PEPs about them, and Zope created a userspace implementation (example) which is used by Twisted.
    – Francis Avila
    Commented Jan 21, 2012 at 4:11
  • BTW, an example of an "abstract class" in the Python standard library is asynchat.async_chat.
    – Francis Avila
    Commented Jan 21, 2012 at 4:16
  • Thanks for the suggestions about interfaces and abstract classes. I actually recall that once I created one with the NotImplementedError.
    – Luis
    Commented Jan 21, 2012 at 6:12
  • @FrancisAvila the abc module exists for handling abstract base classes a bit more elegantly, but I think most Pythonistas generally just don't bother setting them up at all - it's just that much needless busywork when you can just rely on duck typing. I know that's my feeling on the matter, anyway :)
    – Karl Knechtel
    Commented Jan 21, 2012 at 10:56
-1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.