day14 類和對(duì)象

類方法和靜態(tài)方法

類中的方法分為:對(duì)象方法, 類方法和靜態(tài)方法

1.對(duì)象方法

a.直接聲明在類中
b.有默認(rèn)參數(shù)self
c.通過(guò)對(duì)象去調(diào)用: 對(duì)象.對(duì)象方法()

2.類方法

a.在聲明前添加@classmethod
b.有默認(rèn)參數(shù)cls, 調(diào)用的時(shí)候不需要給cls傳參蹬铺。系統(tǒng)會(huì)自動(dòng)將調(diào)用當(dāng)前類方法的類傳給cls避除。
cls最終指向的是一個(gè)類瓦灶,類可以做的事情cls都可以做
c.通過(guò)類去調(diào)用: 類.類方法()

3.靜態(tài)方法

a.在聲明前添加@staticmethod
b.沒(méi)有默認(rèn)參數(shù)
c.通過(guò)類去調(diào)用:類.類方法()

4.對(duì)象方法、類方法和靜態(tài)的方法的選擇

a.什么時(shí)候使用對(duì)象方法:
當(dāng)實(shí)現(xiàn)函數(shù)的功能需要用到對(duì)象的屬性的時(shí)候就使用對(duì)象方法

b.什么時(shí)候使用類方法:
實(shí)現(xiàn)函數(shù)的功能不需要對(duì)象的屬性紊服,但是需要類的時(shí)候就使用類方法

c.什么時(shí)候使用靜態(tài)方法
實(shí)現(xiàn)函數(shù)的功能既不需要對(duì)象的屬性,也不需要類的時(shí)候,就使用靜態(tài)方法

class Person():

    # 類的字段
    num = 61

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

    # 對(duì)象方法
    def eat(self, food):
        # print(Person.num)
        print('%s在吃%s' % (self.name, food))

    # 類方法
    @classmethod
    def destroy(cls):
        # cls = Person
        print('cls:',cls)
        print('人類破壞環(huán)境')

        # 可以用cls來(lái)創(chuàng)建對(duì)象
        p1 = cls('小明')
        p1.eat('面包')

        # 可以用cls使用類的字段
        print(cls.num)

        # 可以用cls調(diào)用類相關(guān)的方法

    # 靜態(tài)方法
    @staticmethod
    def hit_animal():
        print('人類毆打小動(dòng)物!')
        print(Person.num)


print('Person:', Person)
Person.destroy()
Person.hit_animal()


# 練習(xí):
# 數(shù)學(xué)類柜候,屬性:pi  功能:求兩個(gè)數(shù)的和,  求一個(gè)圓的面積
class Math:
    pi = 3.1415926

    @staticmethod
    def sum(num1, num2):
        return num1+num2

    @classmethod
    def circle_area(cls, r):
        return cls.pi * (r ** 2)

    # @staticmethod
    # def circle_area(r):
    #     return Math.pi * (r ** 2)


class YTMath(Math):
    pi = 3.14



print(Math.sum(10, 3.10))
print(Math.circle_area(2))

print(YTMath.circle_area(2))


私有化

1.私有化

在類中,可以通過(guò)在屬性名前买猖,或者方法名前加(注意:不能以結(jié)尾),那么這個(gè)屬性或者方法就會(huì)變成私有的改橘。
私有的屬性和方法在類的外部不能使用

class Person:
    __num = 100    # 私有的屬性
    __number__ = 200   # 不是私有屬性

    def __init__(self):
        self.name = '張三'
        self.__age = 18

    def __show_message(self):
        print(Person.__num)
        print('名字:', self.name, '年齡:', self.__age)

    def func1(self):
        self.__show_message()


# print(Person.__num)

p1 = Person()
print(p1.name)

# p1.__show_message()
p1.func1()

# print(p1.__age)

print(Person.__number__)

2.私有化原理
python中沒(méi)有真正的私有化, 不能從訪問(wèn)權(quán)限上控制屬性和方法的使用。
只是在名字前有但是沒(méi)有以結(jié)尾的名字前再加了'_類名',導(dǎo)致不能直接通過(guò)原屬性和方法名進(jìn)行訪問(wèn)

class Dog:
    def __init__(self, name, color):
        self.__name = name
        self.__color = color


dog1 = Dog('大黃', '黃色')
print(dog1.__dict__)
# print(dog1.__name, dog1.__color)
print(dog1._Dog__name)


getter和setter

1.getter和setter

如果希望在獲取對(duì)象屬性之前要做點(diǎn)兒別的事情玉控,就給這個(gè)屬性添加getter飞主;
如果希望在給對(duì)象屬性賦值之前做點(diǎn)兒別的事情,就給這個(gè)屬性添加setter

2.給對(duì)象屬性添加getter

a.屬性命名的時(shí)候,屬性名前加_; 例如:self._age = 0
b.聲明一個(gè)函數(shù)碌识,函數(shù)的名字是屬性名(不要下劃線),不需要額外參數(shù),有返回值碾篡;并且函數(shù)前使用@property修飾。
這個(gè)函數(shù)的返回值就是獲取屬性的結(jié)果
例如:
@property
def age(self):
return 年齡相關(guān)值

c.當(dāng)需要獲取屬性的時(shí)候通過(guò)對(duì)象.不帶下劃線的屬性筏餐;例如:對(duì)象.age

3.給對(duì)象屬性添加setter

想要給對(duì)象屬性添加setter开泽,必須先給它添加getter
a.屬性命名的時(shí)候,屬性名前加_; 例如:self._age = 0
b.聲明一個(gè)函數(shù)魁瞪,函數(shù)的名字是屬性名(不要下劃線)穆律,需要一個(gè)額外的參數(shù),不用返回值;
并且函數(shù)前使用@getter名.setter修飾
例如:
@age.setter
def age(self, value):
self._age = value

c.當(dāng)需要給屬性賦值的時(shí)候,通過(guò)對(duì)象.不帶下劃線的屬性來(lái)賦值导俘;例如: 對(duì)象.age = 100

"""

class Person:
    def __init__(self, name='小紅'):
        self.name = name
        self._age = 60
        self.sex = '男'

    # 這兒的age函數(shù)就是屬性_age的getter方法
    @property
    def age(self):
        if self._age < 1:
            return '嬰兒'
        elif self._age < 18:
            return '未成年'
        elif self._age < 50:
            return '中年'
        else:
            return '老年'

    # 這兒的age函數(shù)就是屬性_age的setter
    @age.setter
    def age(self, value):
        if not isinstance(value, int):
            print('年齡必須是整數(shù)!!!!')
            raise ValueError

        if not (0 <= value <= 100):
            print('年齡超出范圍!!!!')
            raise ValueError

        self._age = value


p1 = Person()
# print(p1.age)  # 希望取到的不是年齡值峦耘,而是年齡對(duì)應(yīng)的階段
# p1.age = '12'    # 存 0
# p1.age = '100'   # 150

# 這兒實(shí)質(zhì)是在調(diào)用_age的getter方法
print(p1.age)

# 這兒實(shí)質(zhì)是在調(diào)用_age的setter方法: p1.age(80)
p1.age = 80


# 練習(xí):聲明一個(gè)時(shí)間類,有一個(gè)屬性是以秒的形式保存時(shí)間
# 不斷的輸入時(shí)間旅薄,以'XX:XX'的形式輸入辅髓。輸入多少個(gè)時(shí)間就保存多少個(gè)時(shí)間對(duì)象。知道輸入end為止

class Time:
    def __init__(self):
        self._second= 0

    @property
    def second(self):
        return self._second

    # '01:11 - 71'
    @second.setter
    def second(self, value: str):
        times = value.split(':')
        self._second = int(times[0])*60 + int(times[1])

    補(bǔ)充:打印自己聲明的類的對(duì)象的時(shí)候少梁,默認(rèn)打印的是:<模塊名.類名 object at 對(duì)象地址>
    如果不希望以默認(rèn)的方式去打印對(duì)象洛口,可以實(shí)現(xiàn)__repr__魔法方法。打印對(duì)象的時(shí)候就會(huì)打印這個(gè)方法的返回值
    
    這個(gè)函數(shù)的返回值必須是字符串

    def __repr__(self):
        return '時(shí)間:'+ str(self.second)



10:20   -> time.秒 = 620
1:20   ->  time.秒 = 80
# times = []
# while True:
#     value = input('時(shí)間:')
#     if value == 'end':
#         break
#     # 創(chuàng)建對(duì)象凯沪,并且將輸入的內(nèi)容賦給時(shí)間
#     t = Time()
#     t.second = value
#     times.append(t)
#
# print(times)


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

    # def __repr__(self):
    #     return '[' + self.__class__.__module__+'.'+\
    #            self.__class__.__name__+' object at '+ hex(id(self))+']'
    def __repr__(self):
        # return 'name:%s, age:%d' % (self.name, self.age)
        return str(self.__dict__)[1:-1]


stu1 = Student('小明', 29)   # >>__main__.Student object at 0x1077a9550<<
stu2 = Student('小??', 18)   # name:小??, age:18
print(stu1, stu2)


類的繼承

繼承

python中的類支持繼承第焰,并且支持多繼承。
python中默認(rèn)情況是繼承自object(object是python中所有類的基類)

a.什么是繼承
一個(gè)類可以繼承另外一個(gè)類著洼,繼承者我們叫子類樟遣,被繼承者叫父類。繼承就是讓子類直接擁有父類中的內(nèi)容

b.可以繼承哪些內(nèi)容
所有的屬性和方法都可以繼承

class Person(object):
    num = 61

    # 注意:__slots__對(duì)應(yīng)的值不會(huì)被繼承
    __slots__ = ('name', 'age', 'sex')

    def __init__(self):
        self.name = '張三'
        self.age = 0
        self.sex = '男'

    def show_message(self):
        print('%s你好嗎?' % self.name)


# Student類繼承自Person類
class Student(Person):
    pass


# 創(chuàng)建學(xué)生對(duì)象
stu1 = Student()
# 對(duì)象屬性可以繼承
print(stu1.name, stu1.age, stu1.sex)

# 類的字段可以繼承
print(Student.num)

# 對(duì)象方法可以繼承
stu1.show_message()



p1 = Person()
# p1.color = '黃色'
stu1.color = '白色'
print(stu1.color)


添加方法

子類除了擁有從父類繼承下來(lái)的屬性和方法身笤,還擁有屬于自己的屬性和方法

在子類中添加方法

a.添加一個(gè)新的方法
直接在子類中聲明其他的方法;
添加后子類可以調(diào)用自己的方法也可以調(diào)用父類的方法豹悬,但是父類不能調(diào)用子類的方法

b.重寫父類的方法: 重新實(shí)現(xiàn)父類的方法
完全重寫 - 覆蓋父類的功能 - 直接在子類中重新實(shí)現(xiàn)父類的方法
部分重寫 - 保留父類的功能,添加新的功能 - 在子類中實(shí)現(xiàn)父類方法的時(shí)候通過(guò)super()去調(diào)用父類的方法液荸,
再添加新的功能
注意:a.可以子類的方法中通過(guò)super()去調(diào)用父類的方法
super(類, 對(duì)象) - 獲取對(duì)象中父類的部分(要求對(duì)象是這個(gè)指定的類的對(duì)象)
b.靜態(tài)方法中不能使用super()

c.類中方法的調(diào)用過(guò)程
通過(guò)對(duì)象或者類調(diào)用方法的時(shí)候瞻佛,先看當(dāng)前類中是否聲明過(guò)這個(gè)方法,如果聲明過(guò)就直接調(diào)用當(dāng)前類對(duì)應(yīng)的方法;
如果當(dāng)前類中沒(méi)有聲明過(guò)娇钱,會(huì)去找父類中有沒(méi)有聲明過(guò)這個(gè)方法伤柄,聲明過(guò)就調(diào)用父類的方法;
如果父類中也沒(méi)有聲明過(guò),就去找父類的父類...以此類推文搂,直到object中也沒(méi)有聲明過(guò)适刀,程序才會(huì)崩潰

class Person:
    # 類的字段
    num = 61

    # 對(duì)象屬性
    def __init__(self):
        self.name = '張三'
        self.age = 0
        self.sex = '男'

    def fun1(self):
        print('Person的對(duì)象方法')

    # 方法
    def show_message(self):
        print('%s,你好嗎?' % self.name)

    @staticmethod
    def info():
        print('我是人類')


class Student(Person):

    def study(self):
        print('%s在學(xué)生' % self.name)

    @classmethod
    def message(cls):
        super().info()
        print('我是學(xué)生!')

    # 完全重寫
    @staticmethod
    def info():
        print('我是學(xué)生C翰洹1屎怼取视!')

    # 保留父類的功能
    def show_message(self):
        super().show_message()
        print('我去上學(xué)~')
        super().fun1()


添加屬性

1.添加類的字段

直接在子類中添加新的字段

2.添加對(duì)象屬性

繼承對(duì)象屬性是通過(guò)繼承父類的init方法繼承下來(lái)的

如果想要在保留父類繼承下來(lái)的對(duì)象屬性的前提下,添加新的對(duì)象屬性常挚,
需要在子類的init方法中作谭,通過(guò)super()去調(diào)用父類的init方法

class Person:
    num = 61

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


class Student(Person):
    number = 100

    def __init__(self, name):
        super().__init__(name)
        self.study_id = '001'


print(Student.number, Student.num)

stu1 = Student('小明')
print(stu1.name, stu1.age, stu1.study_id)

# 練習(xí):
# 聲明一個(gè)動(dòng)物類,有屬性:年齡奄毡,顏色折欠,類型。
#  要求創(chuàng)建動(dòng)物對(duì)象的時(shí)候類型和顏色必須賦值吼过,年齡可以賦值也可以不賦值
# 聲明一個(gè)貓類锐秦,有屬性:年齡,顏色那先,類型, 愛(ài)好
# 要求創(chuàng)建貓對(duì)象的時(shí)候农猬,顏色必須賦值,年齡和愛(ài)好可以賦值也可以不賦值售淡,類型不能賦值


class Aniaml:
    def __init__(self, type, color, age=0):
        self.type = type
        self.color = color
        self.age = age


class Cat(Aniaml):
    def __init__(self, color, age=0, hobby=''):
        super().__init__('貓科', color, age)
        self.hobby = hobby


an1 = Aniaml('犬科', '黃色')
an2 = Aniaml('犬科', '黃色', 10)

cat1 = Cat('白色')
cat2 = Cat('灰色', 3)
cat3 = Cat('灰色', hobby='睡覺(jué)')
cat4 = Cat('灰色', 3, '睡覺(jué)')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市慷垮,隨后出現(xiàn)的幾起案子揖闸,更是在濱河造成了極大的恐慌,老刑警劉巖料身,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汤纸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡芹血,警方通過(guò)查閱死者的電腦和手機(jī)贮泞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)幔烛,“玉大人啃擦,你說(shuō)我怎么就攤上這事《鲂” “怎么了令蛉?”我有些...
    開(kāi)封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)狡恬。 經(jīng)常有香客問(wèn)我珠叔,道長(zhǎng),這世上最難降的妖魔是什么弟劲? 我笑而不...
    開(kāi)封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任祷安,我火速辦了婚禮,結(jié)果婚禮上兔乞,老公的妹妹穿的比我還像新娘汇鞭。我一直安慰自己凉唐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布虱咧。 她就那樣靜靜地躺著熊榛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腕巡。 梳的紋絲不亂的頭發(fā)上玄坦,一...
    開(kāi)封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音绘沉,去河邊找鬼煎楣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛车伞,可吹牛的內(nèi)容都是我干的择懂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼另玖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼困曙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谦去,我...
    開(kāi)封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤慷丽,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鳄哭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體要糊,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年妆丘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锄俄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勺拣,死狀恐怖奶赠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宣脉,我是刑警寧澤车柠,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站塑猖,受9級(jí)特大地震影響竹祷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜羊苟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一塑陵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜡励,春花似錦令花、人聲如沸阻桅。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嫂沉。三九已至,卻和暖如春扮碧,著一層夾襖步出監(jiān)牢的瞬間趟章,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工慎王, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚓土,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓赖淤,卻偏偏與公主長(zhǎng)得像蜀漆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咱旱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一确丢、類方法和靜態(tài)方法 類中的方法分為:對(duì)象方法,類方法和靜態(tài)方法 1.類方法a.在聲明前添加@classmetho...
    憧憬001閱讀 199評(píng)論 0 0
  • 對(duì)于愛(ài)情 我期待 但卻不敢觸及
    乞丐與玫瑰閱讀 145評(píng)論 0 0
  • 春天(原創(chuàng)) 春天之美吐限, 鳥語(yǔ)花香蠕嫁,生機(jī)盎然, 催人奮進(jìn)毯盈, 充滿對(duì)未來(lái)憧憬的, 美好希望病袄, 讓人留戀搂赋, 為此留下優(yōu)...
    你健康我快樂(lè)_61fc閱讀 323評(píng)論 3 6
  • 之前我有發(fā)表過(guò)一篇關(guān)于王者速讀法的文章,這次想要嘗試用視覺(jué)筆記分享一個(gè)技能益缠,于是我選擇分享這個(gè)速讀方法脑奠。 首先,按...
    BIKY閱讀 411評(píng)論 0 4
  • 運(yùn)用 https://html-cleaner.com/ 進(jìn)行Word 轉(zhuǎn)化 文字原文 二幅慌、課程目標(biāo) 透過(guò)混合學(xué)習(xí)...
    葉榮杰閱讀 209評(píng)論 0 1