day9 面向对象进阶

day9

面向对象进阶

——————————————————————————

#@property装饰器
#访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作
#使用@property包装器来包装getter和setter方法
#@符号用做函数的修饰符,可以在模块或者类的定义层内对函数进行修饰,出现在
#函数定义的前一行,不允许和函数定义在同一行
#一个修饰符就是一个函数,它将被修饰的函数作为参数,并返回修饰后的同名函
#数或其他可调用的东西(如果返回不是一个可调用的对象那么会报错)
#@符号其实就是个包装器,每一层调用装饰都传递的是函数对象
class Person(object):
    def __init__(self, name, age):
        self._name = name
        self._age = age
    # 访问器 - getter方法
    @property
    def name(self):
        return self._name
    # 访问器 - getter方法
    @property
    def age(self):
        return self._age
    # 修改器 - setter方法
    @age.setter
    def age(self, age):
        self._age = age
    #修改器-setter方法
    @name.setter
    def name(self,name):
        self._name = name      
    def play(self):
        if self._age <= 16:
            print('%s正在玩飞行棋.' % self._name)
        else:
            print('%s正在玩斗地主.' % self._name)
def main():
    person = Person('王大锤', 12)
    person.play()
    person.age = 22
    person.play()
    person.name = '白元芳'
    person.play()
if __name__ == '__main__':
    main()
    in():
    person = Person('王大锤', 12)
    person.play()
    person.age = 22
    person.play()
    person.name = '白元芳'
    person.play()
if __name__ == '__main__':
    main()

----------------------------------------------------
王大锤正在玩飞行棋.
王大锤正在玩斗地主.
白元芳正在玩斗地主.

————————————————————————————————————————————

#_slots_魔法
#Python是一门动态语言
#动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定
#但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定
#需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用
class Person(object):
    #限定Person对象只能绑定_name,_age,_gender属性
    __slots__ = ("_name","_age","_gender")
    def __init__(self,name,age):
        self._name = name
        self._age = age
    @property
    def name(self):
        return self._name
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self,age):
        self._age =age
        
    def play(self):
        if self._age<=16:
            print("%s在玩飞行棋"%self._name)
        else:
            print("%s在玩斗地主" %self._name)
            
def main():
    person =Person("yu",23)
    person.play()
    person._gender ="man"
    #person._is_boy =True  # AttributeError: 'Person' object has no attribute '_is_boy'
main()

-------------------------------------------------------
yu在玩斗地主

"""
Python还可以在类中定义类方法,类方法的第一个参数约定名为cls,
它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地
方也称之为类的元数据对象),通过这个参数我们可以获取和类相关
的信息并且可以创建出类的对象
"""
from time import time ,localtime,sleep
class Clock(object):
    def __init__(self,hour = 0,mimute =0,second =0):
        self._hour =hour
        self._minute = mimute
        self._second = second
        
    #这是一个类方法   
    @classmethod
    def now(cls):
        ctime = localtime(time())
        return cls(ctime.tm_hour,ctime.tm_min,ctime.tm_sec)
    def run(self):
        self._second += 1
        if self._second == 60:
            self._second = 0
            self._minute += 1
            if self._minute == 60:
                self._minute = 0
                self._hour += 1
                if self._hour == 24:
                    self._hour = 0
    def show(self):
        """显示时间"""
        return '%02d:%02d:%02d' %(self._hour, self._minute, self._second)
def main():
    #通过类方法创建对象并获取系统时间
    #通过类方法的cls这个参数我们可以获取和类相关的信息并且可以创建出类的对象
    clock=Clock.now()#类方法
    while True:
        print(clock.show())
        sleep(1)
        clock.run()
main()

-----------------------------------------
12
12
6.0
6.0

————————————————————————————————————————————
“”"

#类之间的关系 继承和多态
#类和类之间的关系有三种:is-a、has-a和use-a关系。
#is-a关系也叫继承或泛化,比如学生和人的关系、手机和电子产品的关系都属于继承关系。
#has-a关系通常称之为关联,比如部门和员工的关系,汽车和引擎的关系都属于关联关系;
关联关系如果是整体和部分的关联,那么我们称之为聚合关系;如果整体进一步负责了部
分的生命周期(整体和部分是不可分割的,同时同在也同时消亡),那么这种就是最强的关联关系,我们称之为合成关系。
#use-a关系通常称之为依赖,比如司机有一个驾驶的行为(方法),其中(的参数)使用到了汽车,那么司机和汽车的关系就是依赖关系
"""
#在实际开发中,我们经常会用子类对象去替换掉一个父类对象,这是面向对象编程中一个常见的行为,对应的原则称之为里氏替换原则
class Person(object):
    """"""

    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property #访问器getter
    def name(self):
        return self._name

    @property#访问器getter
    def age(self):
        return self._age

    @age.setter #访问器setter
    def age(self, age):
        self._age = age

    def play(self):
        print('%s正在愉快的玩耍.' % self._name)

    def watch_av(self):
        if self._age >= 18:
            print('%s正在观看武侠动作片.' % self._name)
        else:
            print('%s只能观看《熊出没》.' % self._name)
            
class Student(Person):#括号内的参数Person表示继承了Person类
    """学生"""
    def __init__(self,name,age,grade):#可以与父类不同的参数
        super().__init__(name,age)#调用父类进行初始化
        self._grade = grade
        
    @property #getter
    def grade(self):
        return self._grade
    @grade.setter #setter
    def grade(self,grade):
        self._grade =grade
    def study(self,course):
        print("%s的%s正在学习%s"%(self._grade,self._name,course))
        
        
class Teacher(Person):
    """老师"""
    def __init__(self,name ,age,title):
        super().__init__(name,age)
        self._title =title
        
    @property
    def title(self):
        return self._title
    @title.setter
    def title(self,title):
        self._title =title
    def teach(self,course):
        print("%s%s正在讲%s"%(self._name,self._title,course))
def main():
    stu =Student("li",15,"高一")
    stu.study("数学")
    stu.watch_av()
    t =Teacher("wang",40,"professor")
    t.teach("物理")
    t.watch_av()
main()

--------------------------------------------------
高一的li正在学习数学
li只能观看《熊出没》.
wangprofessor正在讲物理
wang正在观看武侠动作片.

#子类在继承了父类的方法后,可以对父类已有的方法重写(override)
#通过方法重写我们可以让父类的同一个行为在子类中拥有不同的实现版本
#当我们调用这个经过子类重写的方法时,不同的子类对象会表现出不同的行为,这个就是多态(poly-morphism)。
from abc import ABCMeta,abstractmethod
#抽象类,不能创建对象的类
#通过abc模块的ABCMeta元类和abstractmethod包装器来达到抽象类的效果
class Pet(object,metaclass=ABCMeta):
    """宠物"""
    def __init__(self,nickname):
        self._nickname = nickname
    @abstractmethod#声明这是个抽象方法
    #如果一个类中存在抽象方法那么这个类就不能够实例化(创建对象)
    def make_voice(self):
        """发出声音的抽象方法"""
        pass#等待重写
class Dog(Pet):
    def make_voice(self):
        print("%s:汪汪汪...."%self._nickname)
class Cat(Pet):
    def make_voice(self):
        print("%s:喵喵喵...."%self._nickname)
def main():
    pets =[Dog("旺财"),Cat("katty"),Dog("大黄")]#对象队列
    for pet in pets:
        pet.make_voice()      
main()

------------------------------------------------------------------
旺财:汪汪汪....
katty:喵喵喵....
大黄:汪汪汪....

————————————————————————————————————————————

#综合案例 奥特曼打小怪兽
from abc import ABCMeta,abstractmethod
from random import randint,randrange

class Fighter(object,metaclass =ABCMeta):
    """战斗者"""
    #通过__slots__魔法限定对象可以绑定的成员变量
    __slots__ =("_name","_hp")
    
    def __init__(self,name,hp):
        self._name=name
        self._hp =hp
    @property
    def name(self):
        return self._name
    @property
    def hp(self):
        return self._hp
    @hp.setter
    def hp(self,hp):
        self._hp = hp if hp>=0 else 0
    @property
    def alive(self):
        return self._hp>0
    @abstractmethod
    def attack(self,other):
        """攻击"""
        pass
class Ultraman(Fighter):
    """奥特曼"""
    __slots__ =("_name","_hp","_mp")
    def __init__(self,name,hp,mp):
        #mp为魔法值
        super().__init__(name,hp)
        self._mp =mp
    def attack(self,other):
        other.hp-=randint(5,21)
    def huge_attack(self,other):
        """终极必杀技
        :param other:被攻击的对象
        reurn :使用成功返回true否则返回false
        """
        if self._mp>=50:
            self._mp-=50
            injury =other.hp*3//4
            injury = injury if injury>=50 else 50
            other.hp-=injury
            return True
        else:
            self.attack(other)
            return False
    def magic_attack(self,others):
        #others 被攻击的群体
        #return 使用成功返回true否则返回false
        if self._mp>=20:
            self>mp-=20
            for temp in others:
                if temp.alive:
                    temp.hp-=randint(10,15)
            return True
        else:
            return False
    def resume(self):
    """恢复魔法值"""
    incr_point = randint(1,10)
        self._mp+=incr_point
        return incr_point
    def __str__(self):
        return "-----%s奥特曼-----\n"%self._name + "生命值:%d\n"%self._hp + \
               "魔法值:%d\n"%self._mp
class
""待完善TODO"""

——————————————————————————————————————

    #综合案例 扑克游戏
import random 
class Card(object):
    """一张牌"""
    def __init__(self,suite,face):
        self._suite =suite
        self._face =face
    @property
    def face(self):
        return self._face
    @property
    def suite(self):
        return self._suite
    def __str__(self):
        if self._face==1:
            face_str="A"
        elif self._face==11:
            face_str ="J"
        elif self._face==12:
            face_str ="Q"
        elif self._face==13:
            face_str ="K"
        else:
            face_str = str(self._face)
        return"%s%s"%(self._suite,face_str)
    
    def __repr__(self):
        return self.__str__()
    
class Poker(object):
    def __init__(self):
        self._cards = [Card(suite,face) for suite in "♠♥♣♦" for face in range(1,14)]
        self._current =0
    @property
    def cards(self):
        return self._cards
    def shuffle(self):
        """洗牌,随机打乱"""
        self._current = 0
        random.shuffle(self._cards)
    @property
    def next(self):
        """发牌"""
        card = self._cards[self._current]
        self._current+=1
        return card
    
    @property
    def has_next(self):
        """还没有发牌"""
        return self._current<len(self._cards)
    
class Player(object):
    """玩家"""
    
    def __init__(self,name):
        self._name =name
        self._cards_on_hand=[]
        
        
    @property
    def name(self):
        return self._name
    @property
    def cards_on_hand(self):
        return _cards_on_hand
    def get(self,card):
        """摸牌"""
        self._cards_on_hand.append(card)
    def arrange(self,card_key):
        """玩家整理手上的牌"""
        self._cards_on_hand.sort(key =card_key)
#排序规则,先根据花色再根据点数排序
def get_key(card):
    return (card.suite,card.face)
def main():
    p =Poker()
    p.shuffle()
    players = [Player("chen"),Player("yu"),Player("cai"),Player("qiu")]
    for _ in range(13):
        for player in players:
            player.get(p.next)
    for player in players:
        print(player._name+":",end=" ")
        player.arrange(get_key)
        print(player._cards_on_hand)
        
main()
        
"""

还没弄太懂
还得完善
"""     

  -----------------------------------------------------------------------------------  
chen: [2,3, ♠J, ♠Q,2,4,3,5,7,9, ♥K,3,7]
yu: [6,7,8, ♠K,3,5,6,9, ♣K,6, ♥J,5, ♦Q]
cai: [♠A,4,9, ♣J, ♣Q,2,4,2,4,6,9, ♦J, ♦K]
qiu: [5,10, ♣A,7,8,10, ♥A,8,10, ♥Q, ♦A,8,10]
_____________________________________________________________
#综合案例 工资结算系统
"""
某公司有三种类型的员工 分别是部门经理、程序员和销售员
需要设计一个工资结算系统 根据提供的员工信息来计算月薪
部门经理的月薪是每月固定15000元
程序员的月薪按本月工作时间计算 每小时150元
销售员的月薪是1200元的底薪加上销售额5%的提成
"""  

你可能感兴趣的:(python,100days学习)