天天看點

day17 面向對象及作業day17 面向對象

day17 面向對象

一、類和對象

1.定義類

定義類用代碼描述清楚你這個類是擁有哪些相同功能哪些相同屬性的對象的集合。

功能 - 對應的是函數

屬性 - 儲存資料的變量(在類中叫屬性)

文法:

class 類名:

類的說明文檔

類的内容

說明:

class - 關鍵字,固定寫法

類名 - 程式員自己命名

要求:是辨別符,不是關鍵字

規範:見名知義;駝峰式命名(第二個單詞開始,單詞之間采用首字母大寫),首字母大寫;不使用系統函數名、類名、子產品名

: - 固定寫法

類的說明文檔 - 本質就是多行注釋

類的内容 - 包括屬性和方法

屬性分為:類屬性(類的字段)和對象屬性

方法分為:對象方法、類方法和靜态方法

注解:方法就是定義在類中的函數

class Students:
    """
    學生類
    """
    pass
           

2.定義對象(建立對象)

文法:類()

stu1 = Students()
stu2 = Students()
print(stu1, stu2)
           

二、對象方法

1.方法

定義在類中的函數就是方法

2.對象方法

怎麼定義:直接定義在類中的函數(定義函數前不用加裝飾器)

怎麼調用:用對象來調用 - 對象.函數名()

特點:自帶參數self,在調用的時候self不用傳參,系統會自動将目前對

class Person:
    """
    人類
    """
    def sleep(self):
        print(f'self:{self}')
        print('睡覺')

    def eat(self, food):
        print(f'吃{food}')


p1 = Person()   # 建立對象
p2 = Person()
print(f'p1:{p1} p2:{p2}')
p1.sleep()


p1.eat('面條')
           

三、構造方法和初始化方法

1.構造函數/構造方法

函數名和類名相同,并且是用來建立對象的方法就是構造方法

Python的構造函數在建立類的時候由系統自動建立,程式員隻需要在建立對象的時候自動調用

2.初始化方法:_init_

定義類的時候可以根據需求在類中添加對象方法:init,添加的時候要保證函數名是__init__,第一個參數是self。

除此以外我們可以随意添加參數和函數體。

使用類建立對象的時候,系統會自動調用這個類中的__init__方法

調用構造方法建立對象的時候需不需要參數,需要幾個參數看這個類的__init__方法除了self以外有沒有額外的參數

魔法方法:類中,方法名由__開頭并且以__結尾的方法就是魔法方法。所有的魔法方法都是自動調用。

class Dog:
    def __init__(self):
        print('__init__被調用')
           

下面的這個函數的定義由系統自動完成

def Dog():

建立好的對象 = 建立對象并且申請記憶體儲存對象

建立好的對象.init()

return 建立好的對象

dog1 = Dog()  # 沒有調用__init__,就列印了,說明隻要一建立對象,__init__就被調用
dog2 = Dog()
           
class Cat:
    def __init__(self, name, age):
        print('貓:__init__被調用')
        print(f'name:{name}, age:{age}')


cat1 = Cat('小花', 3)
cat2 = Cat(name='洋芋', age=2)
           

=====補充:=

def __init__(x, y):
    print('自己的__init__被調用')
    print(f'x:{x},y:{y}')


def Cat(*args, **kwargs):
    print(f'=={kwargs}')   # kwargs:{'x': 10, 'y': 20}
    __init__(*args, **kwargs)
    print(f'args:{args}')
    print(f'kwargs:{kwargs}')   # kwargs:{'x': 10, 'y': 20}


c1 = Cat(10, 20)
c2 = Cat(x= 10, y=20)

*x, y = 10, 20, 30, 40  # *的打包功能


def func2(a, b, c):
    print(f'a:{a}, b:{b}, c:{c}')


func2(100, 200, 300)
print('====')
alist = (100, 200, 300)
print(*alist)   # *的解包功能
print('====')
func2(*alist)   # func2(100, 200, 300)

dict1 = {'a': 10, 'b': 20, 'c': 30}
# print(**dict1)
# **dict1 => a= 10, b=20,c=30
func2(**dict1)   # func2(a=10, b=20, c=30)
           

四、屬性

1.屬性

屬性是用來描述類的資料特征。屬性的本質是儲存資料的變量。

2.對象屬性和類屬性

1)類屬性

怎麼定義:直接定義在類中的變量就是類屬性

怎麼使用:通過類來使用,類.類屬性

什麼時候用:屬性值不會因為對象的不同而不一樣,這種屬性就定義成類屬性

2)對象屬性

怎麼定義:以‘self.屬性名=值’的形式定義在__init__方法中

怎麼使用:通過對象來使用,對象.對象屬性

什麼時候用:屬性值會因為對象的不同而不一樣,這種屬性就定義成對象屬性

class Person:
    # num就是類屬性
    num = 61

    # name,age,gender是對象屬性
    def __init__(self):
        self.name = '小明'
        self.age = 18
        self.gender = '男'


print(Person.num)
Person.num = 60
print(Person.num)

p1 = Person()
print(p1.name, p1.age, p1.gender)
p1.name = '小胡'
print(p1.name)


class Circle:
    # pi就是類屬性
    pi = 3.1415926

           

3.對象屬性賦初值的三種方式

方式1:賦一個固定的值,

方式2:使用沒有預設值的參數指派

方式3:使用有預設值的參數指派

class Dog:
    def __init__(self, name, color, breed='土狗', gender='母'):
        self.breed = breed  # 方式3
        self.name = name  # 方式2
        self.gender = gender # 方式3
        self.color = color  # 方式2
        self.age = 1   # 方式1

    # __repr__方法在目前類的對象被列印的時候會被自動調用,這個方法的傳回值(必須是字元串)是什麼就列印什麼
    def __repr__(self):
        # 列印誰,self就是誰
        # return f'{self.name, self.breed, self.gender, self.color, self.age}'
        return str(self.__dict__)

dog1 = Dog('财财', '黃色')
print(f'dog1:{dog1}')    # dog1:abc

dog2 = Dog('花花', '白色', gender='公')
print(f'dog2:{dog2}')
           

練習:定義一個商品類,擁有屬性:價格、名稱、産地、類型、生産日期、保存期限

要求:建立對象的時候價格、名稱、生産日期必須指派、産地預設溫州、保存期限預設1年、類型預設食品

列印對象的時候列印商品所有的基本資訊

class Goods:
    def __init__(self, price, name, date, place='溫州', expiration_date='1年', goods_type='food'):
        self.price = price
        self.name = name
        self.date = date
        self.place = place
        self.expiration_date = expiration_date
        self.goods_type = goods_type

    def __repr__(self):
        return f'<{str(self.__dict__)[1:-1]}>'


goods1 = Goods('100元', 'xx', '2021.2.1')
print(goods1)

           

五、方法

1.對象方法

怎麼定義:直接在類中定義函數(函數前不加裝飾器)

怎麼調用:對象.對象方法()

特點:自帶參數self,self不用傳參,誰調用self就指向誰

什麼時候用:如果實作函數的功能需要用到對象屬性,一定是對象方法

2.類方法

怎麼定義:在定義函數前加裝飾器@classmethod

怎麼調用:類.類方法()

特點:自帶參數cls,cls不用傳參,系統将目前類傳給cls(誰調用就指向誰)

什麼時候用:實作函數的功能,在不需要對象屬性的時候需要類就使用類方法

3.靜态方法:

怎麼定義:在定義函數前裝裝飾器@staticmethod

怎麼調用:類.靜态方法

特點:沒有預設參數

什麼時候用:實作函數的功能既不需要目前類的對象也不需要目前類,就使用靜态方法

class Test:

    def func1(self):
        print('對象方法')

    @classmethod
    def func2(cls):
        print('類方法')

    @staticmethod
    def func3():
        print('靜态方法')


t1 = Test()

# 用對象調用對象方法
t1.func1()

# 用類調用類方法
Test.func2()


class Circle:
    pi = 3.1415926

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

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

    @classmethod
    def set_pi(cls, value):
        cls.pi = value
           

六、作業

  1. 定義一個狗類和一個人類:

    狗擁有屬性:姓名、性别和品種 擁有方法:叫喚

    人類擁有屬性:姓名、年齡、狗 擁有方法:遛狗

    class Dog:
    
        def __init__(self, name, gender, breed):
            self.name = name
            self.gender = gender
            self.breed = breed
    
        def bark(self):
            return '汪汪'
    
    
    class Person:
    
        def __init__(self, name, age, dog=None):
            self.name = name
            self.age = age
            self.dog = dog
    
        def walk_dog(self):
            print(f'{self.dog.name},叫一個:{self.dog.bark()}')
    
    
    p1 = Person('小明', '18')
    p1.dog = Dog('旺财', '母', '土狗')
    p1.walk_dog()  
               
  2. 定義一個矩形類,擁有屬性:長、寬 擁有方法:求周長、求面積
    class Rectangle:
        def __init__(self, length, width):
            self.length = length
            self.width = width
    
        def perimeter(self):
            return (self.length + self.width) * 2
    
        def area(self):
            return self.length * self.width
    
    
    r1 = Rectangle(3, 4)
    print(r1.perimeter())
    print(r1.area())
               
  3. 定義一個二維點類,擁有屬性:x坐标、y坐标 擁有方法:求目前點到另外一個點的距離
    class TwoDimensionalPoint:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def coordinate(self):
            return self.x, self.y
    
    
    def distance(coordinate1:tuple, coordinate2:tuple):
        return ((coordinate1[0] - coordinate2[0]) ** 2 + (coordinate1[1] - coordinate2[1]) ** 2) ** 0.5
    
    
    d1 = TwoDimensionalPoint(1, 2)
    d2 = TwoDimensionalPoint(3, 2)
    print(distance(d1.coordinate(), d2.coordinate()))
               
  4. 定義一個圓類,擁有屬性:半徑、圓心 擁有方法:求圓的周長和面積、判斷目前圓和另一個圓是否外切
    class Circle:
        pi = 3.14
    
        def __init__(self, radius, center=(0, 0)):
            self.radius = radius
            self.center = center
    
        def perimeter(self):
            return 2 * Circle.pi * self.radius
    
        def area(self):
            return Circle.pi * self.radius ** 2
    
    
    def isexcircle(radius1, radius2, center1:tuple, center2:tuple):
        if ((center1[0] - center2[0])**2 + (center1[1] - center2[1])**2) ** 0.5 == radius1 + radius2:
            print('兩圓相切')
        else:
            print('兩圓不相切')
    
    
    c1 = Circle(2, center=(1, 2))
    c2 = Circle(3, center=(2, 1))
    print(c1.perimeter(), c1.area())
    print(c2.perimeter(), c2.area())
    
    isexcircle(c1.radius, c2.radius, c1.center, c2.center)
               
  5. 定義一個線段類,擁有屬性:起點和終點, 擁有方法:擷取線段的長度
    class Line:
        def __init__(self, start_point:tuple, end_point:tuple):
            self.start_point = start_point
            self.end_point = end_point
    
        def length(self):
            return ((self.start_point[0] - self.end_point[0]) ** 2 + (self.start_point[1] - self.end_point[1]) ** 2) ** 0.5
    
    
    d1 = Line((2, 3), (3, 2))
    print(d1.length())