欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python面向对象编程

程序员文章站 2022-05-08 14:44:15
...

python面向对象编程

python支持函数式编程面向对象式编程
需要实现以下

小明,12岁,男,喜欢打篮球
小明,12岁,男,喜欢踢足球
小明,12岁,男,喜欢打羽毛球

老王,32岁,男,喜欢抽烟
老王,32岁,男,喜欢喝酒
老王,32岁,男,喜欢大保健
  1. 定义
    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 => 类的方法
    self

    class 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、存在统一根时,根最后执行
python面向对象编程注意避坑:

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等等。。。。

相关标签: python