Python基础:类与面向对象编程(二)

Comparison is the thief of joy.

攀比是盗取快乐的贼


声明

仅作为个人学习使用,仅供参考


区分对象与类

小贝 喜欢 猫咪,今年领养了一只名叫 Kitty布偶猫。则下列哪项是 对象 呢?

小贝 Kitty   >对象

闻闻 更喜欢 犬科 动物,家里养了两只 萨摩耶犬,一只名叫 丁丁,另一只名叫 当当。则下列哪项是 呢?

犬科动物 萨摩耶犬  >类

因此

具体的是对象  具有抽象概念的是类

这两道题目中出现了 小贝闻闻 这两位具体的人,提到了 Kitty丁丁当当 这三只具体的动物,他们都是 对象。这其中的人(Human)、猫咪(Cat)、布偶猫(Dagdoll)、萨摩耶(Samoyed)、犬科(Dog)几个 抽象概念 则是


isinstance()函数

isinstance(object, classinfo)

参数

  • object -- 实例对象。
  • classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组

接受两个参数 第一个参数是实例对象,第二次参数为某个类,检查实例对象是否是第二个参数的实例,返回 True 或 False

isinstance演示


class Dog:pass #定义类:狗

dingding = Dog() #dingding是一条狗

print(isinstance(dingding,Dog))

输出 True 即表示 dingding 是 Dog类 的实例对象

Dog 类中只包含一条 pass 语句,此时 pass 语句可以直接跟在 class xxx: 之后,

写成一行是一种简便写法


类的继承

class 子类名(父类名): 的方式实现类的继承

萨摩耶是狗的种类,丁丁是萨摩耶,那么丁丁是狗 非常缜密的逻辑推理

class Dog:pass

class Samoyed(Dog):pass

dingding = Samoyed()  #dingding是萨摩耶

print(isinstance(dingding,Samoyed))  #dingding是萨摩耶
print(isinstance(dingding,Dog))      #那dingding 也是狗咯~

class 子类名(父类名): 的方式实现类的继承

class Samoyed(Dog):pass

即表示 Samoyed 是 Dog 的 子类 ,Dog是 Samoyed 的父类

Samoyed继承了 Dog类

即表示 是Samoyed类的 也一定是Dog类

那如果已知dingding是Dog类 用 isinstance() 判断是否是 Samoyed 类 ,当然会输出 False

这就是

继承 的第一个好处

它能够让 Python 理解 类 与 类 之间的范围关系(父类与子类)

子类调用父类方法

class Dog:
    def run(self):
        print('今天天气真好,让我想飞快的跑')

class Samoyed(Dog):pass

dingding = Samoyed()

dingding.run()


输出:今天天气真好,让我想飞快的跑

可以看到 run 函数定义在 Dog 父类里,dingding是子类 Samoyed 的实例

我们依然能够通过子类调用父类的方法

其实是 子类Samoyed 继承了 父类Dog 的所有属性与方法

Python 在执行到 dingding.run() 时,会先检查 dingding 自身类型 Samoyed 中有没有 run() 方法,发现没有,再去 Samoyed 的父类 Dog 中寻找 run() 方法。这时它找到了 run() 方法,就执行了。

这就是

继承 的第二个好处

当我们约定 A 类继承自 B 类后,子类 A 将 自动获得 B 类中定义的 所有属性与方法

再次强调一下 类中的属性与方法 就是 定义在类内的变量与def函数

多态

上文提到 因为 子类Samoyed 找不到 run 方法 就去 父类 Dog 找,找到了然后执行

那如果 子类Samoyed 有 run 方法呢 即存在与父类的同名方法呢?

这就是 多态

子类重写父类方法

子类与父类中有 相同名称的方法 但是执行的东西不一样,那么子类可以重写父类中的同名方法

class Dog:
    def run(self):
        print('今天天气真好,让我想飞快的跑')

class Samoyed(Dog):
    def run(self):
        print('今天天气真好,但是萨摩耶不想飞快的跑')

dingding = Samoyed()
dingding.run()


输出:今天天气真好,但是萨摩耶不想飞快的跑

输出发生了变化 ,是因为 子类Samoyed 也定义了run 方法

当 dingding 调用 run 方法 时候,run 方法 在子类中存在 就不去执行父类的 run 方法了

子类新增方法

给子类定义方法 不一定要与父类同名重写方法 ,你也可以定义新的方法

道理是一样的

继承 与 多态 的好处

它们的存在,让我们能够在 不改变犬科动物共性 前提下,为不同品种的狗狗赋予个性,使我们的代码结构清晰

继承 就是 子类与父类 相同的地方 ||  多态 就是 子类与父类不同的地方

狼人杀项目

1.random.choice()的使用


2.对于roles = [Villager(), Prophet()]代码的解释
这行代码 分别创造了1个 Villager() 和 Prophet() 的实例,但是没有命名


3.为什么Villager().show_card()还是可以调用方法

有效,但并不推荐,但它确实做了以下几件事

创建实例:Villager() 调用了 Villager 类的构造函数,创建了一个新的 Villager 实例。

调用方法:紧接着,.show_card() 在这个新创建的实例上调用了 show_card 方法。

销毁实例:由于这个 Villager 实例没有被赋值给任何变量,因此在 show_card 方法执行完毕后,这个实例将变得不可达,随后Python的垃圾回收机制会将其回收。

就是说Villager().show_card()

确实既创造了Villager的实例又调用了show_card方法,但是一般只用于测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值