【Python】面向对象

一、类的构建与继承

class Person:
    name = '没有名字'
    age = '未出生'
    sex = '不知道'

    # 静态方法
    @staticmethod
    def print_name():
        print(f'{Person.name}')

    #实例化属性方法
    def __init__(self, name='无名氏', age=0, sex='未知'):
        self.name = name
        self.age = age
        self.sex = sex
        # 初始化无返回值

    def PrintName(self):
        print(f'my name is {self.name}')
    def PrintAge(self):
        print(f'my age is {self.age}')
    def PrintSex(self):
        print(f'my sex is {self.sex}')

# 继承Person的子类
class Son(Person):
    def PrintName(self):
        print(f'我的名字是{self.name}')
    def __init__(self, name='子女', age=1):
        Person.__init__(self)
        self.name = name
        self.age = age

if __name__ == '__main__':
    # 类直接调用静态方法
    Person.print_name()      # 没有名字

    girl_friend = Person()
    # 类对象调用静态方法
    print(girl_friend.name)  # 无名氏
    girl_friend.print_name() # 没有名字
    girl_friend.PrintName()  # my name is 无名氏
    girl_friend.PrintAge()   # my age is 0
    girl_friend.PrintSex()   # my sex is 未知

    friend = Person('坤坤', 2.5, '女')
    friend.print_name()     # 没有名字
    print(friend.name)      # 坤坤
    friend.PrintName()      # my name is 坤坤
    friend.PrintAge()       # my age is 2.5
    friend.PrintSex()       # my sex is 女

    print(Son.name)         # 没有名字
    s = Son()
    s.PrintName()           # 我的名字是子女
    s.PrintAge()            # my age is 1
    s.PrintSex()            # my sex is 未知

二、多继承

class Master:
    def __init__(self):
        self.kongfu = '传统奶茶配方'
    def make_cake(self):
        print(f'【传统】按照{self.kongfu}制作了一杯奶茶')
    def smoke(self):
        print('抽个烟')

class School:
    def __init__(self):
        self.kongfu = '现代奶茶配方'
    def make_cake(self):
        print(f'【现代】按照{self.kongfu}制作了一杯奶茶')
    def drink(self):
        print('喝点酒')

class Prentice(Master, School):     # 谁排前面,谁优先继承
    pass

# 子类的魔法属性 __mro__ 决定了属性和方法的优先级
me = Prentice()
print(me.kongfu)
me.make_cake()
me.smoke()
me.drink()

三、钻石继承

# super()函数保证公共父类只被执行一次
class A:
    def __init__(self):
        print('进入A')
        print('离开A')

class B(A):
    def __init__(self):
        print('进入B')
        super().__init__()
        print('离开B')

class C(A):
    def __init__(self):
        print('进入C')
        super().__init__()
        print('离开C')

class D(B, C):
    def __init__(self):
        print('进入D')
        super().__init__()
        print('离开D')

if __name__ == '__main__':
    D()

四、多态

多态:不同对象在调用相同函数时,呈现不同状态

class Animal:
    def eat(self):
        print('动物吃饭了')

class Dog(Animal):
    def eat(self):
        print('小狗吃饭了')

class Cat(Animal):
    def eat(self):
        print('小猫吃饭了')

a = Animal()
b = Dog()
c = Cat()

# isinstance() 判断一个对象是否属于某个类
print(isinstance(a, Animal))    # True
print(isinstance(b, Animal))    # True
print(isinstance(c, Animal))    # True
print(isinstance(a, Dog))       # False
a.eat() # 动物吃饭了
b.eat() # 小狗吃饭了
c.eat() # 小猫吃饭了

五、鸭子类型

class Duck:
    def quack(self):
        print('嘎嘎,我是一只可达鸭')
    def feathers(self):
        print('我有黄色的羽毛')

class Person:
    def quack(self):
        print('我也会嘎嘎嘎,但我是一个人')
    def feathers(self):
        print('我没有羽毛')

def in_the_poor(d):
    d.quack()
    d.feathers()

duck = Duck()
person = Person()
in_the_poor(duck)
in_the_poor(person)

六、类的组合

# 乌龟类
class Turtle:
    def __init__(self, x):
        self.num = x

# 鱼类
class Fish:
    def __init__(self, x):
        self.num = x

# 池塘类
class Pool:
    def __init__(self, x, y):
        self.turtle = Turtle(x)
        self.fish = Fish(y)
    def print_num(self):
        print(f'池塘里有{self.turtle.num}只乌龟,{self.fish.num}只鱼')

p = Pool(10, 20)
p.print_num()       # 池塘里有10只乌龟,20只鱼

七、类的私有属性

class Person(object):
    def __init__(self, password):
        # 变量前面加两个下划线,是私有属性,外部不可直接访问
        self.__password = password

    def GetPassword(self):
        return self.__password  # 类的内部可调用私有属性

    def SetPassword(self, new__password):
        if len(new__password) >= 6:
            self.__password = new__password
        else:
            print('密码长度需大于等于6')

me = Person('123456')

try:
    print(me.__password)
except:
    print('报错')

print(me.GetPassword())
me.SetPassword('654321')
print(me.GetPassword())

八、魔法方法

class Obj(int):
    def __init__(self, num):
        self.num = num

    # 自定义类对象的基本计算方法
    def __add__(self, other):
        return self.num + other + 1
    def __sub__(self, other):
        return self.num - other + 1
    def __mul__(self, other):
        return self.num * other + 1
    def __truediv__(self, other):
        return self.num / other + 1
    def __floordiv__(self, other):
        return self.num // other + 1

    # __str__ 是一个显示对象信息的魔法方法
    # 这个方法需要return一个数据,并且只有self一个参数
    # 当在类的外部print对象,则打印这个返回的数据
    def __str__(self):
        return (f'这个数是{self.num}')

    # __getattr__(self) 当访问一个不存在的对象时,不报错
    # 防报错的异常捕获机制
    def __getattr__(self, name):
        return (f'{name}属性不存在')

if __name__ == '__main__':
    a = Obj(3)
    b = Obj(5)
    print(a)
    print(type(a))
    print(a.x)
    print(a + b)
    print(a - b)
    print(a * b)
    print(a / b)
    print(a // b)

九、单例模式

保证一个类只有一个实例存在

class Single:
    # 创建类的隐藏属性
    __instance = None   # 父类new方法的返回值,None的bool值为False

    def __new__(cls):
        # 如果 __instance 的值为None,就创建一个对象并赋值
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

if __name__ == "__main__":
    a = Single()
    b = Single()
    print(id(a), id(b)) # 地址一样

    a.name = '张三'
    a.sex = '帅哥'
    print(a.name, a.sex)    # 张三 帅哥
    print(b.name, b.sex)    # 张三 帅哥

    b.name = '坤坤'
    b.sex = '美女'
    print(a.name, a.sex)    # 坤坤 美女
    print(b.name, b.sex)    # 坤坤 美女

猜你喜欢

转载自blog.csdn.net/phoenixFlyzzz/article/details/129756926