python——面向对象(类)
1、python面向对象编程
1.1概述
2、面向对象:所谓面向对象,其实就是说,站在上帝的视角下,世界万物一切皆对象。把拥有共同属性的归为一类,这就是class的由来。
3、类的定义:
(1)类的关键字:class。
(2)类中有属性、方法(就是之前学习过的函数),类里面的属性(类有三种属性:字段、方法、特性)及方法,调用的前提是首先要对类进行实例化处理。类的实例化处理必须调用__init__初始化方法。
(3)类的名称首字母必须是大写的。
注意事项:在类中调用类的数据属性和方法时前面要加self。
4、函数与方法的区别
(1)定义位置
A、函数:Python的函数是直接写在Python模块中的,即在.py文件中直接定义。
B、方法:只能定义在class类中。
(2)定义方式
A、函数:函数定义的方式 def 函数名(),括号里面写形参,也可以省略不写形参。
B、方法:方法定义的方式, 首先方法是定义在类中的,其他大体和函数定义差不多,这里需要注意的一点就是方法必须带一个默认参数self,self指的是类自己。
(3)调用方式
A、函数:直接使用函数名(参数1,参数2,…)调用。
B、方法:方法:方法是通过 对象.方法 的方式调用的(这里是指对象方法)
1.2方法(method)
python的类有类方法、普通方法、特性方法、静态方法。python的类方法中,默认使用的第一个参数是cls;而普通方法和特性方法,默认使用self作为第一个参数;静态方法是不需要默认参数的。
(1)类方法:其默认使用的参数是cls,需要在@classmethod的装饰下定义的方法。
(2)普通方法:我们平时在类中自己定义的方法,如show(),info()。
(3)特性方法,只具备只读属性,不能写(这个方法里面不能有形式参数),在装饰器(@property)下定义的方法。
(4)静态方法:静态方法可以理解为全局变量,但是它不等价于全局变量,静态方法是可以使用类名来直接进行调用。需要在@staticmethod的装饰下定义的方法。
静态方法的特点:
A、可以使用类名来直接进行调用;
B、静态方法的括号中是不需要默认参数self的。
C、静态方法不能够调用实例属性。
D、静态方法可以完全替代数据属性。
1.3实例
1.3.1定义类
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
def name(self): #在类中定义的函数叫做方法,self是类本身自己,该方法为实例方法。
print("我是一个方法")
obj=Introduction()
obj.name()
1.3.2数据属性
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
city = "西安" # 定义一个数据数据属性,只能通过类名或者类的对象来调用。
def name(self): #在类中定义的函数叫做方法,self是类本身自己,该方法为实例方法。
print("my city is {0}".format(self.city))
#数据属性的调用:对于数据属性而言,使用类名及类的对象调用是一样的,即他们的内存地址是一致的,不用对其进行实例化即可调用。
obj=Introduction() #类对象
print(obj.city)
print(Introduction.city)
1.3.3初始化
__init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self,myName,age):
#实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName=myName
self.age=age
print("我执行的是初始化")
1.3.4构析方法
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
1.3.5实例方法的定义与输出
调用方法的执行顺序,先执行构造方法————再执行真正调用的方法,真正调用的方法就是我们自己定义的方法————最后执行析构方法。其中构造方法和析构方法都是内部方法。
1.3.5.1定义的字段类似形式参数
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
city = "西安" # 定义一个数据数据属性,只能通过类名或者类的对象来调用。
#__init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self,myName,age):
#实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName=myName
self.age=age
print("我执行的是初始化")
def name(self): #在类中定义的函数叫做方法,self是类本身自己,该方法为实例方法。
print("my city is {0},my name is {1},my age is {2}".format(self.city,self.myName,self.age))
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中实例方法调用的方式:
#第一种:对象.方法,也就是类对象调用类的方法。
obj=Introduction(myName="qy",age=23) #name="qy",age=23是对实例属性赋值的过程,obj第一个对象。
obj.name() #调用方法,调用的是name的方法。
# obj2=Introduction(myName="zl",age=24) #name="qy",age=23是对实例属性赋值的过程,obi2第二个对象。
# obj2.name() #调用方法,调用的是name的方法。
#第二种:类.方法(self 参数值),此方式需要手动给 self 参数传值,也就是类名直接调用类的方法。
obj1=Introduction(myName="qy",age=23)
Introduction.name(obj1)
1.3.5.2定义的字段类似动态参数
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
def variable(self,*args,**kwargs): #在类中定义的函数叫做方法,self是类本身自己,该方法为实例方法。
print(kwargs) #输出的动态变量,需要根据下面赋值的数据类型选择。key=value选择**kwargs。
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中实例方法调用的方式:
#第一种:对象.方法,也就是类对象调用类的方法。
obj=Introduction(myName="qy",age=23) #name="qy",age=23是对实例属性赋值的过程。
obj.variable(job="测试",city="西安") #调用方法,调用的是variable的方法。
#第二种:类.方法(self 参数值),此方式需要手动给 self 参数传值,也就是类名直接调用类的方法。
obj1=Introduction(myName="qy",age=23)
Introduction.variable(obj1,job="测试",city="西安")
1.3.5.3定义的字段类似默认参数
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
# 这里的sex可以简单的理解为一个形式参数,也可以给它赋值让它作为形式参数,类似于局部变量,只属于Information方法,也只能被Information调用。
def information(self,sex="女"):
print("my name is{0},my sex is {1}".format(self.myName,sex))
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中实例方法调用的方式:
#第一种:对象.方法,也就是类对象调用类的方法。
obj=Introduction(myName="qy",age=23) #name="qy",age=23是对实例属性赋值的过程。
obj.information() #调用方法,调用的是information的方法,不给sex赋值时,默认值是女。
#第二种:类.方法(self 参数值),此方式需要手动给 self 参数传值,也就是类名直接调用类的方法。
obj1=Introduction(myName="qy",age=23)
Introduction.information(obj1,sex="男") #给sex赋值时,sex的值就是你赋予的值。
1.3.6类方法的定义与输出
类方法:其默认使用的参数是cls,需要在@classmethod的装饰下定义的方法。
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
#__init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self,myName,age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName=myName
self.age=age
print("我执行的是初始化")
#定义一个类方法,类方法的默认参数为cls。
@classmethod
def nameInfo(cls):
return "my city is xian"
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中类方法的调用方式:
#第一种:类名直接调用类的方法,类方法会自动将self 参数值自动绑定,无需显式传参,这样调用他是不执行__init__构造方法和__del__构析伏方法的。
print(Introduction.nameInfo())
#第二种:类对象调用类的方法
obj3=Introduction(myName="qy",age=23)
print(obj3.nameInfo())
1.3.7特性方法的定义与输出
特性方法,只具备只读属性,不能写(这个方法里面不能有形式参数),在装饰器(@property)下定义的方法。
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
@property # 装饰器,特性方法区别于普通方法最大的点。特性方法只具有只读属性。
def info(self):
print("my name is {0},my age is {1}".format(self.myName, self.age))
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中特性方法的调用方式:对象.方法,也就是类对象调用类的方法,调用时特性方法不能带括号。
obj=Introduction(myName="qy",age=23) #name="qy",age=23是对实例属性赋值的过程。
obj.info
1.3.8静态方法的定义与调用
静态方法:静态方法可以理解为全局变量,但是它不等价于全局变量,静态方法是可以使用类名来直接进行调用。需要在@staticmethod的装饰下定义的方法。
静态方法的特点:
A、可以使用类名来直接进行调用;
B、静态方法的括号中是不需要默认参数self的。
C、静态方法不能够调用实例属性。
D、静态方法可以完全替代数据属性。
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
#定义一个静态方法
@staticmethod
def address():
return "陕西汉中"
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中静态方法的调用方式:
# 第一种:对象.方法,也就是类对象调用类的方法,调用时特性方法不能带括号。
obj=Introduction(myName="qy",age=23) #name="qy",age=23是对实例属性赋值的过程。
print(obj.address())
#第二种:类.方法,调用静态方法,与类方法一样无需显式传参,调用静态方法时是不执行__init__构造方法和__del__构析伏方法的。
print(Introduction.address())
1.3.9综合实例
#类:
#实例方法,默认参数为self,即最少也要包含一个 self 参数。类方法必须使用@classmethod修饰符进行修饰
#类方法:默认参数为cls,它最少也要包含一个cls参数。
class Introduction(object): #object是所有类的父类,也可以说是类的祖先,Introduction是定义的一个类。
city="西安" #定义一个数据数据属性,只能通过类名或者类的对象来调用。
#__init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self,myName,age):
#实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName=myName
self.age=age
print("我执行的是初始化")
#定义一个类方法,类方法的默认参数为cls。
@classmethod
def nameInfo(cls):
return "my job is ceShi"
def name(self): #在类中定义的函数叫做方法,self是类本身自己。
print("my name is {0},my gae is {1},my city is {2},my address is {3},work:{4}".format(self.myName,self.age,self.city,self.address(),self.nameInfo()))
#self.city:数据属性作为变量的调用方式,self.address():静态方法也可以作为变量进行调用,self.nameInfo():类方法也可以作为变量进行调用,当静态方法等作为变量调用时,输出应该为print()的形式。
#这里的sex可以简单的理解为一个形式参数,也可以给它赋值让它作为形式参数,类似于局部变量,只属于Information方法,也只能被Information调用。
def information(self,sex="女"):
print("my name is{0},my sex is {1}".format(self.myName,sex))
def variable(self,*args,**kwargs):
print(*kwargs) #输出的动态变量,需要根据下面赋值的数据类型选择。key=value选择**kwargs。
@property #装饰器,特性方法区别于普通方法最大的点。特性方法只具有只读属性。
def info(self):
print("my name is {0},my city is {1}".format(self.myName,self.city))
#定义一个静态方法,静态方法是在@staticmethod下定义的方法,不实例化类的情况下可以直接访问该方法。
@staticmethod
def address():
return "陕西汉中"
# __del__:析构方法,其价值是清理,可以简单的理解为后置处理,如要读一个文件时关闭文件的操作。
def __del__(self):
print("我执行的是清理")
#调用方法的执行顺序,先执行构造方法————再执行真正调用的方法,真正调用的方法就是我们自己定义的方法————最后执行析构方法。其中构造方法和析构方法都是内部方法。
# obj可以理解为类的对象,也可以将他理解为一个变量,所以obj可以简单的理解为给类定义的对象。
#类中实例方法调用的方式:
# 第一种:对象.方法,也就是类对象调用类的方法。
obj=Introduction(myName="qy",age=23) #name="qy",age=23是对实例属性赋值的过程,obj第一个对象。
obj.name() #调用方法,调用的是name的方法。
print(obj.name())
obj2=Introduction(myName="zl",age=24) #name="qy",age=23是对实例属性赋值的过程,obi2第二个对象。
obj2.name() #调用方法,调用的是name的方法。
#第二种:类.方法(self 参数值),此方式需要手动给 self 参数传值,也就是类名直接调用类的方法。
obj1=Introduction(myName="qy",age=23)
Introduction.name(obj1)
obj.information(sex="男") #调用实例方法,调用的是information的方法,里面的参数为默认参数。
obj.variable(job="测试",location="西安") #调用实例方法,调用的是variable方法,里面的参数为动态参数。
#特性方法的调用方式:
obj.info #调用特性方法,调用的是info方法。
#类中类方法的调用方式:
#第一种:类名直接调用类的方法,类方法会自动将self 参数值自动绑定,无需显示传参,这样调用他是不执行__init__构造方法和__del__构析伏方法的。
print(Introduction.nameInfo())
#第二种:类对象调用类的方法
obj3=Introduction(myName="qy",age=23)
print(obj3.nameInfo())
#静态方法的调用方式
print(Introduction.address()) #调用静态方法,既可以使用类名,也可以使用类对象,调用静态方法时是不执行__init__构造方法和__del__构析伏方法的。
#数据属性的调用:对于数据属性而言,使用类对象和类名调用是一样的,即他们的内存地址是一致的,不用对其进行实例化即可调用。
print(obj.city)
print(Introduction.city)
2、继承
2.1概述
1、java和python的继承的区别:
(1)python是一个类可以继承N个类。
(2)java只能继承一个类。
2、相关概念:
(1)基类(父类):被继承的类
(2)派生类(子类):继承其他的类。
3、子类继承父类,继承了什么?
(1)实例属性
#子类继承父类的实例属性,即Person继承Animal的实例属性myName,age。
super().__init__(myName,age) #第一种方法
Animal.__init__(self,myName,age) #第二种方法
(2)数据属性
(3)方法
4、继承的原则
(1)从上到下原则:当父类的方法没有满足子类的需求的时候,子类就会重写父类的方法叫做方法重写,我们调用这个方法时,继承的顺序从下到上,线性查找,找到一个满足的方法,后面继承的类即使有这个方法,也不会调用,即子类优先调用自己的方法。
(2)子类继承的父类必须是同一个阶层,即平等的关系。如果阶层不平等,会出现MRO错误。
(3)从左到右原则:线性查找的顺序规则,也就是说调用show()方法,如果找到一个满足的方法,后面继承的类即使有这个方法,也不会调用。当子类没有重写父类的方法时,查找的顺序为:父类从左到右查找。当子类重写了父类的方法时,子类优先调用自己的方法。
综上所述,在python中,基于MRO的解析顺序规则,就会从左到右开始查找基类,如果找到第一个匹配的属性类,就会停止查找,如果没有,那就继续查找,直到找到符合要求的位置。MRO其实就是通过一个C3线性化算法来实现的,他的核心思想为:
A、子类会优于父类检查;
B、多个父类会根据他们在列表中的顺序被依次检查;
#查看子类查找的顺序:是根据MRO的解析顺序规则进行查找的。Son是子类的类名,输出的结果是一个列表,根据列表从左到右就是Son的查找顺序。
print(Son.mro())
2.2实例
2.2.1继承实例
2.2.1.1单类继承
单类继承:子类只继承一个父类。
class Animal(object):
address="地球村"
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
def information(self):
# print("name is {0},age is {1}".format(self.myName,self.age))
return "name is {0},age is {1}".format(self.myName,self.age) #子类继承父类的方法时,并将方法作为变量时输出时,输出的形式。
class Person(Animal):
def __init__(self, myName,age,sex):
#子类继承父类的实例属性,即Person继承Animal的实例属性myName,age。
super().__init__(myName,age) #第一种方法
Animal.__init__(self,myName,age) #第二种方法
self.sex=sex
#子类继承父类的数据属性和方法,self.address继承数据属性,self.introduction()继承方法,子类继承父类的方法时,要输出里面的内容,输出要用返回值的形式。
def info(self):
print("I am from {0},information:{1}".format(self.address,self.information()))
obj=Person(myName="qy",age=23,sex="女")
obj.info()
2.1.2.1多类继承
多类继承:子类继承多个父类。
从左到右原则:线性查找的顺序规则,也就是说调用show()方法,如果找到一个满足的方法,后面继承的类即使有这个方法,也不会调用。当子类没有重写父类的方法时,查找的顺序为:父类从左到右查找。当子类重写了父类的方法时,子类优先调用自己的方法。
#多类继承:继承的原则是,父类从左到右继承,执行该原则的前提是子类没有重写父类的方法。
class Father(object):
def __init__(self,salary):
self.salary=salary
def show(self):
print("男人赚钱")
class Mother(object):
def __init__(self,hobby):
self.hobby=hobby
def show(self,hobby):
print("女人花钱")
class Son(Father,Mother):
def __init__(self,salary,hobby):
Father.__init__(self,salary)
Mother.__init__(self,Mother)
obj=Son(salary=100,hobby="读书")
obj.show()
2.2.2方法重写
当父类的方法没有满足子类的需求的时候,子类就会重写父类的方法叫做方法重写,我们调用这个方法时,继承的顺序从下到上,即子类优先调用自己的方法。方法重写在单类继承和多类继承中都会体现。如下以:单类继承为例:
class Animal(object):
address="地球村"
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
def information(self):
# print("name is {0},age is {1}".format(self.myName,self.age))
return "name is {0},age is {1}".format(self.myName,self.age) #子类继承父类的方法时,并将方法作为变量输出时,输出的形式。
class Person(Animal):
def __init__(self, myName,age,sex):
#子类继承父类的实例属性,即Person继承Animal的实例属性myName,age。
super().__init__(myName,age) #第一种方法
Animal.__init__(self,myName,age) #第二种方法
self.sex=sex
#子类继承父类的数据属性和方法,self.address继承数据属性,self.introduction()继承方法,子类继承父类的方法时,要输出里面的内容,输出要用返回值的形式。
def info(self):
print("I am from {0},information:{1}".format(self.address,self.information()))
#方法重写:当父类的方法没有满足子类的需求的时候,子类就会重写父类的方法叫做方法重写,我们调用这个方法时,继承的顺序从下到上,即子类优先调用自己的方法。
def information(self):
print("我不喜欢喝奶茶!")
obj=Person(myName="qy",age=23,sex="女")
obj.information()
2.2.3错误继承
子类继承的父类必须是同一个阶层,即平等的关系。如果阶层不平等,会出现(MRO)错误。
class Animal(object):
address="地球村"
# __init__:初始化,又叫构造方法,针对类初始化的时候必须要对构造方法里面的实例属性赋值,类进行实例化的过程中必须调用__init__方法,可以简单的理解为前置动作,如要读一个文件时打开文件的操作。
def __init__(self, myName, age):
# 实例属性的过程,name和age是实例属性,是属于整个类的,类似于全局变量,即整个类都可以进行调用的,调用的方法是self.实例属性:
self.myName = myName
self.age = age
print("我执行的是初始化")
def information(self):
# print("name is {0},age is {1}".format(self.myName,self.age))
return "name is {0},age is {1}".format(self.myName,self.age) #子类继承父类的方法时,并将方法作为变量输出时,输出的形式。
class Person(Animal):
def __init__(self, myName,age,sex):
#子类继承父类的实例属性,即Person继承Animal的实例属性myName,age。
super().__init__(myName,age) #第一种方法
Animal.__init__(self,myName,age) #第二种方法
self.sex=sex
#子类继承父类的数据属性和方法,self.address继承数据属性,self.introduction()继承方法,子类继承父类的方法时,要输出里面的内容,输出要用返回值的形式。
def info(self):
print("I am from {0},information:{1}".format(self.address,self.information()))
#错误的继承方式:子类继承的父类必须是同一个阶层,就会出现#错误的继承方式:order (MRO) for bases Animal, Person。
class Model(Animal,Person):
def __init__(self, myName, age, sex,rjm):
Animal.__init__(myName, age) # 第一种方法
Person.__init__(self, sex) # 第二种方法
self.rjm=rjm
obj=Person(myName="qy",age=23,sex="女")
obj.information()