封装,继承,多态。
定义一个类,它就是封装。通过类,可以将类里面的一些属性和方法封装在一起。子类继承父类,可以获得父类里面的属性和方法,这个就叫做继承。
严格来说,Python中是没有多态的,但是Python中可以实现伪多态,Python中函数的参数是没有类型限制的。Python中有个鸭子类型,比多态更厉害。
多态是建立在继承的基础上的。指的是一类事物有多种形态,其实就是一个父类有多个子类。
父类里面有某个方法,在子类中同样也有这个方法。但是在子类中有这个方法体现的形式和父类中不一样。
在调用这个父类,它所有的子类对象里面,同样是调用同一个方法。因为是不同的子类,所以执行的内容、结果、功能不一样,这就是多态。
都是动物类,但是有不同的形态
多态是建立在继承的基础上的。
Python中实现的多态是伪多态。Python中定义一个函数,只要函数给它传参数,对于函数的参数是没有类型限制的。
c和java定义一个函数,函数的参数是有类型限制的。指定这个函数的参数只能传什么类型。
定义一个函数,调用的时候可以传字符、数值、列表。a这个参数没类型限制,传个类进去也行,传个函数进去也可以,传个对象进去也可以,传什么都可以,没有类型限制。
#Python中函数的参数是没有类型限制的。
def func(a):
print(a)
func(122)
func('1213')
func([12,22])
运行结果
假如Python是个强类型语言。函数只能传父类(Base)这个类型的数据。接下来子类的对象是不是属于这个父类?
# 伪多态的实现。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):#继承Base。
def run(self):#同样里面也有run()方法。
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
print(isinstance(c_obj,Base))
多态是建立在继承的基础上,同样多态要重写。
运行结果
子类所创建出来的对象也属于父类的类型。
假设func()的参数需要Base类型的。Cat和Dog这个子类创建出来的对象也是属于Base类型的。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):
def run(self):
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
class Pig(Base):#同样也继承于Base
pass#这个里面没有任何方法。
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
p_obj=Pig()
# 子类的对象是属于父类的类型。
# print(isinstance(c_obj,Cat))
# print(isinstance(c_obj,Base))
#Python中函数的参数是没有类型限制的。
# 假设func的参数需要Base类型的。
def func(base_obj):
base_obj.run()
func(b_obj)
func(c_obj)
func(d_obj)
func(p_obj)#这个类创建出来的对象,它传进去的时候,它里面没有run()方法,调用父类的run方法。
# func(122)
# func('1213')
# func([12,22])
运行结果
这个就是个多态。一类事物有不同的形态。传进去的b_obj、c_obj、d_obj、p_obj都是属于Base这个类型的。
Base这个父类有很多个子类。参数限定的时候,限定的是Base这个类。
但是如果传入不同子类,同样的方法传入这个类型的对象。因为是不同的子类创建出来的,它会执行不同的功能。
有一个不同的体现,那么这种就叫做多态。
注意:Python中函数的参数是没有类型限制的,所以多态在Python中的体现并不是很严谨。多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
不修要修改原来已经实现的功能代码,通过继承扩展新的功能。重新定义方法,变成另外一种形态:
# 伪多态的实现。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):
def run(self):
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
class Pig(Base):#同样也继承于Base
def run(self):
print("这是一个幂运算")
class CCC(Base):
def run(self):#重新定义方法,变成另外一种形态。
print("cccc功能")
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
p_obj=Pig()
c=CCC()
# 子类的对象是属于父类的类型。
# print(isinstance(c_obj,Cat))
# print(isinstance(c_obj,Base))
#Python中函数的参数是没有类型限制的。
# 假设func的参数需要Base类型的。
def func(base_obj):
base_obj.run()
func(b_obj)
func(c_obj)
func(d_obj)
func(p_obj)
func(c)
# func(122)
# func('1213')
# func([12,22])
运行结果
在Python里面这个是伪多态的实现。
多态的意义:开放封闭的原则。
鸭子类型概念: 它并不要求严格的继承体系,关注的不是对象的类型本身,而是它是如何使用的,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
定义个类不继承Base,在里面定义个run()方法,把MyClass这个类创建个对象。调用这个函数,把m传进去,同样也可以调用。
# 伪多态的实现。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):
def run(self):
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
class Pig(Base):#同样也继承于Base
def run(self):
print("这是一个幂运算")
class CCC(Base):
def run(self):#重新定义方法,变成另外一种形态。
print("cccc功能")
class MyClass(object):#这个类不继承Base
def run(self):
print("是myclass的run方法")
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
p_obj=Pig()
c=CCC()
m=MyClass()
# 子类的对象是属于父类的类型。
# print(isinstance(c_obj,Cat))
# print(isinstance(c_obj,Base))
#Python中函数的参数是没有类型限制的。
# 假设func的参数需要Base类型的。
def func(base_obj):
base_obj.run()
func(b_obj)
func(c_obj)
func(d_obj)
func(p_obj)
func(c)
func(m)
# func(122)
# func('1213')
# func([12,22])
运行结果
像java和c这种强类型的语言,多态的意义在于参数有类型的限制,限制只能传入某个类型的参数,某个类型对象的数据。那么接下来传数据的话只能传这个类型,或者传它的子类。
在Python里的参数没类型限制的。也就是说不用多态照样能够实现,只要定义一个类,类里面有这个run()方法就行了。
因为传进去的对象在里面调用的是run()方法,自己定义一个类,类里面只要有run()方法,那么就都能够放在这个函数例如func()里面去调用。不会报错,有run()方法就行了。不继承它也可以。这叫做鸭子类型。
自己定义的类里面,只要实现了这个里面的方法:
Python中的多态都是伪多态,因为函数的参数都没类型限制,严格意义来说就没有多态。多态和鸭子类型差不多。Python的鸭子类型开放性更好,只要对象里面实现了某个方法,看起来和它一样可以用就行了。
Python中鸭子类型:新定义一个类,在类里面同样实现这个方法,在方法里面写一些不同的代码,同样是调用这个函数,同样是传一个对象,可以做一些不同的事情。