## 复习
1.类
对象属性的查找顺序: 先找自身再找类
1)类的名称空间:直接写在类中
2) 对象的名称空间:写在__init__方法中,通过self.属性形成名称空间中的名字
3) 类的方法:在类中用@classmethod装饰的方法,第一个参数一定接收类,建议只拿类来调用
4) 对象方法:在类中定义的普通方法,第一个参数一定接收对象,建议只拿对象调用
2.封装:对外隐藏属性与方法的实现细节,类的内部均可以直接访问 __名字
# 方式:在属性或方法前用__修饰,将 __名字 更名为 _类名__名字
# 作用:有些属性或方法只提供给内部使用,所有采用封装处理
# 对象属性的封装,对外提供接口:
@property
def id(self):
return self.__id
@id.setter
def id(self, id):
self.__id = id
@id.deleter
def id(self):
del self.__id
组合:自定义类的对象作为类的属性
继承:父类与子类,多继承
接口:python中没有接口的语法,接口是一种编程思想
抽象类:abc(元类的思想)
多态:继承方式的多态,鸭子类型
```
## 作业
# class A:
# pass
#
# # 内部类
# class B:
# pass
# class C:
# pass
# print(C.__dict__)
# print(B.C.__dict__)
class Zombie:
def __init__(self, name):
self.HP = 100
if name not in ['普通僵尸', '路障僵尸', '铁桶僵尸']:
name = '普通僵尸'
if name.startswith('普通'):
self.__armor = ['无', 0]
elif name.startswith('路障'):
self.__armor = ['路障', 5]
else:
self.__armor = ['铁桶', 15]
self.name = name
@property
def armor_count(self):
return self.__armor[1]
@property
def armor_name(self):
return self.__armor[0]
@armor_name.setter
def armor_name(self, a_name):
if a_name not in ['无', '路障', '铁桶']:
return
if a_name == '无':
self.__armor = ['无', 0]
a_name = '普通'
elif a_name == '路障':
self.__armor = ['路障', 5]
else:
self.__armor = ['铁桶', 15]
self.name = '%s僵尸' % a_name
# 测试Zombie类
zombie = Zombie('铁桶僵尸')
zombie.aaa()
# # zombie = Zombie(123)
# # print(zombie.__dict__)
# print(zombie.armor_name)
# zombie.armor_name = '路障'
# print(zombie.__dict__)
class User:
def __init__(self, name):
self.name = name
def beat(self, zombie):
u_name = self.name # 用户名
z_name = zombie.name # 僵尸名
z_HP = zombie.HP # 僵尸血量
low_PH = 25 - zombie.armor_count # 不同道具下僵尸的一次掉血量
while z_HP > 0:
import time
time.sleep(1)
z_HP -= low_PH
print("%s攻击了%s僵尸,僵尸损失%s滴血,还剩%s滴血" %
(u_name, z_name, low_PH, z_HP))
print('%s击杀了%s' % (u_name, z_name))
import random
class Game:
name = "植物大战僵尸"
@classmethod
def start(cls):
print(cls.name)
user = User('Owen')
for i in range(1, 4):
# 可以分别随机产生三个僵尸
name = random.choice(['普通僵尸', '路障僵尸', '铁桶僵尸'])
zombie = Zombie(name)
print('开始击杀第%d只僵尸' % i)
user.beat(zombie)
print('第%d只僵尸已被击杀完毕' % i)
Game.start()
```
## 面向对象的三大特性
- 封装:隐藏细节-抽离共有
- 继承:父类与子类,多继承
- 多态:继承方式的多态,鸭子类型
## 继承
#继承
#什么是继承:继承是一种新建类的方式,新建的类称之为子类/派生类,被继承的类称之为父类、基类、超类
#继承的特性:子类可以遗传/重用父类的属性
#python中继承的特点
#1、python中一个子类可以同时继承多个父类
#2、在继承背景下说,python中的类分为两种:新式类,经典类
#新式类:但凡继承了object的类,以及该类的子类,都是新式类(在python3中都是会默认继承object,都是新式类)
#经典类:没有继承object的类,以及该类的子类,都是经典类(在python2中没有写object,不会默认继承)
# 有继承关系下的属性查找顺序:
# 1.优先找自身,自身没有找父类
# 2.父类没有找父类的父类
# 3.一直找到最顶级的父类,如果还没有报错
# 抽离:先有多个有共同点的类,抽离出共性形成的类 => 父类
# 派生:通过已有的父类,再去定义该类的子类,这种方式就叫做派生
class OldboyStudent:
school='oldboy'
def __init__(self,name,age,sex,score=0):
self.name=name
self.age=age
self.sex=sex
self.score=score
def choose_course(self):
print('%s choosing course '%self.name)
class OldboyTeacher:
school='oldboy'
def __init__(self,name,age,sex,level):
self.name=name
self.age=age
self.sex=sex
self.level=level
def score(self,stu,num):
stu.score=num
#将其变成继承
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople): ## 留下自己的新东西就叫派生,如果这里啥也不写,就表示全部都是来自于父类,
# 如果有一个新的技能,会以自己的新技能为准,如果父类有一个跟新技能重名,那始终还是以自己的技能为准,这就是派生
def choose_course(self):
print('%s choosing course'%self.name)
class OldboyTeacher(OldboyPeople):
def score(self,stu,num):
stu.score=num
stu1=OldboyStudent('里二蛋',18,'male')
#这个空对象,会去类中找_init__这个函数,类中没有就去父类中找
#二、子类派生的新方法中重用父类功能的方式有两种:
#指名道姓 #super()
#两者不可混用
#1、super()
# 严格依赖继承的mro列表
# 访问时是绑定方法
#注意:在python2中super(自己的类名,自己的对象)
#在python3中super()调用时会得到一个特殊的对象,该对象专门用来访问父类中的属性,完全参照mro列表
# super()必须在类中使用
#第一种方式:super()
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent:
def __init__(self,name,age,sex,score=0):
super(OldboyPeople,self).__init__(name,age,sex) super().__init__(name) # 父级有的共性功能通过super()交给父级做
self.score=score #子类特有的自己来完成
def choose_course(self):
print('%s choosing course'%self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level):
super().__init__(name,age,sex)
self.level=level
def score(self,stu,num):
stu.score=num
#第二种方式:指名道姓d地引用某一个类中的函数
#注意:
#1、与继承无关
#2、访问是类中的函数,没有自动传值的效果
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent:
def __init__(self, name, age, sex, score=0):
OldboyPeople.__init__(self,name, age, sex)
self.score = score
def choose_course(self):
print('%s choosing course' % self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level):
OldboyPeople.__init__(self, name, age, sex)
self.level = level
def score(self, stu, num):
stu.score = num
# 在多继承背景下属性查找的优先级:
#如果一个子类继承多个分支(多个分支又同时继承一个非object的类),
# 此时属性的查找优先级是:对象》对象的类》按照从左往右的顺序,一个分支一个分支找下去
```
补充继承
```python
继承的信息
class Sup:
__num = 10 # 封装被更名为_Sup__num
def __init__(self, name):
self.__name = name
@property
def name(self):
print(self)
return self.__name
@classmethod
def __c_fn(cls):
print(cls, 'c fn')
#
# def __o_fn(self):
# print(self.name, 'o fn')
class Sub(Sup):
def test(self):出现子类对象的属性比父类多
print(self)# 父类对象调用就是父类对象,子类对象调用就是当前调用的子类对象
print(self.__name) # 本质去访问_Sub__name,所以不能访问
# print(Sub.num)
sub = Sub('sssssssss') 默认父级的__init__可以被继承过来,
Sub._Sup__c_fn()
# print(sub.name)
# sub.o_fn()
# print(Sup.__dict__)
# sub = Sub('sssssssss')
# print(sub.name)
# sub.test()
# 继承关系
# 1.父类的所有未封装的属性和方法,子类都能访问
# 2.父类的所有封装的属性和方法,子类都不能访问
# -- 在外界通过子类或子类对象,不能访问
# -- 在子类内部也不能访问
# 有继承关系下的属性查找顺序:
# 1.优先找自身,自身没有找父类
# 2.父类没有找父类的父类
# 3.一直找到最顶级的父类,如果还没有报错
# 两个名词:
# 先写子类,抽离 出父类
# 先写父类,派生 出子类
class Sup:
num = 10
def test(self):
print('test sup')
class Sub(Sup):
num = 100
# 先写好父类的方法,由于父类方法的功能不满足子类需求,
# 子类可以重写父类方法:方法名与父类相同,自定义方法的实现体
def test(self):
print('test sub')
print(Sub.num)
Sub().test()
```
## 组合
```python
#二、组合
#1、社么是组合
#组合指的是某一个对象拥有一个属性,该属性的值是另一个类的对象
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople):
def __init__(self,name,age,sex,c_name,c_price,c_period,score=0):
OldboyPeople.__init__(self, name, age, sex)
self.score = score
self.c_name=c_name
self.c_price=c_price
self.c_price=c_period
def choose_course(self):
print('%s choosing course' % self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level,c_name,c_price,c_period):
OldboyPeople.__init__(self, name, age, sex)
self.level = level
self.c_name=c_name
self.c_price=c_price
self.c_period=c_period
def score(self, stu, num):
stu.score = num
# 将重复放入类中
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex,c_name, c_price, c_period,):
self.name = name
self.age = age
self.sex = sex
self.c_name = c_name
self.c_price = c_price
self.c_price = c_period
class OldboyStudent(OldboyPeople):
def __init__(self, name, age, sex,c_name, c_price, c_period,score=0):
OldboyPeople.__init__(self, name, age, sex,c_name, c_price, c_period)
self.score = score
def choose_course(self):
print('%s choosing course' % self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level, c_name, c_price, c_period):
OldboyPeople.__init__(self, name, age, sex, c_name, c_price, c_period)
self.level = level
def score(self, stu, num):
stu.score = num
#创建课程
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent(OldboyPeople):
def __init__(self, name, age, sex, c_name, c_price, c_period, score=0):
OldboyPeople.__init__(self, name, age, sex)
self.score = score
def choose_course(self):
print('%s choosing course' % self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level, c_name, c_price, c_period):
OldboyPeople.__init__(self, name, age, sex, c_name, c_price, c_period)
self.level = level
def score(self, stu, num):
stu.score = num
class Course:
def __init__(self,c_name,c_price,c_period ):
self.c_name=c_name
self.c_price=c_price
self.c_period=c_period
def tell_info(self):
print('课程名:%s,价钱:%s,周期:%s'%(self.c_name,self.c_price,self.c_period))
python=Course('python全栈开发',1900,'5mons')
linux=Course('linux架构师',900,'3mons')
stu1=OldboyStudent('nn',23,'male')
stu1.course1=python
print(stu1.__dict__)
stu1.course1.tell_info()
#多门课程
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent(OldboyPeople):
def __init__(self, name, age, sex,score=0):
OldboyPeople.__init__(self, name, age, sex)
self.score = score
self.courses=[]
def choose_course(self):
print('%s choosing course'%self.name)
def tell_all_course(self):
print(('学生【%s】选修的课程如下'%self.name).center(50,'='))
for obj in self.courses:
obj.tell_info()
print('='*60)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, level):
OldboyPeople.__init__(self, name, age, sex)
self.level = level
self.courses=[]
def score(self, stu, num):
stu.score = num
def tell_all_course(self):
print(('老师【%s】教授的课程如下'%self.name).center(50,'*'))
for obj in self.courses:
obj.tell_info()
print('*',*70)
class Course:
def __init__(self, c_name, c_price, c_period):
self.c_name = c_name
self.c_price = c_price
self.c_period = c_period
def tell_info(self):
print('课程名:%s,价钱:%s,周期:%s' % (self.c_name, self.c_price, self.c_period))
python=Course('python 全栈开发',1900,'5mons')
linux=Course('linux架构师',900,'3mons')
stu1=OldboyStudent('刘二蛋',34,'male')
stu1.courses.append(python)
stu1.courses.append(linux)
stu1.tell_all_course()
teal=OldboyTeacher('egon',18,'male',10)
teal.courses.append(python)
teal.tell_all_course()
```