## 复习

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()
```

day24的更多相关文章

  1. 阶段01Java基础day24多线程+GUI

    25.01_多线程(多线程方法) 1.yield让出cpu 2.setPriority()设置线程的优先级 25.02_多线程(单例设计模式)(掌握) 单例设计模式:保证类在内存中只有一个对象. 如何 ...

  2. day24<多线程>

    多线程(多线程的引入) 多线程(多线程并行和并发的区别) 多线程(Java程序运行原理和JVM的启动是多线程的吗) 多线程(多线程程序实现的方式1) 多线程(多线程程序实现的方式2) 多线程(实现Ru ...

  3. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  4. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  5. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  6. Java多线程

    一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程.   进程:进程 ...

  7. .NET基础拾遗(5)多线程开发基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  8. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  9. C#多线程之线程池篇3

    在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...

  10. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

随机推荐

  1. Mysql8安装与配置

    网上的教程有很多,基本上大同小异.但是安装软件有时就可能因为一个细节安装失败.我也是综合了很多个教程才安装好的,所以本教程可能也不是普遍适合的. 安装环境:win7 1.下载zip安装包: MySQL ...

  2. jupyter notebook 动态图显示

    直接在import matplotlib.pyplot as plt 后面加%matplotlib,或者%matplotlib auto就可以通过弹出窗口的形式显示图片

  3. Javascript循环删除数组中元素的几种方法示例

    发现问题 大家在码代码的过程中,经常会遇到在循环中移除指定元素的需求.按照常规的思路,直接一个for循环,然后在循环里面来个if判断,在判断中删除掉指定元素即可.但是实际情况往往不会像预想的那样顺利运 ...

  4. turtle模块绘图

    import turtle #运动命令 # forward(d) 向前移动d长度 # backward(d) 向后移动d长度 # right(d) 向右转动多少度 #left(d) 向左转动多少度 # ...

  5. HTML5的优点与缺点?

    优点:a.网络标准统一.HTML5本身是由W3C推荐出来的. b.多设备.跨平台 c.即时更新,提高可用性和改进用户的友好体验: d.有几个新的标签,这将有助于开发人员定义重要的内容: e.可以给站点 ...

  6. conn.encoders[SafeBytes] = conn.encoders[bytes] KeyError: <class 'bytes'>

    问题描述:Django连接mysql数据库,修改了setting.py文件后,启动服务器报错 错误截图如下: 解决方法: 1.pip install pymsql 2.在setting.py同目录下的 ...

  7. TTL和COMS电平匹配以及电平转换的方法

    一.TTL TTL集成电路的主要型式为晶体管-晶体管逻辑门(transistor-transistor logic gate),TTL大部分都采用5V电源.1.输出高电平Uoh和输出低电平UolUoh ...

  8. MQ知识点汇总

    1. MQ是什么 2. MQ能做什么 3. 消息模式 4. 使用MQ的时候需要注意什么 5. 常用MQ 6. MQ的不足 7. 什么时候不适用MQ 8. MQ的组成 9. MQ的关注点 1. MQ是什 ...

  9. REST AND SOAP

    REST,即Representational State Transfer的缩写.直接翻译的意思是"表现层状态转化".它是一种互联网应用程序的API设计理念:URL定位资源,用HT ...

  10. uploadify上传图片的使用

    一:引用jquery.uploadify.js 二:代码 <body> <table> <tr> <td style="width: 15%; te ...