print('面向对象')
'''
今日内容:
1,继承
2,多态
3,封装
4,绑定方法和非绑定方法
classmethod
staticmethod
5,面向对象高级
反射
一些内置方法
__str__
__del__
6,元类(看视频)
这个是属于面向对象底层的知识点,可能会打破你之前对于面向对象的知识点认知
所以这个放到后面讲,当你对面向对象有了足够的了解之后,再深入的研究这个
面向对象:核心是对象二字
对象:对象是特征(变量)与技能(函数)的结合体
基于该思想编写程序,就好比是在创造一个世界,你就是这个世界的上帝
世界是由一个个对象组成的
在上帝眼里所有存在的事物都是对象,任何不存在的事物也可以创造出来
优点:可扩展性强
缺点:编程复杂度高于面向过程编程
类:
对象是特征与技能的结合体
而类则是一系列对象相同特征与技能的结合体
对象是具体存在的,而类是总结出来的抽象的概念
类本质就是一个容器(名称空间)
对象本身也是一个容器(名称空间)
在现实世界中,先有对象,再先有类
在程序中,先定义类,再调用类,实例化生成对象
定义类
class OldboyStudent:
# "文档注释"
#相同的特征
school = 'oldboy'
#相同的技能:
def choose_course(self):
pass
类体代码会在类定义阶段立即执行,产生一个类的名称空间,用来存放类体代码执行过程中产生的名称与变量
使用类
两种用途:
1,当做一个容器
2,调用类产生对象
调用类会产生两件事:
1:产生一个空对象
2,触发类的函数,对象的绑定方法
强调__init__方法:
1,该方法是在产生对象之后才调用
2,该方法可以有任意python代码,但是唯独不能有返回值
属性查找:
强调:类的属性与对象的属性,访问时必须加前缀
先从对象自己的名称空间中查找,如果没有再到类的名称空间中查找
绑定方法:
类中定义的函数,是类的函数属性,就是一个普通函数,没有自动传参的效果
但类中定义的函数其实是绑定给对象用的,称之为绑定方法,绑定方法的特殊之处
就在于绑定给谁就应该由谁来调用,谁来调用就会将第一个位置的参数自动传入
在python 中统一了一个类与类型的概念
一切皆对象
class OldboyStudent:
# "文档注释"
# 相同的特征
school = 'oldboy'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
pass
# 相同的技能:
def choose_course(self):
pass
# print(OldboyStudent.__dict__)
stu1 = OldboyStudent('szp',24,'male')
print(stu1.name)
print(stu1.age)
print(stu1.gender)
'''
print('hello')
'''
面向对象的三大特性:
1,继承
2,多态
3,封装
一.继承
1,什么是继承?
继承是一种新建类的方式,新建的类称之为子类,被继承的类称之为基类,父类 或者超类
继承描述的是一种遗传的关系,子类可以重用父类的属性
在python中的继承注意两点:
1,在python中支持一个紫烈同时继承多个父类, 而在java中,一个子类只能继承一个父类
2,Python中类分为两种:
新式类:但凡继承object的类,以及该类的紫烈 都是新式类
经典类:没有继承object的类,以及该类的子类 都是经典类
在python3中,一个类如果没有继承任何类,那么默认继承object类,即python3中,所有的类都是新式类
在python2中才区分新式类与经典类
2,为何要用继承?
1,减少代码冗余
3,如何用继承?
class Parent1:
name = 'szp'
class Parent2:
age = 24
pass
class Subclass(Parent1,Parent2):
pass
print(Parent1.__bases__)
print(Subclass.__bases__)
print(Subclass.name)
print(Subclass.age)
'''
'''
1,如何利用继承减少代码的冗余?
2,在继承的背景下,属性查找的优先级
3,新式类与经典类的区别????????????????
现在我们来重点学习一下,如何用继承减少代码的冗余?
继承解决的是类与类之间的代码冗余的问题,一定是一个类是另一个类的子类 存在这种父子关系
总结继承关系:
总结对象之间的相似之处得到类,总结类与类之间的相似之处就得到了类们的父类
问题:如何在子类派生出的新方法中重用父类的功能???
在子类派生的新方法中,重用父类的功能方式一:
知名道姓的访问某一个类的函数
注意:
1,该方式与继承是没有关系的
2,访问的是某一个类的函数,没有自动传值的效果
这种做法是直接调用,就像调用函数一样,和继承没有多大关系,但是很好的解决了这个代码冗余的问题
class OldboyPeople:
school = 'oldboy'
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent(OldboyPeople):
score = 0
def __init__(self,name,age,sex,score):
OldboyPeople.__init__(self,name,age,sex)
self.score = score
def choose_course(self):
print('%s is choosing course' %self.name)
pass
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
stu1 = OldboyStudent('szp',24,'male',90)
print(stu1.name)
print(stu1.age)
print(stu1.sex)
print(stu1.score)
tea = OldboyTeacher('Owen',34,'male',8)
print(tea.name)
print(tea.age)
print(tea.sex)
print(tea.level)
2,在继承的背景下,属性查找的优先级
现在研究这个问题2,在继承的背景下,属性查找的优先级,既然说到继承背景,就需要考虑分成两个方面:一个是单继承,也就是继承一个,
另一个是多继承,也就是一个子类继承多个父类的
我们首先考虑单继承:
在单继承的情况下,属性查找,首先找对象自己的,找不到再去找对象所属的子类,子类再找不到,就去找父类,然后找父类的父类
一直找上去
验证:
class Foo:
x = 1
pass
class Bar(Foo):
# x = 2
pass
obj = Bar()
# obj.x = 3
print(obj.x)
例子2
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')