第十章 初识面向对象

1.面向对象思想的引入

例:公司需要开发一款人狗大战的游戏
需要两个角色:人 狗
  人的属性:昵称、性别、生命值、战斗力、背包
  狗的属性:昵称、品种、生命值、战斗力
再尚未学习面向对象知识的时候,我们只是知道需要两个字典描述这两个角色

例1:初步思想

# 例1:初步思想
# 人
person = {'name':'alex', 'sex':'不详', 'hp':250, 'dps':5, 'bag':[]}
# 狗
dog = {'name':'2哈', 'kind':'哈士奇', 'hp':15000, 'dps':200}
# 说明: 这样虽然已经能够描述这两个角色,但是如果增加角色,就需要重新创建字典,很是繁琐

例2:使用函数创建两个模子

# 例2:使用函数创建两个模子
def Person(name, sex, hp, dps): # 人模子dic = {'name': name, 'sex': sex, 'hp':hp, 'dps': dps, 'bag': []}return dic
def Dog(name, kind, hp, dps): # 人模子dic = {'name': name, 'kind': kind, 'hp':hp, 'dps': dps, 'bag': []}return dicalex = Person('alex', 'N/F', 250, 5)
ha2 = Dog('2哈', '哈士奇', 15000, 200)print(alex)
# {'name': 'alex', 'sex': 'N/F', 'hp': 250, 'dps': 5, 'bag': []}
print(ha2)
# {'name': '2哈', 'kind': '哈士奇', 'hp': 15000, 'dps': 200, 'bag': []}
# 说明:这样创建人物已经很方便了,接下来就要进行人狗大战了

例3:人狗大战 -- 使用函数

# 例3:人狗大战
def Person(name, sex, hp, dps): # 人模子dic = {'name': name, 'sex': sex, 'hp':hp, 'dps': dps, 'bag': []}return dic
def Dog(name, kind, hp, dps): # 人模子dic = {'name': name, 'kind': kind, 'hp':hp, 'dps': dps, 'bag': []}return dicalex = Person('alex', 'N/F', 250, 5)
ha2 = Dog('2哈', '哈士奇', 15000, 200)# 人打狗
def attack(person_name, dog_name, person_dps, dog_hp):print('%s打了%s,%s掉了%s点血,剩余%s点血' % (person_name, dog_name, dog_name, person_dps, dog_hp-person_dps))attack(alex['name'], ha2['name'], alex['dps'], ha2['hp'])
# alex打了2哈,2哈掉了5点血,剩余14995点血
# 说明人狗大战的时候,需要输入的参数过多,不好调用

例4:简化人狗大战函数

# 例4:简化人狗大战函数
def Person(name, sex, hp, dps): # 人模子dic = {'name': name, 'sex': sex, 'hp':hp, 'dps': dps, 'bag': []}return dic
def Dog(name, kind, hp, dps): # 人模子dic = {'name': name, 'kind': kind, 'hp':hp, 'dps': dps, 'bag': []}return dicalex = Person('alex', 'N/F', 250, 5)
ha2 = Dog('2哈', '哈士奇', 15000, 200)# 人打狗
def attack(person, dog):dog['hp'] -= person['dps']print('%s打了%s,%s掉了%s点血,剩余%s点血' % (person['name'], dog['name'], dog['name'], person['dps'], dog['hp']-person['dps']))# 狗咬人
def bite(dog, person):person['hp'] -= dog['dps']print('%s咬了%s,%s掉了%s点血,剩余%s点血' % (dog['name'], person['name'], person['name'], dog['dps'], person['hp']-person['dps']))attack(alex, ha2)
# alex打了2哈,2哈掉了5点血,剩余14990点血
attack(alex, ha2)
# alex打了2哈,2哈掉了5点血,剩余14985点血

bite(ha2, alex)
# 2哈咬了alex,alex掉了200点血,剩余45点血# 异常展示
attack(ha2, alex)
# 2哈打了alex,alex掉了200点血,剩余-350点血
# 说明:虽然这已经满足了我们的需求,但是还是出现 狗打人 人咬狗的错误

例5:升级:将打狗变为人的特有功能,将咬人变为狗的特有功能

# 例5:--升级,将打狗变为人的特有功能,将咬人变为狗的特有功能
def Person(name, sex, hp, dps):dic = {'name': name, 'sex': sex, 'hp': hp, 'dps': dps, 'bag': []}def attack(dog):dog['hp'] -= dic['dps']print('%s打了%s,%s掉了%s点血,剩余%s点血' % (dic['name'], dog['name'], dog['name'], dic['dps'], dog['hp']))dic['attack'] = attackreturn dicdef Dog(name, kind, hp, dps):dic = {'name': name, 'kind': kind, 'hp': hp, 'dps': dps}def bite(person):person['hp'] -= dic['dps']print('%s咬了%s,%s掉了%s点血,剩余%s点血' % (dic['name'], person['name'], person['name'], dic['dps'], person['hp']))dic['bite'] = bitereturn dic# 创建人物alex,狗ha2
alex = Person('alex', 'N/F', 250, 5)
ha2 = Dog('2哈', '哈士奇', 15000, 200)# 人打狗
alex['attack'](ha2)
# alex打了2哈,2哈掉了5点血,剩余14995点血
# 狗咬人
ha2['bite'](alex)
# 2哈咬了alex,alex掉了200点血,剩余50点血

思路总结:

1. 面向过程思想
  创建一个人
  创建一个狗
  人打狗 -- 函数
  狗咬人 -- 函数
2.面向对象思想
  造模子 -- 面向对象
  规范了一类角色的属性项目、属性的名字、技能的名字
  权限 有一些函数 只能是这个角色才能拥有 才能使用

2.初识类的语法

类 :具有相同属性和相同方法(技能、动作)的一类事物 组成一个类

对象 :具体的某一个具有实际属性和具体动作的一个实体

类是抽象的

对象是具体的

类被创造出来 就是模子 是用来描述对象的

类的编写格式

class 类名:静态属性 = 123# def 动态属性(self): pass # 就是函数def 动态属性(self):# 在类中的方法的一个默认的参数,但也只是一个形式参数# 约定必须叫selfprint(self)
# 说明
#  类中的变量 -- 静态属性
#  类中的函数 -- 动态属性
# 只要是类中的名字 不管是变量还是函数名 都不能在类的外部直接调用
# 只能通过类名来使用它

类的第一个功能:查看属性

# 只要是类中的名字 不管是变量还是函数名 都不能在类的外部直接调用
# 只能通过类名来使用它
# 1- 查看类的属性
print(类名.__dict__) # 类中必要的默认值之外 还记录了程序员在类中定义的所有名字
# {'__module__': '__main__', '静态属性': 123, '动态属性': <function 类名.动态属性 at 0x0000023F9EB91158>, '__dict__': <attribute '__dict__' of '类名' objects>, '__weakref__': <attribute '__weakref__' of '类名' objects>, '__doc__': None}
# 查看静态属性
print(类名.静态属性)
# 123# 2- 修改静态属性
类名.静态属性 = 123345
print(类名.静态属性)
# 123345# 3- 增加静态属性
类名.静态属性2 = 2345
print(类名.静态属性2)
# 2345# 4- 删除静态属性
del 类名.静态属性2
print(类名.静态属性2)
# AttributeError: type object '类名' has no attribute '静态属性2'
# 查看动态属性
# 类名可以查看某个方法,但是一般情况下 我们不直接使用类名来调用方法
print(类名.动态属性)
# <function 类名.动态属性 at 0x00000206B5E61158>
类名.动态属性(1)
# 1

修改类的静态属性/实例的静态属性

class C:version = 1.2c = C()
print(C.version)
print(c.version)
# 1.2
# 1.2
# 说明:修改类的静态属性,实例的静态属性随之改变
C.version += 0.1
print(C.version)
print(c.version)
# 1.3
# 1.3
# 说明:修改实例的静态属性,类的静态属性不改变
c.version += 0.1
print(C.version)
print(c.version)
# 1.3
# 1.4

类的第二个功能:实例化(创造对象)

# 函数名的第一个字母一定是要小写的
# 类名的第一个字母一定要大写的
class Person:passalex = Person()
# 对象 = 类名() # 实例化的过程
print(alex)
# <__main__.Person object at 0x0000023BCFE70B00>
# __main__ -- 当前文件
print(Person)
# <class '__main__.Person'>

给对象添加属性

# 查看alex的属性
print(alex.__dict__)
# {}
# 给alex添加属性
alex.__dict__['name'] = 'alex'
alex.__dict__['sex'] = '不详'
alex.__dict__['hp'] = 250
alex.__dict__['dps'] = 5
alex.__dict__['bag'] = []
print(alex.__dict__)
# {'name': 'alex', 'sex': '不详', 'hp': 250, 'dps': 5, 'bag': []}# 简化方法
alex.name = 'alex' # 给alex对象添加属性
alex.hp = 250
alex.dps = 5
alex.sex = '不详'
alex.bag = []
print(alex.__dict__)
# {'name': 'alex', 'hp': 250, 'dps': 5, 'sex': '不详', 'bag': []}

实例化的过程

# 类名()就是实例化
# 在实例化的过程中 发生了很多事情是外部看不到的
# 1.创建了一个对象
# 2.自动调用__init__方法,进行初始化
# 3.这个被创造的对象会被当作实际参数 传到__init__方法中,并且传给第一个参数self
# 执行init方法中的内容

初始化和在外部使用对象来调用属性

# 初识化和在外部使用对象来调用属性
class Person:def __init__(self):self.name = 'alex'self.hp = 250self.dps = 5self.sex = '不详'self.bag = []
升级
class Person:def __init__(self,name,hp,dps,sex):self.name = nameself.hp = hpself.dps = dpsself.sex = sexself.bag = []alex = Person('alex',250,5,'N/A') # 参数个数必须与__init__参数相对应
print(alex.__dict__)
# {'name': 'alex', 'hp': 250, 'dps': 5, 'sex': 'N/A', 'bag': []}
print(alex.name)
# alex

使用面向对象的方式编写人狗大战代码

class Person:def __init__(self, name, hp, dps, sex):self.name = nameself.hp = hpself.dps = dpsself.sex = sexself.bag = []def attack(self,dog):dog.hp -= self.dpsprint('%s打了%s,%s掉了%s点血,剩余%s点血' % (self.name, dog.name, dog.name, self.dps, dog.hp))class Dog:def __init__(self,name,kind,hp,dps):self.name = nameself.hp = hpself.kind = kindself.dps = dpsdef bite(self, person):person.hp -= self.dpsprint('%s咬了%s,%s掉了%s点血,剩余%s点血' % (self.name, person.name, person.name, self.dps, person.hp))alex = Person('alex', 250, 5, 'N/A')
ha2 = Dog('2哈', '哈士奇', 15000, 200)
# Person.attack(alex)
# 简化的方式
# alex.attack(ha2) #Person.attack(alex)
alex.attack(ha2)
alex.attack(ha2)
alex.attack(ha2)
# alex打了2哈,2哈掉了5点血,剩余14995点血
# alex打了2哈,2哈掉了5点血,剩余14990点血
# alex打了2哈,2哈掉了5点血,剩余14985点血
ha2.bite(alex)
ha2.bite(alex)
ha2.bite(alex)
# 2哈咬了alex,alex掉了200点血,剩余50点血
# 2哈咬了alex,alex掉了200点血,剩余-150点血
# 2哈咬了alex,alex掉了200点血,剩余-350点血
# 说明:对象名.方法名 相当于调用一个函数,这个函数默认把对象名作为第一个参数传入函数
# 剩余的其他参数根据我的需求可以随意传

例:使用面向对象的思想编写已知半径,计算圆的面积和周长

from cmath import pi
class Circle:def __init__(self, radius):self.radius = radiusdef area(self):return pi * self.radius ** 2def perimeter(self):return 2 * pi * self.radiusa = Circle(5)
print(a.area())
# 78.53981633974483
print(a.perimeter())
# 31.41592653589793

# 程序运行过程:自上至下一次执行
from cmath import pi # 1- 导入模块
class Circle:  # 2- 创建类Circle,在内存中开辟一块内存空间,记录类中的名字__init__,area,perimet# 3- 加载__init__def __init__(self, radius): # 7- 创建对象,在内存中开辟一块内存空间(self) radius=5self.radius = radius# 4- 加载areadef area(self):return pi * self.radius ** 2# 5- 加载perimeterdef perimeter(self):return 2 * pi * self.radius
# 6- 实例化
c1 = Circle(5)  # 8- 赋值
# c1.area() ==> Circle.area(c1)
print(c1.area())
# 78.53981633974483
# c1.perimeter() ==> Circle.perimeter(c1)
print(c1.perimeter())
# 31.41592653589793

面向对象的好处:

  每一个角色都有属于自己的属性和方法

  高可扩展性: 可以方便添加属性和方法

  可读性/规范性

不好的:

  结局不可控性

3.类的命名空间

类有自己的命名空间

对象也有自己的命名空间

对象能不能访问类的命名空间?  --- 可以

类能不能访问对象的命名空间?  --- 不可以

# 运行过程分析
class Person: # 1- 定义类PersonCOUNTRY = '中国人' # 2- 定义变量def __init__(self, name): # 3- 定义__init__self.name = name # 5-  8- 执行__init__
# 4- 实例化alex ==> Person('alex')
# 6- 赋值
alex = Person('alex')
# 7- 实例化egon ==> Person('egon')
# 9- 赋值
egon = Person('egon')print(alex.name)
# alex
print(egon.name)
# egonclass Person:COUNTRY = '中国人'def __init__(self, name):self.name = namedef eat(self):print('%s在吃面包' % self.name)alex = Person('alex')
egon = Person('egon')
alex.eat() # Person.eat(alex)
# alex在吃面包
print(Person.name)
# AttributeError: type object 'Person' has no attribute 'name'
# 当一个类在创建一个实例的时候 就产生了一个这个实例和类之间的联系
# 可以通过实例 对象找到实例化它的类
# 但是 类不能找到它的实例化     

测试:

# 例1: 类的命名空间分析
class Person:COUNTRY = '中国人'def __init__(self, name):self.name = namedef eat(self):print('%s在吃面包' % self.name)alex = Person('alex')
egon = Person('egon')
print(alex.COUNTRY)
# 中国人
alex.COUNTRY == '印度人'
print(alex.COUNTRY)
print(egon.COUNTRY)
print(Person.COUNTRY)
# 中国人
# 中国人
# 中国人# 例2: 类的命名空间分析
class Person:COUNTRY = ['中国人']def __init__(self, name):self.name = namedef eat(self):print('%s在吃面包' % self.name)alex = Person('alex')
egon = Person('egon')
print(alex.COUNTRY)
# ['中国人']
alex.COUNTRY[0] = '印度人'
print(alex.COUNTRY)
print(egon.COUNTRY)
print(Person.COUNTRY)
# ['印度人']
# ['印度人']
# ['印度人']# 说明
# 在访问变量的时候,都显示用自己命名空间中的,如果自己的空间中没有,再到类的空间中去找
# 在使用对象修改该静态变量的过程中,相当于在自己的空间中创建了一个新的变量
# 在类的静态变量(大家都需要的变量)的操作中 应该使用类名来直接进行操作(不应该用对象名修改) 就不会出现乌龙问题

4.组合

组合 一个类的对象作为另一个类对象的属性

# 例1: 添加武器类
class Person:def __init__(self, name, hp, dps, sex):self.name = nameself.hp = hpself.dps = dpsself.sex = sexself.bag = []def attack(self,dog):dog.hp -= self.dpsprint('%s打了%s,%s掉了%s点血,剩余%s点血' % (self.name, dog.name, dog.name, self.dps, dog.hp))class Dog:def __init__(self,name,kind,hp,dps):self.name = nameself.hp = hpself.kind = kindself.dps = dpsdef bite(self, person):person.hp -= self.dpsprint('%s咬了%s,%s掉了%s点血,剩余%s点血' % (self.name, person.name, person.name, self.dps, person.hp))class Weapon:def __init__(self, name, price, dps):self.name = nameself.price = priceself.dps = dpsdef kill(self, dog):dog.hp -= self.dps# 给alex装备一个武器
# 肉包子打狗
alex = Person('alex', 250, 5, 'N/A')
ha2 = Dog('2哈', '哈士奇', 15000, 200)
roubaozi = Weapon('肉包子', 600000, 10000)
alex.money = 1000000
if alex.money >= roubaozi.price:alex.weapon = roubaozialex.weapon.kill(ha2)print(ha2.__dict__)
# {'name': '2哈', 'hp': 5000, 'kind': '哈士奇', 'dps': 200}

# 例2: 常见使用实例
# 基础数据类型 都是类
# 'alex' : str的对象
print(alex.name) # => 'alex'
# 组合
print(alex.name.startswith('a'))
# True

# 例3: 圆形类 -- 圆环类
# 组合 求圆环的面积和周长from cmath import pi
class Circle:def __init__(self,r):self.r = rdef area(self):return pi * self.r ** 2def primeter(self):return 2 * pi * self.rclass Annulus:def __init__(self, outr, inr):self.outr = outrself.inr = inrdef area(self):return Circle(self.outr).area() - Circle(self.inr).area()def primeter(self):return Circle(self.outr).primeter() + Circle(self.inr).primeter()a = Annulus(5, 3)
print(a.area())
print(a.primeter())

总结 : 组合是描述了一种什么有什么的关系 圆环有圆 人有武器

5.继承

为什么会出现继承?

class Person:def __init__(self, name, hp, dps, sex):self.name = nameself.hp = hpself.dps = dpsself.sex = sexself.bag = []def attack(self,dog):dog.hp -= self.dpsprint('%s打了%s,%s掉了%s点血,剩余%s点血' % (self.name, dog.name, dog.name, self.dps, dog.hp))class Dog:def __init__(self,name,kind,hp,dps):self.name = nameself.hp = hpself.kind = kindself.dps = dpsdef bite(self, person):person.hp -= self.dpsprint('%s咬了%s,%s掉了%s点血,剩余%s点血' % (self.name, person.name, person.name, self.dps, person.hp))

仔细观察上面的代码,你会发现在定义Person/Dog类的时候都创建了name/hp/dps属性,这样就出现了多个类的冗余,所以就引入了继承

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可以成为基类或超类,新建的类成为派生类或子类

继承的分类

# 单继承
class Parent:pass
class Son(Parent):pass
print(Son.__bases__) # 查看父类
# (<class '__main__.Parent'>,)# Son类 继承 Parent类
# 父类 基类 超类 -- Parent类
# 子类 派生类 -- Son类# 多继承
class Parent1:pass
class Parent2:passclass Son(Parent1,Parent2):pass
print(Son.__bases__) # 查看父类
# (<class '__main__.Parent1'>, <class '__main__.Parent2'>)

含有继承关系的类的实例化过程

class Animal:def __init__(self, name, hp, dps):print('---->')self.name = nameself.hp = hpself.dps = dpsclass Person(Animal):pass
class Dog(Animal):passalex = Person('alex', 250, 5)
# ---->
ha2 = Dog('哈士奇', 15000, 200)
# ---->
print(alex.__dict__)
# {'name': 'alex', 'hp': 250, 'dps': 5}
print(ha2.__dict__)
# {'name': '哈士奇', 'hp': 15000, 'dps': 200}
# 每当实例化发生的时候发生
# 1. 创建了一个对象 ---> 该对象由子类创建
# 2. 把我创建的对象传给__init__
# 3. 把子类创建的对象传给父类__init__的self
# 4. 执行__init__
# 5. 把self返回给alex

类的内存空间的查找顺序

先找对象的内存空间 -> 再找创建这个对象的类的内存空间 -> 父类的

class Animal:def __init__(self, name, hp, dps):print('---->')self.name = nameself.hp = hpself.dps = dpsclass Person(Animal):def __init__(self, name, hp, dps):print('*****')alex = Person('alex', 250, 5)
# *****
# 说明: 对象在使用名字的时候,先在子类Person中已经找,如果找到就不到父类Animal中找了

派生属性: 子类添加自己的新的属性或者在自己这里重新定义这些属性(不会影响到父类), 但是需要注意,一旦重新定义了自己的属性且父类重名,那么调用新增的属性时,就以自己为准了。

# 派生属性
class Animal:def __init__(self, name, hp, dps):print('---->')self.name = nameself.hp = hpself.dps = dpsclass Person(Animal):def __init__(self, name, hp, dps, sex):# Animal.__init__(self, name, hp, dps)super().__init__(name, hp ,dps)  #super(Person, self).__init__(name, hp ,dps)self.sex = sex     # 派生属性
class Dog(Animal):def __init__(self, name, hp, dps, kind):Animal.__init__(self, name, hp, dps)super().__init__(name, hp ,dps)self.kind = kind   # 派生属性

alex = Person('alex', 250, 5, 'N/A')
ha2 = Dog('2哈', 15000, 200, '哈士奇')
print(alex.__dict__)
# {'name': 'alex', 'hp': 250, 'dps': 5, 'sex': 'N/A'}
print(ha2.__dict__)
# {'name': '哈士奇', 'hp': 15000, 'dps': 200}

子类重复的方法 重复的属性都放到父类中,子类特有的方法放到子类中

# 例
class Animal:def __init__(self, name, hp, dps):print('---->')self.name = nameself.hp = hpself.dps = dpsdef eat(self):print('%s吃药回血了' % self.name)
class Person(Animal):def __init__(self, name, hp, dps, sex):# Animal.__init__(self, name, hp, dps)super().__init__(name, hp ,dps)  #super(Person, self).__init__(name, hp ,dps)self.sex = sex     # 派生属性def attack(self,dog):dog.hp -= self.dpsprint('%s打了%s,%s掉了%s点血,剩余%s点血' % (self.name, dog.name, dog.name, self.dps, dog.hp))class Dog(Animal):def __init__(self, name, hp, dps, kind):Animal.__init__(self, name, hp, dps)self.kind = kind   # 派生属性def bite(self, person):person.hp -= self.dpsprint('%s咬了%s,%s掉了%s点血,剩余%s点血' % (self.name, person.name, person.name, self.dps, person.hp))alex = Person('alex', 250, 5, 'N/A')
ha2 = Dog('哈士奇', 15000, 200, 'zangao')
print(alex.__dict__)
# {'name': 'alex', 'hp': 250, 'dps': 5, 'sex': 'N/A'}
print(ha2.__dict__)
# {'name': '哈士奇', 'hp': 15000, 'dps': 200}
alex.eat()
# alex吃药回血了
ha2.eat()
# 哈士奇吃药回血了
alex.attack(ha2)
# alex打了哈士奇,哈士奇掉了5点血,剩余14995点血
ha2.bite(alex)
# 哈士奇咬了alex,alex掉了200点血,剩余50点血

子类继承父类方法

class G:def f0(self):print('G.f0')class F(G):def f1(self):print('F.f1')def f2(self):print('F.f2')class S(F):def f2(self):print('S.f2')super(S, self).f2() # 子类执行父类中的方法# F.f2(self)def f3(self):print('S.f3')s = S()
s.f0()
s.f1()
s.f2()
s.f3()
# G.f0
# F.f1
# S.f2
# F.f2
# S.f3

测试题

class Foo:def __init__(self):self.func()def func(self):print('in Foo')class Son(Foo):def func(self):print('in Son')Son()
# in Son
# Son() 实例化,创建对象self
# 执行父类Foo的init
# 调用self.func方法,按照--'先找对象的内存空间 -> 创建这个对象的类的内存空间 -> 父类的'的原则
# 所以,先找Son中的func,输出 in Son

6.多继承

python中有两种类

  经典类 py3已经灭绝了, 在py2里还存在,在py2中只要程序员不主动继承object,这个类就是经典类 -- 深度优先算法

  新式类 py3所有的类都是新式类,所有的新式类都继承自object -- 在多继承中遵循广度优先算法

python3
class A:def f(self):print('in A')class B(A):def f(self):print('in B')class C(A):def f(self):print('in C')class D(B):def f(self):print('in D')class E(C):def f(self):print('in E')class F(D,E):def f(self):print('in F')print(F.mro()) # 查看继承顺序,遵循广度优先原则, 如图
# [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

super和找父类这件事是两回事

在单继承中  super就是找父类

在多继承中  super的轨迹是根据整个模型的起始点而展开的一个广度优先顺序 遵循mro规则

# 例:
class A:def f(self):print('in A')class B(A):def f(self):print('in B')super().f()class C(A):def f(self):print('in C')super().f()class D(B,C):def f(self):print('in D')super().f()d = D()
d.f()
# in D
# in B
# in C
# in A

继承的总结:

继承的作用

  减少代码的重用

  提高代码的可读性

  规范编码模式

名词说明

  抽象: 抽象即抽取类似或者说比较像的部分, 是一个从具体到抽象的过程

  继承: 子类继承了父类的方法和属性

  派生: 子类在父类方法和属性的基础上产生了新的方法和属性

钻石继承

  新式类: 广度优先

  经典类: 深度优先

7.多态

在python中处处都是多态

在java(强数据类型语言)定义函数/执行函数参数都要表明参数的数据类型

# java 强数据类型语言
# def func(int a, str b, dic c):pass
# func(1, 'x', {'a':'b'})

在python(弱数据类型语言)中,定义函数/执行函数是参数不要求数据类型就可以执行

class Person():passalex = Person()
# 每个对象对应的数据类型,就是对象对应的类
print(type(alex)) # 类型是Person
# <class '__main__.Person'>
print(type('123'))
# <class 'str'>
print(type(123))
# <class 'int'>

转载于:https://www.cnblogs.com/gongniue/p/9041220.html

第十章 初识面向对象相关推荐

  1. 16.1、python初识面向对象(1)

    初识面向对象 楔子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人 ...

  2. Python初识面向对象

    一.Python初识面向对象 1.1 封装 class Person:country='中国' #静态字段,可以直接调用def __init__(self,name,pwd): #Python类自带的 ...

  3. 网工学Python——初识面向对象

    阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 类命名空间与对象.实例的命名空间 类的组合用法 初识面向对象小结 面向对象的三大特性 继承 多态 封装 ...

  4. Java基础-初识面向对象编程(Object-Oriented-Programming)

    Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...

  5. learn_Day14 内置函数补充、反射、初识面向对象

    内置函数 __import__()用于导入模块 getattr 用于寻找模块的指定对象 a = __import__('b')  # b为模块名,b是字符串 ==>> 导入模块b并重新命名 ...

  6. 第一小节 初识面向对象

    阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 类命名空间与对象.实例的命名空间 类的组合用法 初识面向对象小结 面向对象的三大特性 继承 多态 封装 ...

  7. JavaScript基础——第四章,JavaScript对象及初识面向对象

    文章目录 JavaScript对象及初识面向对象 1.对象 1.1 对象的概念 1.2 内置对象 1.3 自定义对象 1.3.1 操作符new创建对象 1.3.2 使用字面量赋值的方式定义对象 2.构 ...

  8. python人狗大战游戏_day22 01 初识面向对象----简单的人狗大战小游戏

    day22 01 初识面向对象----简单的人狗大战小游戏 假设有一个简单的小游戏:人狗大战   怎样用代码去实现呢? 首先得有任何狗这两个角色,并且每个角色都有他们自己的一些属性,比如任务名字nam ...

  9. day22~day23初识面向对象

    python之路--初识面向对象 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同 ...

最新文章

  1. 经典论文复现 | LSGAN:最小二乘生成对抗网络
  2. 单元测试——第六周作业
  3. 实时平台在趣头条的建设实践
  4. 【题解】【洛谷 P1967】 货车运输
  5. 以孩子兄弟链表为存储结构,请设计递归算法求树的高度
  6. 开发人员需要了解的测试
  7. 【网络基础】【TCP/IP】私有IP地址段
  8. android绘制矢量图_Android矢量可绘制
  9. 重启路由器可以换IP吗
  10. ipMonitorAdministratorGuide
  11. FlexPaper查看.swf文件的使用方法
  12. iOS country code及国际区号
  13. html下拉栏去掉样式,怎么去掉下划线样式?
  14. Arduino UNO+OLED可视化音乐频谱:32段分频0.96寸OLED显示细条频谱线
  15. 深度学习关于分布式任务调度平台XXL-JOB框架详解
  16. 气功修炼常识之:调息、丹田呼吸、脐呼吸、体呼吸
  17. 好歌推荐 绝对经典(中外结合)
  18. Linux环境下安装Redis(保姆级教程)
  19. 什么是PON(无源光纤网络)、PON的发展及演进
  20. C#22GDI+图形图像处理技术

热门文章

  1. OKL4虚拟化技术跟踪
  2. 迷你WiFi摄像机需要多少兆的带宽才不会卡顿
  3. Oracle内存结构:SGA PGA UGA
  4. 6 个接私活的网站,你有技术就有钱!推荐给大家!
  5. 计算机毕业设计SSM 校园疫情防控系统【附源码数据库】
  6. AdMob Mediation + Vungle (iOS + Android)
  7. 邮件里面的图怎么复制出来_图文并茂的电子邮件制作,只要你想,你也能做到...
  8. Chrome调试工具(CSS)
  9. 华为p20Android怎么解开,华为P20/P20 Pro如何进行双清?华为P20进recovery双清格机教程...
  10. BGA焊盘分类和阻焊层要求