23
Programação I / Introdução à Programação Capítulo D, "Classes and Objects" João Pedro Pedroso 2019/2020

Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Programação I / Introdução à ProgramaçãoCapítulo D, "Classes and Objects"

João Pedro Pedroso

2019/2020

Page 2: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Últimas aulas:I Programação orientada a objetos

Hoje:I Programação orientada a objetos (cont.).

Page 3: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Programação orientada a objetos: exemplo com frações

I Classe para representar frações:I métodos: operações habituais com frações

I Frações:I dois inteiros: numerador e denominadorI devem ser dados ao construtor

Page 4: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Fração: construtor

1 class Fraction:2 def __init__(self, top, bottom):3 self.num = top # the numerator is on top4 self.den = bottom # the denominator is on the bottom5

6 def __str__(self):7 return str(self.num) + "/" + str(self.den)8

9 def getNum(self):10 return self.num11

12 def getDen(self):13 return self.den

I output:

>>> myfraction = Fraction(3,4)>>> print(myfraction)3/4>>> myfraction.getNum()3>>> myfraction.getDen()4

Page 5: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Objectos são mutáveis

I Podemos alterar os atributos de uma instância:

myfraction.num = 5myfraction.den = 3

I Podemos fazer o mesmo em métodos da classe, utilizadoself.num e self.den

I Situação em que isto é útil: simplificação de fraçõesI Exemplo: as frações 12/16 e 6/8 podem ambas ser

representadas por uma fração irredutível: 3/4I Redução: divisão do numerador e do denominados pelo maior

divisor comum

Page 6: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Estado e métodos: Fraction

Page 7: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Algoritmo de Euclides:I Para reduzirmos uma fracção aos termos mais simples:

I encontrar o maior divisor comum (GCD)I dividir numerador e denominador por GCDI → reduzir objectos Fraction sempre que são credos

I Algoritmo de Euclides:Se n divide m, então n é o GCD. Caso contrário, o GCD éo GCD a n e ao resto da divisão de m por n.

I Versão recursiva

1 def gcd (m, n):2 if m % n == 0:3 return n4 else:5 return gcd(n, m%n)

I Versão iterativa:

1 def gcd(m,n):2 while m%n != 0:3 m, n = n, m%n4 return n

I Utilização:

>>> gcd(12,16)4

Page 8: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Simplificação de frações

I Com a função gcd podemos implementar um método parasimplificar frações:

class Fraction:[... ]def simplify(self):

common = gcd(self.num, self.den)

self.num = self.num // commonself.den = self.den // common

I Notas:I gcd é uma função, não é um método da classe (helper

function);I o método simplify não devolve nada, apenas altera o objeto

(mutator method);

Page 9: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Identicidade de dois objetosI Tal como na realidade, dois objetos podem ser iguais sem

serem o mesmo; esta ambiguidade existe também em objetosPython;

I Para verificar se duas referências dizem respeito ao mesmoobjeto, utiliza-se o operador is:

>>> myfraction = Fraction(3,5)>>> yourfraction = Fraction(3,5)>>> myfraction is yourfractionFalse

Page 10: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Igualdade superficial de dois objetos

I Se atribuirmos outro a a, as variáveis passam a ser aliasespara o mesmo objecto: igualdade superficial — shallow identity

>>> ourfraction = myfraction>>> myfraction is ourfractionTrue

Page 11: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Comparação de dois objetos

I O operador ==, se não for redefinido, devolve a igualdadesuperficial:

>>> a = Fraction(3,5)>>> b = Fraction(3,5)>>> a == bFalse

I Para compararmos o conteúdo de dois objectos — igualdadeprofunda — podemos definir uma função:

def sameFraction(f1,f2):return (f1.getNum() == f2.getNum()) \

and (f1.getDen() == f2.getDen())>>> sameFraction(a, b)True

Page 12: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Comparação e os seus riscos

I Python permite-nos escolher o significado dos operadores, taiscomo ==

p = Point(4, 2)s = Point(4, 2)print("== on Points returns", p == s) # shallow equality test here

a = [2,3]b = [2,3]print("== on lists returns", a == b) # deep equality test on lists

I em Point comparação com == devolve False;I em list comparação com == devolve True.

Page 13: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Recomendação:

Beware of ==“When I use a word,” Humpty Dumpty said, in a ratherscornful tone, “it means just what I choose it to mean —neither more nor less.”

Alice in Wonderland

Page 14: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Cópia de objectosI Para duplicarmos um objecto (cópia shallow):

>>> import copy>>> a = Fraction(4,5)>>> b = copy.copy(a)>>> a == b>>> a == bFalse>>> sameFraction(a,b)True

I Cópia em profundidade: deepcopy (copia o objecto, e todosobjectos nele embebidos):

>>> a = [[1,2,3],4]>>> b = copy.copy(a)>>> a[0][1] = 999>>> b[[1, 999, 3], 4]

>>> a = [[1,2,3],4]>>> b = copy.deepcopy(a)>>> a[0][1] = 999>>> b[[1, 2, 3], 4]

I Com deepcopy, a e b ficam objectos completamenteseparados.

Page 15: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Fração: construtor

class Fraction:def __init__(self,top,bottom):

self.num = top # the numerator is on topself.den = bottom # the denominator is on the bottom

def __str__(self):return str(self.num) + "/" + str(self.den)

def getNum(self):return self.num

def getDen(self):return self.den

def simplify(self):common = gcd(self.num, self.den)self.num = self.num // commonself.den = self.den // common

Page 16: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Operações aritméticasI Podemos definir uma função que calcula a soma de duas

frações:a

b+

c

d=

ad + cb

bd

class Fraction:[...]def add(self,otherfraction):

newnum = self.num*otherfraction.den + self.den*otherfraction.numnewden = self.den * otherfraction.den

common = gcd(newnum,newden)

return Fraction(newnum//common,newden//common)

I Utilização:

>>> f1 = Fraction(1,2)>>> f2 = Fraction(1,4)>>> f3 = f1.add(f2)>>> print(f3)3/4

Page 17: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Operações aritméticas: métodos especiaisI Podemos definir um método especial para a adição de duas

frações, que torna a utilização de frações mais natural;I O método existente para isso é __add__:

class Fraction:[...]def __add__(self,otherfraction):

newnum = self.num*otherfraction.den + self.den*otherfraction.numnewden = self.den * otherfraction.den

common = gcd(newnum,newden)

return Fraction(newnum//common,newden//common)

I Utilização:

>>> f1 = Fraction(1,2)>>> f2 = Fraction(1,4)>>> f3 = f1 + f2>>> print(f3)3/4

I Nota: nas operações com inteiros e em vírgula flutuante, asituação é exatamente a mesma: executar 4+5 é equivalente a<

Page 18: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Operações aritméticas: métodos especiais

Método Resultado__add__ self + other__sub__ self - other__mul__ self * other__truediv__ self / other__floordiv__ self // other. . .

Page 19: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Operadores relacionais: métodos especiais

Método Uso Descrição__lt__ x < y devolve True se x for menor do que y__le__ x <= y devolve True se x for menor do que, ou igual a y__eq__ x == y devolve True se x for igual a y__ne__ x != y devolve True se x for diferente y__ge__ x >= y devolve True se x for maior do que, ou igual a y__gt__ x > y devolve True se x for maior do que y

Page 20: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Métodos especiais

I A lista completa de métodos especiais pode ser consultada em:https://docs.python.org/3.8/reference/datamodel.html

I Incluí metodos para:I Adaptação/personalização de tipos (type customization);I Comparação/relação entre objetos;I Controlar acesso a atributos da classe;I Implementar tipos compostos e o respetivo acesso (e.g.,

mapas/dicionários personalizados);I Emular tipos e conversões numéricos;I . . .

Page 21: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Noções estudadas esta semanaclasse tipo composto definido pelo programador

instanciar criar um objeto de uma determinada classeinstância o mesmo que objeto

objeto variável de um determinado tipo (a sua classe),frequentemente utilizada para modelar uma coisa ouconceito do mundo real; junta informação (dados) eoperações relevantes para esse tipo composto dedados

construtor cada classe é uma fábrica de objetos; se tiver definidoum método de inicialização, esse método seráexecutado ao criar um objeto, para dar um valorcorreto aos atributos

método de inicialização em Python: __init__método função definida dentro de uma classe, que é invocada

partindo de instâncias dessa classeatributo um dos dados que constituí uma instância

Page 22: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Noções estudadas esta semana

programação orientada a objetos estilo de programação em quedados e operações que os manipulam são definidosem classes e métodos

linguagem orientada a objetos linguagem com capacidades deprogramação orientada a objetos

igualdade superficial (shallow equality) igualdade de referências:verifica se duas variáveis se referem ao mesmo objeto

igualdade profunda (deep equality) igualdade dos valores guardadosnum objeto

cópia superficial (shallow copy) cópia do conteúdo de um objeto edas referências a outros objetos nele imbricados

cópia profunda (deep copy) cópia do conteúdo de um objeto e,recursivamente, de todos os objetos que nele estãodefinidos

Page 23: Programação I / Introdução à Programação - Capítulo D ...jpp/Prog1920/teorica-22_oop-2.pdf · Objectossãomutáveis I Podemosalterarosatributosdeumainstância: myfraction.num=5

Aula de hoje:I Programação orientada a objetos

Próximas aulasI Programação orientada a objetos (continuação)