1、面向对象的概念
拥有共同属性的一类进行归类的过程叫做面向对象。
2、注意事项
class定义类的时候,类名的首字母必须大写
3、面向对象案例
1 class Person(object): 2 def __init__(self,name,age): #name,age可以理解为类的属性;init为初始化;类里定义的函数称为构造方法/构造函数 3 self.name=name #实例属性 4 self.age=age 5 print("start") 6 def __del__(self): #清理操作 7 print("end") 8 def show(self): #self为类本身,不可省略 9 print("name:{0},age:{1}".format(self.name,self.age)) 10 obj=Person(name="wuya",age=18) #要调用类里边的变量、方法函数等,首先需要对类进行实例化;obj是类Person()实例化后的对象,类实例化的过程也是类初始化的过程。类的实例化过程也是针对构造方法初始化的过程(等于调用了__init__的方法) 11 obj.show() 12 #Person(name="wuya",age=18).show() #用类名调用方法
以上代码运行的结果为:
4、类中方法的执行顺序:初始化方法->具体的方法->清理的方法
5、面向对象的特性
1)封装
a.实例属性
b.数据属性(类中的变量)
2)继承
3)多态
6、方法:
a.普通方法:属于对象,也属于类,只能读写;
b.特性方法:属于对象,只具备读属性,方法不能有形式参数;
c.静态方法:属于类,只能用类名来调用,一般把数据属性使用静态方法来处理
7、封装入门实例
1 class Animal(object): 2 def __init__(self,age): 3 self.age=age 4 def getAge(self): 5 return self.age 6 def setAge(self,age): 7 if age>10 and age<100: 8 self.age=age #允许修改年龄 9 else: 10 print("年龄错误") 11 objAnimal=Animal(age=25) #类的实例化 12 print(objAnimal.getAge()) #输出获取年龄的方法的调用结果 13 objAnimal.setAge(age=11) #调用修改年龄的方法 14 print(objAnimal.getAge()) #输出获取年龄的方法的调用结果
8、封装的进阶实例
1 class Animal(object): 2 address="地球" #数据属性 3 def __init__(self,age): 4 self.age=age #实例属性 5 # @staticmethod 6 def address(self): #静态方法,数据属性使用静态方法来处理 7 return "地球" 8 def show(self,name="❀"): #普通方法,可读写 9 print("it come from {0},and it's age is {1},and it's name is {2}".format(self.address(),self.age,name)) 10 def func(self,**kwargs): 11 print(kwargs) 12 @property 13 def info(self): #特性方法,只读(只有输出) 14 print("hello world") 15 @property 16 def getAge(self): #特性方法,只读(只有返回) 17 return self.age 18 objAnimal=Animal(age=30) #类的实例化 19 objAnimal.show() #调用普通方法 20 #objAnimal.show(name="monkey") 21 # Animal().show(name="monkey") 22 # Animal(age=10).address() 23 objAnimal.func(name="cch",age=18,city="西安") 24 objAnimal.info #特性方法调用 25 print(Animal.address("")) 26 print(objAnimal.age)
9、继承
1)概念
父类(基类):被继承的类
子类(派生类):继承其他的类
2)Java和Python继承的区别
Java是单继承的,Python是多继承的
3)子类继承父类的什么:
a、变量(数据属性)
b、实例属性
c、方法
3)方法重写
当父类的方法没有办法满足子类的需求的时候,子类就会重写父类的方法,那么子类实例化后的对象调用该方法,优先考虑的是子类的方法。
1 class Father(object): 2 address="西安" 3 def __init__(self,name,age): 4 self.name=name 5 self.age=age 6 def info(self): 7 print("this is a father's method") 8 class Son(Father): 9 def __init__(self,name,age,score): 10 Father.__init__(self,name,age) #子类继承了父类的实例属性 11 self.score=score 12 def show(self): 13 print("name is {0},and age is {1},and score is {1}".format(self.name,self.age,self.score)) 14 def info(self): #父类的方法重写 15 print("this is a son's method") 16 son=Son(name="wuya",age=18,score=99) 17 son.show() 18 print(son.address) #子类继承了父类的变量(数据属性) 19 son.info() #不用print,info()中有print,函数与返回值时,输出函数为空。子类重写父类的方法,那么子类实例化后的对象调用该方法,优先考虑的是子类的方法。
以上代码运行的结果为:
10、继承顺序
1)从上到下(前提条件):
a.单个继承
b.子类重写了父类的方法
2)从左到右(前提条件):子类继承多个类(子类可以继承多个父类,但父类之间必须是同级关系。)
3)所以在Python中,基于MRO的解析顺序规则,就会从左到右开始查找基类,如果找到第⼀个匹配的属性类,就会停⽌查找,如果没有,那就继续查找,直到查找到符合要
求的为止。MRO其实就是通过⼀个C3线性化算法来实现的,它的核心思想为:
子类会优于父类检查
多个父类会根据他们在列表中的顺序被依次检查
如果对下一个类存在两个合法的选择,只能选择第一个(线性查找)
11、继承顺序示例
1 class Father(object): 2 def __init__(self,name,age): 3 self.name=name 4 self.age=age 5 def funM(self): 6 print("father") 7 8 class Mother(object): 9 def funM(self): 10 print("mother") 11 12 class Son(Father,Mother): #子类Son继承了两个父类 13 def __init__(self,name,age,score): 14 Father.__init__(self,name,age) #子类Son继承了父类Father和Mother的实例属性 15 self.score=score 16 17 son=Son(name="ccj",age=18,score=100) 18 son.funM() 19 print(Son.mro()) #使用类名调用mro,查看类的执行顺序
以上代码的执行结果为:
12、子类继承多个非同级的父类错误示例
1 class Person(object): 2 pass 3 4 class Father(Person): 5 def __init__(self): 6 pass 7 def funM(self): 8 print("father") 9 class Mother(object): 10 def funM(self): 11 print("mother") 12 13 class Son(Person,Father): #子类继承的多个父类不是同一级,代码会报错,z子类可以继承多个父类,但父类之间必须是同级关系。 14 def __init__(self,score): 15 Father.__init__(self) 16 self.score=score 17 son=Son(score=90) 18 son.funM() 19 print(Son.mro())
以上代码的运行结果为;
13、继承方法调用错误示例
1 class Person(object): 2 pass 3 4 class Father(Person): 5 def __init__(self): 6 pass 7 8 class Mother(Person): 9 def funM(self): 10 print("mother") 11 12 class Son(Father): #子类继承的父类中没有funM方法,代码会报错 13 def __init__(self,score): 14 Father.__init__(self) 15 self.score=score 16 17 son=Son(score=99) 18 son.funM()
以上代码的运行结果为:
14、继承方法调用错误示例纠正
1 class Person(object): 2 def funM(self): 3 print("person") 4 5 class Father(Person): 6 def __init__(self): 7 pass 8 9 class Mother(Person): 10 def funM(self): 11 print("mother") 12 13 class Son(Father): #子类继承法的父类是Father 14 def __init__(self,score): 15 Father.__init__(self) 16 self.score=score 17 18 son=Son(score=99) 19 son.funM() #子类调用方法,先从子类中查找,再从继承的父类查找,若未找到,再从父类的父类中查找。 20 print(Son.mro())
以上方法的运行结果为:
15、继承历史问题
python2是深度优先,python3是广度优先
1 class A: 2 def show(self): 3 print('A') 4 5 class B(A): 6 pass 7 8 class C(A): 9 def show(self): 10 print('C') 11 12 class D(B,C): 13 pass 14 15 if __name__ == '__main__': 16 obj=D() 17 obj.show() #python2执行的结果是A,pyhton3中的运行结果为C
16、多态
多太的优势具体可以总结为如下几点,具体为:
增加了持续的灵活性
增加了持续的额外扩展功能
1 class Animal(object): 2 def talk(self): 3 print("动物会叫") 4 5 class Dog(object): 6 def talk(self): 7 print("狗也会叫") 8 9 class Cat(object): 10 def talk(self): 11 print("猫也会叫") 12 13 def func(animal): 14 animal.talk() 15 if __name__ == '__main__': 16 dog=Dog() 17 func(animal=dog)
以上代码的运行结果为: