Em Python uma classe é definida com a keyword class. Exemplo:
class Basket:
# Always remember the *self* argument
def __init__(self,contents=None):
self.contents = contents or [] #esta funcao nunca pode retornar nada
def add(self,element):
self.contents.append(element)
def print_me(self):
result = ""
for element in self.contents:
result = result + " " + `element`
print "Contains:"+result
Novos conceitos:
- Todos os métodos têm de receber um argumento adicional explícitamente que corresponde ao objecto sobre o qual este método deve ser executado. É normal que esse argumento seja chamado self mas isto não é obrigatório. No entanto tem de ser sempre o primeiro argumento.
- Alguns métodos, como
__init__(com dois underscores antes e depois), são prédefinidos (podendo ser redefinidos) e têm significados especiais.__init__é o nome do construtor da classe e é portanto o método que é chamado quando se escreve algo Basket(args), logo após o espaço para o objecto ser criado. - Para aceder aos campos de uma classe é necessário escrever self.campo, isto porque escrever só campo mesmo dentro do código das funções da classe, seria uma construção ambígua (pelo facto de as variáveis locais não serem declarada).
- O método print_me deveria ser chamado __str__ que é o método "especial" implícitamente chamado sempre que uma representação, do objecto, em string é desejada. Assim seria possível chamar print para uma instância de Basket.
- A partir de Python 2.5 todas as classes devem herdar de object. Assim, Basket deveria ser class Basket(object). O facto de isto ser explícito é mau porque implica que se escreva um pouco mais em relação a outras linguagens mas, é também mais extensível.
Não existem mecanismos de protecção de variáveis ou métodos (não existem formas de dizer que algo é private ou protected ou mecanismos similares). A encapsulação é deixada a cargo do programador. No entanto, existe a convenção de que métodos e variáveis cujo nome começa com 1 underscore devem ser privados. Na minha opinião este é um dos defeitos do Python pois a linguagem em si não proíbe que se violem as abstracções. Existem outros defeitos mas lá iremos a seu tempo.
Para definir a superclasse de uma classe deve-se usar parentesis a seguir ao nome. Assim:
class SpamBasket(Basket):#...
Python suporta também herança múltipla. Para dizer que A é um subtipo de B e C usa-se:class A(B, C): É necessário chamar o construtor da superclasse mesmo que não seja necessário passar-lhe argumentos especiais. Desta forma, no __init__ do SpamBasket é necessário chamar o __init__ da sua superclasse,passando explícitamente o argumento self:Basket.__init__(self)
Para tornar isto ainda mais complexo (e confuso), o Python suporta metaclasses.Metaclasses são, como o nome indica, classes de classes. Não vou aqui discutiros mecanismos relacionados com as metaclasses pois são um mecanismoavançado para esta fase (e, honestamente, ainda não tive tempo para os practicare perceber os seus pontos fortes e fracos). Mais tarde vou tentar voltara este ponto pois acho que as linguagens que suportam metaclasses são "potentíssimas", apesar de ser um mecanismo raramente utilizado. Um bom usopara metaclasses é, por exemplo, a criação de uma metaclasse cujas instânciasdas suas classes, bem como os campos "static" da classe, são implicitamentetornados permanentes numa base de dados.
Quanto aos campos partilhados por todas as instâncias eles são definidos no corpo da classe:
class Foo(object):
x=23
y=x+22
def method(self):
print Foo.x #nao se pode escrever simplesmente print x
Notar que estes campos static são criados e os seus valores definidos quando a construção sintáctica class é avaliada, o que constrói um objecto do tipo class associado ao nome foo, algo que vem da filosofia de que tudo é um objecto de 1ª classe.