Dziedziczenie

Po co jest dziedziczenie?

Kod nr 21:

class Person:

    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name

    def is_employee(self):
        return False


class Employee(Person):

    def is_employee(self):
        return True


emp = Person("Bartek")
print(emp.get_name(), emp.is_employee())

emp = Employee("Sylwia")
print(emp.get_name(), emp.is_employee())

Klasa object jest bazowa dla wszystkich obiektów.

Kod nr 22:

class Person(object):

    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name

    def is_employee(self):
        return False


class Employee(Person):

    def is_employee(self):
        return True


emp = Person("Bartek")
print(emp.get_name(), emp.is_employee())

emp = Employee("Sylwia")
print(emp.get_name(), emp.is_employee())

Jak zrobić konstruktor w klasie pochodnej?

Kod nr 23:

class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)


class Student(Person):
    def __init__(self, fname, lname):
        Person.__init__(self, fname, lname)

Kod nr 24:

class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)


class Student(Person):
    def __init__(self, fname, lname):
        super().__init__(fname, lname)

Kod nr 25:

class Person:
    def __init__(self, fname, lname):
        self.firstname = fname
        self.lastname = lname

    def printname(self):
        print(self.firstname, self.lastname)


class Student(Person):
    def __init__(self, fname, lname, year):
        super().__init__(fname, lname)
        self.graduationyear = year

    def welcome(self):
        print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)

Ćwiczenie1. Dodaj do powyższych klas więcej pól i metod i poćwicz ich wywoływanie.

Polimorfizm

Polimorfizm to inaczej “wielopostaciowość”. Innymi słowy, mechanizmy pozwalające programiście używać wartości, zmiennych i podprogramów na kilka różnych sposobów.

Jak to jest zaimplementowane w języku Python?

Ćwiczenie. Stwórz klasy dotyczące osoby, książki i zwierzęcia (z kilkoma polami) do ćwiczenia poniższych konstrukcji.

Polimorfizm wbudowanych operatorów

Kod nr 26:

a = 4
b = 2
c = a + b
print(c)
s1 = "abc"
s2 = "xyz"
s3 = s1 + s2
print(s3)

Polimorfizm wbudowanych metod/funkcji

Kod nr 27

print(len("abcde"))
print(len([3, -2, 8, 2, 2, -2, 0]))

Przeciążanie funkcji (?) - domyślna wartość argumentu

Kod nr 28

def sumxyz(x, y, z=0):
    return x + y + z


print(sumxyz(1, 2, 3))
print(sumxyz(3, 4))

Przeciążenie metody w klasie - domyślna wartość argumentu

Kod nr 29

class Number:
    def sum(self, a=None, b=None, c=None):
        s = 0
        if a is not None and b is not None and c is not None:
            s = a + b + c
        elif a is not None and b is not None:
            s = a + b
        else:
            s = a
        return s


x = Number()
print(x.sum(1))
print(x.sum(3, 5))
print(x.sum(1, 2, 3))

Przeciążanie operatora w klasie

Kod nr 30

class Student:

    def __init__(self, m1, m2):
        self.m1 = m1
        self.m2 = m2

    def __add__(self, other):
        m1 = self.m1 + other.m1
        m2 = self.m2 + other.m2
        s3 = Student(m1, m2)
        return s3


s1 = Student(58, 59)
s2 = Student(60, 65)
s3 = s1 + s2
print(s3.m1)

Tzw “magiczne metody”

Polimorfizm metod w różnych klasach (bez związku między klasami)

Kod nr 31

class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print(f"I am a cat. My name is {self.name}. I am {self.age} years old.")

    def make_sound(self):
        print("Meow")


class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print(f"I am a dog. My name is {self.name}. I am {self.age} years old.")

    def make_sound(self):
        print("Bark")


cat1 = Cat("Kitty", 2.5)
dog1 = Dog("Fluffy", 4)
animals = [cat1, dog1]

for animal in animals:
    animal.make_sound()
    animal.info()
    animal.make_sound()

Polimorfizm przy dziedziczeniu (przesłanianie metod)

Kod nr 32

from math import pi


class Shape:
    def __init__(self, name):
        self.name = name

    def area(self):
        pass

    def fact(self):
        return "I am a two-dimensional shape."

    def __str__(self):
        return self.name


class Square(Shape):
    def __init__(self, length):
        super().__init__("Square")
        self.length = length

    def area(self):
        return self.length ** 2

    def fact(self):
        return "Squares have each angle equal to 90 degrees."


class Circle(Shape):
    def __init__(self, radius):
        super().__init__("Circle")
        self.radius = radius

    def area(self):
        return pi * self.radius ** 2


figures = [Shape("Nazwa"), Circle(2), Square(3)]
for f in figures:
    print(f.area())

Statyczność

“Statyczne pola w klasie”

Kod nr 33

import math


class Point:
    name = "W"

    def __init__(self, a, b):
        self.x = a
        self.y = b

    def move(self, mx, my):
        self.x += mx
        self.y += my

    def dist(self, other=None):
        if other is None:
            return math.sqrt(self.x ** 2 + self.y ** 2)
        else:
            return math.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)


p1 = Point(2, 2)
p1.name = "A"
p1.move(-1, 1)
p2 = Point(3, 4)
p3 = Point(2, 0)
p1.name = "R"
Point.name = "T"
p3.name = "g"
Point.name = "v"

Statyczne metody

Kod nr 34

from datetime import date


class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def frombirthyear(cls, name, year):
        return cls(name, date.today().year - year)

    @staticmethod
    def isadult(age):
        return age > 18


person1 = Person('mayank', 21)
person2 = Person.frombirthyear('mayank', 1996)

print(person1.age)
print(person2.age)

print(Person.isadult(22))

Kod nr 35:

class Student:
    name = 'unknown'  # class attribute

    def __init__(self):
        self.age = 20  # instance attribute

    @classmethod
    def tostring(cls):
        print('Student Class Attributes: name=', cls.name)


Student.tostring()
s1 = Student()
s1.tostring()
s1.name = "Tom"
s1.tostring()

Kod nr 36:

class Student:
    name = 'unknown'  # class attribute

    def __init__(self):
        self.age = 20  # instance attribute

    @classmethod
    def tostring(cls):
        print('Student Class Attributes: name=', cls.name, ', age=', cls.age)


# Student.tostring()
s1 = Student()
# s1.tostring()
s1.name = "Tom"
# s1.tostring()

Sortowanie

Kod nr 37

class Employee:

    def __init__(self, name, dept, salary):
        self.name = name
        self.dept = dept
        self.salary = salary

    def __repr__(self):
        return '{' + self.name + ', ' + self.dept + ', ' + str(self.salary) + '}'


workres = [
    Employee('James', 'Finance', 80000),
    Employee('Robert', 'Construction', 60000),
    Employee('James', 'Telecom', 70000)
]

# 1. Sort by only `dept` attribute
workres.sort(key=lambda x: x.dept)

# [{Robert, Construction, 60000}, {James, Finance, 80000}, {James, Telecom, 70000}]
print(workres)

# 2. Sort by `name` attribute, followed by `dept` attribute
workres.sort(key=lambda x: (x.name, x.dept))

# [{James, Finance, 80000}, {James, Telecom, 70000}, {Robert, Construction, 60000}]
print(workres)

# 3. Sort by `name` attribute in reverse order,
# , followed by `dept` attribute in reverse order
workres.sort(key=lambda x: (x.name, x.dept), reverse=True)

# [{Robert, Construction, 60000}, {James, Telecom, 70000}, {James, Finance, 80000}]
print(workres)

# 4. Sort by `name` attribute in the natural order,
# , followed by numeric `salary` attribute in reverse order
workres.sort(key=lambda x: (x.name, -x.salary))

# [{James, Finance, 80000}, {James, Telecom, 70000}, {Robert, Construction, 60000}]
print(workres)

Kod nr 38

from operator import attrgetter


class Employee:

    def __init__(self, name, dept):
        self.name = name
        self.dept = dept

    def __repr__(self):
        return '{' + self.name + ', ' + self.dept + '}'


workers = [
    Employee('James', 'Telecom'),
    Employee('Robert', 'Construction'),
    Employee('James', 'Finance')
]

# sort by `name` and `dept` attribute
workers.sort(key=attrgetter('name', 'dept'))

# [{James, Finance}, {James, Telecom}, {Robert, Construction}]
print(workers)

Kod nr 39

class Employee:

    def __init__(self, name, dept):
        self.name = name
        self.dept = dept

    def __repr__(self):
        return '{' + self.name + ', ' + self.dept + '}'


workers = [
    Employee('James', 'Telecom'),
    Employee('Robert', 'Construction'),
    Employee('James', 'Finance')
]

# sort by `name` and `dept` attribute
sortByNameAndDept = sorted(workers, key=lambda x: (x.name, x.dept))

# [{James, Finance}, {James, Telecom}, {Robert, Construction}]
print(sortByNameAndDept)

Kod nr 40

class Person(object):

    def __init__(self, firstname, lastname):
        self.first = firstname
        self.last = lastname

    def __eq__(self, other):
        return ((self.last, self.first) == (other.last, other.first))

    def __ne__(self, other):
        return ((self.last, self.first) != (other.last, other.first))

    def __lt__(self, other):
        return ((self.last, self.first) < (other.last, other.first))

    def __le__(self, other):
        return ((self.last, self.first) <= (other.last, other.first))

    def __gt__(self, other):
        return ((self.last, self.first) > (other.last, other.first))

    def __ge__(self, other):
        return ((self.last, self.first) >= (other.last, other.first))

    def __repr__(self):
        return "%s %s" % (self.first, self.last)
Operator Metoda
== __eq__
!= __ne__
< __lt__
<= __le__
> __gt__
>= __ge__

Ćwiczenia. Stwórz listę osób, książek, filmów itp i posortują ją różnymi sposobami.