前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >day22-day28-面向对象

day22-day28-面向对象

原创
作者头像
少年包青菜
修改2022-09-06 19:58:36
3690
修改2022-09-06 19:58:36
举报
文章被收录于专栏:Python 学习Python 学习

day22-day23初识面向对象,面向对象的小例子,组合的使用

代码语言:javascript
复制
# 人和狗的战争
class Dog:
    def __init__(self, name, aggr, hp, kind):  # 定义一条狗的属性
        self.name = name  # 初始化属性
        self.aggr = aggr
        self.hp = hp
        self.kind = kind

    def bite(self, person_obj):  # 将人对象作为参数传入,即对于这个人,狗把他咬了,人减少的血量就是狗子的攻击力
        person_obj.hp -= self.aggr  # 作为外来参数做变化,person 不要 self. 操作
        # 这个其实就是组合方法,即,一个对象的属性值是另一个类的对象
         
class Person:
    def __init__(self, name, aggr, hp, sex):  # 定义一个人的属性
        self.name = name  # 初始化属性
        self.aggr = aggr
        self.hp = hp
        self.sex = sex

    def attack(self, dog_obj):  # 人有一个攻击的方法
        dog_obj.hp -= self.aggr


two_ha = Dog('二哈', 25, 1000, '沙雕')  # 生成一个"二哈"对象
ao_te_man = Person('迪迦', 30, 500, '不详')  # 生成一个奥特曼对象

print('奥特曼的血量:', ao_te_man.hp)  # 首先可以查看 奥特曼 的血量
print('二哈的血量:', two_ha.hp)  # 首先可以查看 二哈 的血量
two_ha.bite(ao_te_man)  # 二哈使用 bite 方法咬了奥特曼一口
ao_te_man.attack(two_ha)  # 奥特曼使用 attack 方法攻击了 二哈
print('奥特曼剩余的血量:', ao_te_man.hp)  # 首先可以查看 奥特曼 的血量
print('二哈剩余的血量:', two_ha.hp)  # 首先可以查看 二哈 的血量

day24-继承

代码语言:javascript
复制
# 继承
class Animal:
    def __init__(self, name, aggr, hp):  # 初识化一个 Animal 类,具有以下属性
        self.name = name
        self.aggr = aggr
        self.hp = hp

    def eat(self):  # 有一个 吃 的方法
        self.hp += 100
        print('加了100血量')


class Dog(Animal):
    def __init__(self, name, aggr, hp, kind):
        Animal.__init__(self, name, aggr, hp)  # 继承父类的属性
        # super().__init__(name, aggr, hp)  # 一样的继承,不同的写法
        self.kind = kind  # 同时又有自己的属性,即派生属性

    def eat(self):
        Animal.eat(self)  # 继承父类的方法
        print('顺便做个练习1+1=', 1 + 1)  # 继承过来可以做其他操作,这里引进一个 print 做示例


two_ha = Dog('狗子', 20, 100, '二哈')
print(two_ha.hp)  # 先看一下二哈的血量
two_ha.eat()  # 二哈调用继承父类的 eat 方法
print(two_ha.hp)  # 再看一下二哈的血量
print(two_ha.__dict__)  # 随便看看,调用 __dict__ 方法,以字典的形式查看当前对象的属性
super(Dog, two_ha).eat()  # 直接使用被继承的父类方法

day25-继承规范

代码语言:javascript
复制
from abc import ABCMeta, abstractmethod  # 第一步: 导入这个模块和方法,固定格式1


class Animal(metaclass=ABCMeta):  # 第二步: 固定格式2
    def __init__(self):
        pass

    @abstractmethod  # 第三步: 固定格式3
    def skill_1(self): pass  # 并不实现

    @abstractmethod
    def skill_2(self): pass  # 并不实现


class Dog(Animal):  # 当父类使用了以上格式,只要是继承了父类,就要全部继承父类的方法
    def skill_1(self): print('this is skill_1')  # 重写方法

    def skill_2(self): print('this is skill_2')  # 重写方法

day25-统一入口,多态的理解

代码语言:javascript
复制
from abc import ABCMeta, abstractmethod


class Payment(metaclass=ABCMeta):  # 定义一个支付类
    def __init__(self):
        pass

    @abstractmethod
    def pay(self):
        pass


class WeChatPay(Payment):  # 继承支付方法
    def pay(self): print('微信支付')


class ALiPay(Payment):  # 继承支付方法
    def pay(self): print('支付宝支付')


class BankCardPay(Payment):  # 继承支付方法
    def pay(self): print('银行卡支付')


def all_pay(pay_obj):  # 以上所有支付方式因为都有一个支付方法,所以写这一个方法
    pay_obj.pay()  # 所有支付对象调用同一个方法,就实现了统一支付入口
    
# 什么是多态
# python 动态强类型的语言
# 鸭子类型
# list tuple
# 不崇尚根据继承所得来的相似
# 我只是自己实现我自己的代码就可以了。
# 如果两个类刚好相似,并不产生父类的子类的兄弟关系,而是鸭子类型
# list tuple 这种相似,是自己写代码的时候约束的,而不是通过父类约束的
# 优点 : 松耦合 每个相似的类之间都没有影响
# 缺点 : 太随意了,只能靠自觉

day25-方法的封装

代码语言:javascript
复制
class Person:
    def __init__(self, name, password):
        self.name = name
        self.__password = password  # 双下划线,即实现可私有属性

    def __get_pwd(self):  # 双下划线,即实现方法的私有
        pwd = self.__password
        return pwd

    def return_pwd(self):
        return self.__get_pwd()


# 所有的私有的属性或者方法都是在变量的左边加上双下划线
# 所有的私有属性和方法只能在类里面被使用,外部不能够直接调用类内部的私有属性或者方法
# 外部想要调用,则写一个方法get到类内部的属性或者方法

person = Person('张三', 123)
print(person.return_pwd())
代码语言:javascript
复制
# 会用到私有的这个概念de场景
# 1.隐藏起一个属性 不想让类的外部调用
# 2.我想保护这个属性,不想让属性随意被改变
# 3.我想保护这个属性,不被子类继承

day26-property伪装对象方法作为对象属性

代码语言:javascript
复制
from math import pi


class Circle:
    def __init__(self, r):
        self.r = r

    @property
    def perimeter(self):
        return 2 * pi * self.r

    @property
    def area(self):
        return self.r ** 2 * pi


c1 = Circle(5)
print(c1.area)  # 圆的面积,在原本没有 @property 的时候,打印方式是 c1.area(),有了@property,去掉了(),伪装成了属性
print(c1.perimeter)  # 圆的周长

day26-setter和deleter(了解)修改私有属性

代码语言:javascript
复制
class Person:
    def __init__(self, name):
        self.__name = name

    @property
    def obj_name(self):  # 这里定义的函数名,在下面做修改或者删除时,最好用同一个函数名!!!装饰器的名字也一样,否则报错
        return self.__name

    @obj_name.setter  # 伪装成属性,调用由 .obj_name() 变成 .obj_name
    def obj_name(self, new_name):
        self.__name = new_name

    @obj_name.deleter
    def obj_name(self):
        del self.__name


person = Person('张三')
print(person.obj_name)  # 结果是张三

person.obj_name = '李四'  # 原本的使用方式是 person.obj_name(),这里直接使用属性方式修改
print(person.obj_name)

del person.obj_name  # 执行删除操作
try:
    print(person.obj_name)
except Exception as error:
    print('名字属性不存在!', error)

day26-classmethod方法和staticmethod方法

代码语言:javascript
复制
class Goods:
    __discount = 0.8  # 定义一个商品类,它的私有折扣属性是 0.8

    @property
    def get_discount(self):
        return self.__discount

    @classmethod  # 使用 classmethod 装饰,即代表这个方法只是用来修改类的静态变量属性的,可被类名直接调用
    def change_discount(cls, new_discount):
        cls.__discount = new_discount

    @staticmethod  # 静态一般方法,只是放在了类里面
    def func():
        print('我只是一个放在类里面的一般函数')


good = Goods()
print(good.get_discount)  # 此时折扣属性是 0.8
Goods.change_discount(0.9)
print(good.get_discount)  # 此时折扣属性就是 0.9

Goods.func()  # 可以被类名直接调用
good.func()  # 也可以被类的对象调用

day27-对象和类,继承和被继承类之间的判断

代码语言:javascript
复制
class A:
    pass


class B(A):
    pass


a_obj = A()
print(isinstance(a_obj, A))  # 判断 a_obj 是否是 A 的对象
print(issubclass(B, A))  # 判断 B 是否继承自 A

day27-反射的使用★★★★★

代码语言:javascript
复制
class Person:
    kind = 'human'

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

    @staticmethod
    def func():
        print('这是Person类里面的一个函数')


person = Person('张三', 25)  # 定义一个人

# 放射对象属性
if hasattr(person, 'name'):  # 如果有 'name' 属性  # 通过变量名的字符串形式取到的值
    print(getattr(person, 'name'))  # 就反射这个属性  # 一般 hasattr() 和 getattr() 配合起来用

# 反射对象的方法
if hasattr(person, 'func'):
    getattr(person, 'func')()  # getattr(person, 'func') 拿到一个内存地址,再加上 () 就执行该函数

# 反射类的属性
if hasattr(Person, 'kind'):
    print(getattr(Person, 'kind'))

# 反射类的方法
if hasattr(Person, 'func'):
    getattr(Person, 'func')()

# 反射内置模块方法
import time

if hasattr(time, 'asctime'):
    print(getattr(time, 'asctime')())

# 如何反射本模块中的内容?★★★★★
import sys

man = 'happy'
# print(sys.modules[__name__])  # 代表本模块的地址,如果要反射本模块中的 man 属性,则
if hasattr(sys.modules[__name__], 'man'):
    print(getattr(sys.modules[__name__], 'man'))

# 反射模块方法和类
from AAAAA import forload  # AAAAA目录 里面有自己写 forload.py,内含一个类和方法

if hasattr(forload, 'func'):  # 反射模块方法
    getattr(forload, 'func')()

if hasattr(forload, 'BB'):
    obj = getattr(forload, 'BB')()  # 反射模块里面的类
    obj.inner_func()  # 反射成功,则 BB 类里面的方法被对象调用可以成功

day27-类的内置方法(暂时了解)

代码语言:javascript
复制
class Teacher:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

    def __str__(self):
        return "Teacher's object"


teacher = Teacher('张三', 3000)
print(teacher)  # 打印这个类的对象,实际上就是在调用 __str__ 方法,即实现高可定制

lis = [1, 2, 3]


# 还有很多,了解,后续基本不怎么用
###############################################################################

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

    def __eq__(self, other):  # 定制方法
        if self.__dict__ == other.__dict__:
            return True
        else:
            return False


ob1 = A('egon')
ob2 = A('egg')
print(ob1 == ob2)  # 判断俩对象是否相等,== 本质是上执行的 __eq__

day28-面向对象进阶

代码语言:javascript
复制
class Foo:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    # 对象字典通过 key 取到 value
    def __getitem__(self, item):  # 将对象的属性按照字典的键值对形式,定制通过对象字典的 key 形式获取属性值
        return self.__dict__[item]

    def __setitem__(self, key, value):  # 将对象的属性按照字典的形式,通过对象的 key 修改 value,即修改对象属性
        self.__dict__[key] = value

    def __delitem__(self, key):  # 将对象的属性按照字典的形式,通过删除对象的 key 删除 value,即删除对象的默认属性
        del self.__dict__[key]


person = Foo('张三', 25, '男')

print(person.name)  # 原生方法支持的
print(person['name'])  # 自己通过 __getitem__ 定制的,两者实现一样


person.name = '李四'  # 原生方法支持的
print(person.name)
person['name'] = '王五'  # 自己通过 __setitem__ 定制的,两者实现一样
print(person['name'])


# del person.name  # 原生支持的删除属性的方法
# try:
#     print(person.name)
# except Exception as error:
#     print('找不到该属性', error)

del person['name']  # 自己通过 __delitem__ 定制的,两者实现一样
try:
    print(person['name'])
except Exception as error:
    print('找不到该属性', error)

day28-单例模式★★★★★

代码语言:javascript
复制
class Person:
    __instance = False  # instance 为 True(非空),代表已经被示例化, 为 False (空),代表未被实例化

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

    def __new__(cls, *args, **kwargs):
        if cls.__instance:  # 非空(已经被实例化),即返回原来的 cls.instance,实现单例了
            return cls.__instance
        cls.__instance = object.__new__(cls)  # 未被实例化的话,就执行此操作
        return cls.__instance


'''
 object将__new__()方法定义为静态方法,并且至少需要传递一个参数cls,
 cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供。

'''

'''
1.调用__new__()方法来进行创建对象,这个new方法可以是object的,也可以是自己重写的,
    最后必须要return这个创建好的对象的引用。
2.调用__init__()方法来进行实例对象的初始化,__init__(self)接收的就是new方法return出来的那个创建好的对象的引用。
    返回对象的引用。

'''
'''
我们比较两个方法的参数,可以发现__new__方法是传入类(cls),
而__init__方法传入类的实例化对象(self),
而有意思的是,__new__方法返回的值就是一个实例化对象
ps:如果__new__方法返回None,则__init__方法不会被执行,
并且返回值只能调用父类中的__new__方法,而不能调用毫无关系的类的__new__方法。
我们可以这么理解它们之间的关系,__new__是开辟疆域的大将军,
而__init__是在这片疆域上辛勤劳作的小老百姓,只有__new__执行完后,开辟好疆域后,__init__才能工作。

'''
person_1 = Person('张三', 20)
print(person_1.__dict__)
print(id(person_1))

person_2 = Person('李四', 22)
print(person_2.__dict__)
print(id(person_2))  # 两个对象 id 是一样的

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • day22-day23初识面向对象,面向对象的小例子,组合的使用
  • day24-继承
  • day25-继承规范
  • day25-统一入口,多态的理解
  • day25-方法的封装
  • day26-property伪装对象方法作为对象属性
  • day26-setter和deleter(了解)修改私有属性
  • day26-classmethod方法和staticmethod方法
  • day27-对象和类,继承和被继承类之间的判断
  • day27-反射的使用★★★★★
  • day27-类的内置方法(暂时了解)
  • day28-面向对象进阶
  • day28-单例模式★★★★★
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档