python面向对象编程
python面向对象编程
python支持函数式编程和面向对象式编程
需要实现以下
小明,12岁,男,喜欢打篮球
小明,12岁,男,喜欢踢足球
小明,12岁,男,喜欢打羽毛球
老王,32岁,男,喜欢抽烟
老王,32岁,男,喜欢喝酒
老王,32岁,男,喜欢大保健
-
定义
1、函数:
def + 函数名(参数)def foo(name,age,sex,hobby): print('%s,%s,%s,%s'%(name,age,sex,hobby)) foo('小明','12岁','男','喜欢打篮球') # 小明,12岁,男,喜欢打篮球 foo('小明','12岁','男','喜欢踢足球') # 小明,12岁,男,喜欢踢足球 foo('小明','12岁','男','喜欢打羽毛球') # 小明,12岁,男,喜欢打羽毛球 foo('老王','32岁','男','喜欢抽烟') # 老王,32岁,男,喜欢抽烟 foo('老王','32岁','男','喜欢喝酒') # 老王,32岁,男,喜欢喝酒 foo('老王','32岁','男','喜欢大保健') # 老王,32岁,男,喜欢大保健
2、面向对象:
class => 类
def => 类的方法
selfclass bar: def foo(self,name,age,sex,hobby): print('%s,%s,%s,%s'%(name,age,sex,hobby)) a = bar() # 类的实列化,建立类对象 a.foo('小明','12岁','男','喜欢打篮球') # 小明,12岁,男,喜欢打篮球 a.foo('小明','12岁','男','喜欢踢足球') # 小明,12岁,男,喜欢踢足球 a.foo('小明','12岁','男','喜欢打羽毛球') # 小明,12岁,男,喜欢打羽毛球 a.foo('老王','32岁','男','喜欢抽烟') # 老王,32岁,男,喜欢抽烟 a.foo('老王','32岁','男','喜欢喝酒') # 老王,32岁,男,喜欢喝酒 a.foo('老王','32岁','男','喜欢大保健') # 老王,32岁,男,喜欢大保健
现在看,面向对象的编程方式,并没有比函数式编程简洁,继续向下看;
2. 执行
1、函数 :
函数名(参数)
2、面向对象:
创建一个中间对象,将中间对象赋值给一个变量(即:类的实例化,中间对象即为self
)
利用中间对象调用类下面的各种方法
class bar:
def foo(self,hobby):
print('%s,%s,%s,%s'%(self.name,self.age,self.sex,hobby))
a = bar() # 类的实列化,建立类对象
a.name = '小明'
a.age = '12岁'
a.sex = '男'
a.foo('喜欢打篮球') # 小明,12岁,男,喜欢打篮球
a.foo('喜欢踢足球') # 小明,12岁,男,喜欢踢足球
a.foo('喜欢打羽毛球') # 小明,12岁,男,喜欢打羽毛球
b = bar()
b.name = '老王'
b.age = '32岁'
b.sex = '男'
b.foo('喜欢抽烟') # 老王,32岁,男,喜欢抽烟
b.foo('喜欢喝酒') # 老王,32岁,男,喜欢喝酒
b.foo('喜欢大保健') # 老王,32岁,男,喜欢大保健
这样对比之前函数式编程是不是好多了;
此处可以看出来了把,何时使用函数式编程,何时使用面向对象式编程,故面向对象编程的使用场景是:如果多个函数中均使用相同的参数,那么使用面向对象式编程
继续学习面向对象式编程:
面向对象编程:构造方法 __init__
作用:开始将类实列化时,同时取读取引入的参数,将其放到实列化的对象中,供随时调用:
class bar:
def __init__(self,name,age,sex)
self.name = name
self.age = age
self.sex = sex
def foo(self,hobby):
print('%s,%s,%s,%s'%(self.name,self.age,self.sex,hobby))
a = bar('小明','12岁','男') # 类的实列化,建立类对象
a.foo('喜欢打篮球') # 小明,12岁,男,喜欢打篮球
a.foo('喜欢踢足球') # 小明,12岁,男,喜欢踢足球
a.foo('喜欢打羽毛球') # 小明,12岁,男,喜欢打羽毛球
b = bar('老王','32岁','男')
b.foo('喜欢抽烟') # 老王,32岁,男,喜欢抽烟
b.foo('喜欢喝酒') # 老王,32岁,男,喜欢喝酒
b.foo('喜欢大保健') # 老王,32岁,男,喜欢大保健
此时面向对象编程是不是调用方式更加简便了呢?
这就是面向对象编程的三大特性之一:封装
继续往下看:
如果我对于此打印内容需要变更时,我会怎么做?
class bar:
def __init__(self,name,age,sex)
self.name = name
self.age = age
self.sex = sex
def foo(self,hobby):
print('%s,%s,%s,%s'%(self.name,self.age,self.sex,hobby))
class child(bar):
def foo1(self,where,hobby)
print('%s,%s,%s,%s%s'%(self.name,self.age,self.sex,where,hobby))
a = child('小明','12岁','男') # 类的实列化,建立类对象
a.foo1('在公园','喜欢打篮球') # 小明,12岁,男,在公园喜欢打篮球
a.foo1('在球场','喜欢踢足球') # 小明,12岁,男,在球场喜欢踢足球
a.foo1('在学校','喜欢打羽毛球') # 小明,12岁,男,在学校喜欢打羽毛球
b = child('老王','32岁','男')
b.foo1('在阳台','喜欢抽烟') # 老王,32岁,男,在阳台喜欢抽烟
b.foo1('在酒吧','喜欢喝酒') # 老王,32岁,男,在酒吧喜欢喝酒
b.foo1('在按摩店','喜欢大保健') # 老王,32岁,男,在按摩店喜欢大保健
在第二个类中,并没有引入name、age、sex等,为什么任可以继续调用呢,细心的人观察到我在建立第二个类时,加了一个括号,括号中加了一个ber:class chiind(bar):
,这就是面向对象的第二个特性:继承
;
在面向对象编程时,定义的类对象可以引用其他类的内容:只需将父类(基类)以变量的形式传入子类(派生类)中,即可在子类中继承父类,调用父类。
当不想要继承父类的某一函数时,只需在子类函数中定义一个相同命名的函数即可(此举默认为放弃继承父类指定函数,因为默认当一个类实例化后,类中的self
就代值实例化的对象),当执行一个类方法时,实例对象会先在当前类中找对应类方法,当当前类找不到时,才会到父类中寻找);
当然,也可以取消默认,取消方法如下:
class father:
def f1(self):
print('father:f1')
def f2(self):
print('father:f2')
class child(father):
def f1(self): # 直接引入一个与父类相同的方式,默认不在继承父类方法
print('child:c1') # child:c1
def f2(self): # 引入一个与父类名称一致的方法后,任想要继续调用父类的方式,只需在方法中添加super(子类名,实列化对象).父类函数即可
super(child,self).f2() # father:f2 #执行父类(基类)的方法 如果此方法还需要引入参数,不用加self,self在前面已经引入了
# 或者使用 father.f2(self) 也可执行父类方法 有参数,在self后继续添加即可 与super效果一致 推荐使用super
print('chind:c2') # chind:c2
a = child()
a.f1() # child:c1
a.f2() # father:f2 chind:c2
继承方式,除上述多继承外,还有一个与c++相同的,其他语言都没有的功能:多继承;
class father:
def f1(self):
print('father:f1')
class father2:
def f1(self):
print('father:f2')
class child(father,father2):
pass
a = child()
a.f1() # father:f1
同时继承多个父类,从上代码中,可以猜想出,当多继承父类们有相同方法时,默认按子类继承引入顺序调用,即从左往右继承。
那么,当多继承遇到父类上还有父类时,继承优先级又如何处理呢?
class grandfather:
def f1(self):
print('grandfather:f1')
class father(grandfather):
def f0(self):
print('father:f1')
class father2:
def f1(self):
print('father:f2')
class child(father,father2):
pass
a = child()
a.f1() #grandfather:f1
结论:
调用方法时,继承的优先级默认顺序总是为在子类的基础上找父类,在找父类的父类,直到不存在父类,再找第二个父类,以此类推,注意:此处注明了一个特殊关系,当其中一个顶父类与其他关系存在交集时,优先级降低,不再走到黑!
总结:1、左侧优先、2、一条道走到黑、3、存在统一根时,根最后执行
注意避坑:
class grandfather:
def f1(self):
print('grandfather:f1')
class father(grandfather):
def f0(self):
print('father:f1')
self.f1()
def f1(self):
print('father:f2')
class father2:
def f1(self):
print('father2:f2')
class child(father2,father):
pass
a = child()
a.f0() # father:f1 father2:f2
# 按以上规则,执行f0 找到的时father.f0()毋庸置疑,但是在,f0下调用self.f1时,会执行啥?注意,self永远指代实列化的对象,即child(),故此处self.f1(),与a.f1()没有任何区别,当然优先级也没有区别!!!
面向对象编程的三大特性最后一个特性为:多态
何为多态:引入参数多形态:string、int、list等等。。。。