Python基础知识第八天

方法的重载:
Python中没有方法的重载你,因为Python的参数没有类型(调用时确定参数的类型),丁依依的方法即可有多种调用方式,相当于实现其他语言中方法的重载
如果定义了多个重命名参数,只有最后一个生效

方法的动态性:
Python是动态的语言,我们可以动态的为类添加新方法,或动态的修改类已有的方法

私有属性和私有方法(实现封装):
注:方法本质上也是属性
Python对于类的成员没有严格的访问控制限制
通常,两个下划线开头的属性是私有的,其他为共有
类内部可以访问私有属性(方法)
类外部不能直接访问私有属性(方法)
类外部可以通过“_类名__私有属性(方法)名”访问私有属性

# 测试私有属性
class Employee:
    def __init__(self, name, age):
        self.name = name
        self.__age = age # 变为私有属性

e = Employee('Y', 27)
print(e.name)
print(e._Employee__age) # 访问私有属性

Y
27

# 测试私有方法
class Employee:
    def __init__(self, name, age):
        self.name = name
        self.__age = age # 变为私有属性

    def __work(self): # 私有方法
        print('努力找工作')
        print('{0} is {1} years old'.format(self.name, self.__age))

e = Employee('Y', 27)
e._Employee__work()

努力找工作
Y is 27 years old    

@property装饰器:
可以将方法的调用变成属性的调用
一帮用于给属性增加get和set的方法

# @property测试
class Employee:
    @property
    def salary(self):
        print('salary')
        return 100000

e = Employee()
print(e.salary)

@property的用法:

# 常规
class Employee:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if 0 < age < 150:
            self.__age = age
        else:
            print('Wrong!')

e = Employee('Y', 27)
print(e.get_age())
e.set_age(18)
print(e.get_age())

# @property方法
class Employee:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if 0 < age < 150:
            self.__age = age
        else:
            print('Wrong!')

e = Employee('Y', 27)
print(e.age)
e.age = 160
print(e.age)
e.age = 18
print(e.age)

面向对象三大特征:
封装(隐藏),继承和多态
封装:隐藏对象的属性和实现细节,指对外提供必要的方法,相当于“细节封装起来”,只对外暴露“相关的调节方法”
继承:继承可以让子类(派生类)具有父类(基类)的特性,提高了代码的重要性,Python支持多重继承
多态:多态指同一个方法调用由于对象不同会产生不同的行为,例如每个人放松的方法不同

# 继承
class 子类名([父类1],[父类2],...):
	类体

如果定义没有指定父类,默认父类为object类
定义子类时,子类函数必须调用父类函数

class Person:

    def __init__(self, name, age):
        self.name = name
        self.__age = age # 私有子类不能用

    def say_age(self):
        print('年龄')

class Student(Person):
    def __init__(self, name, age, score):
        Person.__init__(self, name, age) # 必须显式的调用父类,不然不会调用
        self.score = score

s = Student('Y', 27, 100)
s.say_age()
print(s._Person__age) # 调用父类私有

类成员的继承和重写:
成员继承:子类继承了父类的构造方法之外的所有成员
方法重写:子类可以重新定义父类中的方法,这样会覆盖父类的方法,称为“重写”

# 测试方法重写
class Person:

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

    def say_age(self):
        print('年龄', self.__age)

    def introduce(self):
        print('名字是{0}'.format(self.name))

class Student(Person):
    def __init__(self, name, age, score):
        Person.__init__(self, name, age) # 必须显式的调用父类,不然不会调用
        self.score = score

    def introduce(self):
        '''
        重写父类方法
        '''
        print('我的名字是{0}'.format(self.name))

s = Student('Y', 27, 100)
s.say_age()
s.introduce()

年龄 27
我的名字是Y

类的层次结构:
通过类的方法.mro()或者类的属性__mro__可以输出这个类的层次结构

object根类:
object是所有类的父类
dir()可以查看类的所有属性

重写__str__()方法:
用于返回一个对于“对象的描述”,对应于内置函数str(),经常用于print()方法,帮助我们查看对象的信息,str()可以重写

class Person:

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

p = Person('Y')
print(p)

<__main__.Person object at 0x0000019DDC737D00>

# 重写__str__()
class Person:

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

    def __str__(self):
        return '名字是{0}'.format(self.name)
    
p = Person('Y')
print(p)

名字是Y

Python支持多重继承,一个子类可以有多个父类,好处是类更灵活,坏处是破坏了“类的结构”,尽量避免使用

mro()函数:
如果多个父类有相同名字的方法,在子类没有指定父类时,解释器将从左到右按顺序搜索
mro:方法解析顺序,可以通过mro()方法获得类的层次结构,方法解析顺序也是按照这个层级结构寻找到
super()获取父类的定义:
是定义不是对象!

# 测试super()
class A:
    def say(self):
        print('A', self)

class B(A):
    def say(self):
        super().say() # 和A.say(self)一样
        print('B', self)

B().say()

A <__main__.B object at 0x0000023DF0136DD0>
B <__main__.B object at 0x0000023DF0136DD0>

多态:
指同一个方法调用由于对象不同会产生不同的行为
多态是方法的多态,属性没有多态
多态的存在有两个必要条件,继承和方法重写

组合:

# 测试组和
# 继承的方法
class A1:
    def say_A1(self):
        print('A1, A1, A1')

class B1(A1):
    pass

b1 = B1()
b1.say_A1()

A1, A1, A1

# 组合的方法
class A2:
    def say_A2(self):
        print('A2, A2, A2')

class B2:
    def __init__(self, A):
        self.A = A

b2 = B2(A2())
b2.A.say_A2()

A2, A2, A2

练习:

# 测试has—a关系,使用组合
class MobilePhone:
    def __init__(self, cpu, screen):
        self.cpu = cpu
        self.screen = screen

class CPU:
    def calculate(self):
        print('计算')
        print('cpu对象:', self)

class Screen:
    def show(self):
        print('显示')
        print('screen对象:', self)

m = MobilePhone(CPU(), Screen())
m.cpu.calculate()
m.screen.show()

计算
cpu对象: <__main__.CPU object at 0x00000223E4317D00>
显示
screen对象: <__main__.Screen object at 0x00000223E4316B90>

设计模式,工厂模式实现:
工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择现实类、创建对象进行统一的管理和控制

# 测试工厂模式
class CarFactory:
    def creat_car(self, brand):
        if brand == '奔驰':
            return Benz()
        elif brand == '宝马':
            return BMW()
        elif brand == '比亚迪':
            return BYD()
        else:
            return '未知品牌'

class Benz:
    pass

class BMW:
    pass

class BYD:
    pass

factory = CarFactory()
c1 = factory.creat_car('奔驰')
c2 = factory.creat_car('比亚迪')
print(c1)
print(c2)

<__main__.Benz object at 0x000001EE789C7CD0>
<__main__.BYD object at 0x000001EE789C6B90>

设计模式,单例模式实现:
核心作用是确保一个类只有一个实例对象,并提供一个访问该实例的全局访问点
单例模式只生成一个实例对象,减少系统开销,提高性能

# 测试单例模式
class MySingle:
    __obj = None        #类属性
    __init_Flag = True

    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)

        return cls.__obj

    def __init__(self, name):
        if MySingle.__init_Flag == True:
            print('初始化')
            self.name = name
            MySingle.__init_Flag = False

a = MySingle('aa')
b = MySingle('bb')
c = MySingle('cc')
print(a)
print(b)
print(c)

初始化
<__main__.MySingle object at 0x0000027FD6607D00>
<__main__.MySingle object at 0x0000027FD6607D00>
<__main__.MySingle object at 0x0000027FD6607D00>

# 没有控制初始化
class MySingle:
    __obj = None        #类属性

    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)

        return cls.__obj

    def __init__(self, name):
            print('初始化')
            self.name = name


a = MySingle('aa')
b = MySingle('bb')
c = MySingle('cc')
print(a)
print(b)
print(c)

初始化
初始化
初始化
<__main__.MySingle object at 0x00000206B6727CD0>
<__main__.MySingle object at 0x00000206B6727CD0>
<__main__.MySingle object at 0x00000206B6727CD0>

练习工厂模式和单例模式的结合使用:

class CarFactory:
    __obj = None  # 类属性
    __init_Flag = True

    def creat_car(self, brand):
        if brand == '奔驰':
            return Benz()
        elif brand == '宝马':
            return BMW()
        elif brand == '比亚迪':
            return BYD()
        else:
            return '未知品牌'

    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)

        return cls.__obj

    def __init__(self):
        if CarFactory.__init_Flag == True:
            print('初始化 CarFactory')
            CarFactory.__init_Flag = False

class Benz:
    pass

class BMW:
    pass

class BYD:
    pass

factory = CarFactory()
c1 = factory.creat_car('奔驰')
c2 = factory.creat_car('比亚迪')
print(c1)
print(c2)

factory2 = CarFactory()
print(factory)
print(factory2)

初始化 CarFactory
<__main__.Benz object at 0x0000021B27746DD0>
<__main__.BYD object at 0x0000021B27746E00>
<__main__.CarFactory object at 0x0000021B27746DA0>
<__main__.CarFactory object at 0x0000021B27746DA0>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值