一、了解历史很关键:
来自:(https://www.cnblogs.com/linhaifeng/articles/6428835.html)
1940年以前:面向机器
在那个苦逼的年代,编写程序只能写机器语言,也就是一堆0和1,虽然后来可以通过一些符号来代替一些0跟1,但也逃不了被称为“低级语言”了。
后来:面向过程
面向过程用我们小学语文老师的话来说就是写的流水账,但不管怎么样,程序员不用在关心机器本身的指令了,更多的经历可以放在解决问题的过程中。
再后来:结构化程序设计(应该就是函数编程了吧)
结构化程序设计:采用子程序(函数)、代码区块、for循环以及while循环等结构。面向过程可以说已经相当牛逼了,但,怎奈何我IT行业的发展是迅速的,迅速到美国都开始拿程序发射火箭了。阔不阔怕!
很不幸,因为一段代码的原因发射失败了。然后一群伟大的宅男就聚在一起搞了一搞,就搞出来了一套“自顶向下、逐步细化、模块化”结构化程序设计的指导思想。
再后来:面向对象
结构化程序在很大程度上打开了众宅男们的开发激情,从此便一发不可收拾。很快,结构化程序设计以及不能满足众宅男们的欲望。他们探索着、渴望着。就这样面向对象的设计思想开始蔓延
直到C++的出现面向对象的高潮是一波比一波高,后来的java、C#就是最好的体现。面向对象也是至今为止最贴近人类思维的设计思想。但这仅仅只是开始,远远没有结束......
现今:
感谢前辈们赏饭吃。
二、概念:
面向对象:
面向对象讲究的是一切事物皆对象,通过面向对象的方法,将现实世界的事物抽象成对象,现实世界的关系抽象成类、继承。而对象指的就是类的集合。面向对象中的每个对象都应该能够接受数据、处理数据并将数据传达给其他对象,也可以说每个对象都是一个小的程序。
三、python的面向对象:
python:即支持函数式编程,也支持面向对象的编程
java:只能用面向对象编程,虽然也能写函数但函数必须写到类里
类和函数(方法)结合应用就是面向对象
1、类的定义:
1 class bar() : # 类 2 def foo(self,arg): # 方法 3 print(self.name,self.age) 4 print(arg) 5 6 return 1
2、类的调用:
1 o = bar() # 创建中间人(也就是对象或者叫实例) 2 o.name="xiaohei"
3、类中的self:(封装)
定义类的时候必须有一个额外的第一个参数名称(self)
self也代表类的实例,而非类
self代指的是调用方法的对象(中间人),代表当前对象的内存地址
1 class Introdu(): 2 def Name(self): 3 print("My name is: %s "%self.name) 4 5 return 1 6 7 I = Introdu() # 实例化 8 print(I) 9 》》》<__main__.Introdu object at 0x000001C29102B278> #self的内存地址 10 11 I.name="xiaohei" #通过self传参 12 I.Name() #调用类
13 》》》My name is: xiaohei
14
15 In = Introdu() # 实例化
16 In.name="xiaobai"
17 In.Name()
18 》》》My name is: xiaobai
一般情况下都会将对象创建为初始状态,因此类里边会有一个特殊的方法叫做构建方法,在类实例化时会自动调用构建方法
1 class Introdu(): 2 def __init__(self): 3 print("-----test----") 4 5 def Name(self): 6 print("My name is: %s "%self.name) 7 8 return 1 9 10 I = Introdu() # 实例化 11 12 》》》-----test----
也可以通过构建方法定义参数:
1 class Introdu(): 2 def __init__(self,name,age): 3 self.n=name 4 self.a=age 5 6 def Name(self): 7 print("My name is %s and I'm %d years old"%(self.n,self.a)) 8 9 return 1 10 11 I = Introdu("Adair",18) # 实例化 12 I.Name() 13 14 》》》My name is Adair and I'm 18 years old
1 class Introdu(): 2 def __init__(self,name,age): 3 self.n=name 4 self.a=age 5 self.gander="m" 6 7 def Name(self): 8 print("My name is %s and I'm %d years old,Gender is %s"%(self.n,self.a,self.gander)) 9 10 return 1 11 12 I = Introdu("Adair",18) # 实例化 13 I.Name() 14 》》》My name is Adair and I'm 18 years old,Gender is m 15 In = Introdu("xiaohei",16) 16 In.Name() 17 》》》My name is xiaohei and I'm 16 years old,Gender is m
4、类的继承
1 class Father(): #父类(基类) 2 def Smoking(self): 3 print("F,smoking") 4 def Drinking(self): 5 print("F,drinking") 6 def PermedHair(self): 7 print("F,PermedHair") 8 9 class Son(Father): #子类(派生类),通过类名继承父类的属性 10 def basketball(self): 11 print("S,basketball") 12 def Football(self): 13 print("S,Football") 14 15 obj = Son() 16 obj.basketball() # basketball中的self代指的是中间人 obj 17 》》》 S,basketball 18 obj.Smoking() # Smoking中的self代指的也是中间人 obj ,self用于指调用方法的调用者 19 》》》 F,smoking 20 obj.PermedHair() 21 》》》 F,PermedHair
注:当执行类中方法时,会先在子类中加载,若之类中没有此方法。再到父类中加载
1 # 方法的重写 2 3 class Father(): #父类 4 def Smoking(self): 5 print("F,smoking") 6 def Drinking(self): 7 print("F,drinking") 8 def PermedHair(self): 9 print("F,PermedHair") 10 11 class Son(Father): #子类,通过类名加载父类的属性 12 def basketball(self): 13 print("S,basketball") 14 def Football(self): 15 print("S,Football") 16 def Smoking(self): 17 print("S,Smoking") 18 19 20 obj = Son() 21 obj.basketball() 22 》》》 S,basketball 23 obj.Smoking() 24 》》》 S,Smoking
1 #在子类中执行父类中的方法,两种方法任选其一 2 3 class Father(): #父类 4 def Smoking(self): 5 print("F,smoking") 6 def Drinking(self): 7 print("F,drinking") 8 def PermedHair(self): 9 print("F,PermedHair") 10 11 class Son(Father): #子类,通过类名加载父类的属性 12 def basketball(self): 13 print("S,basketball") 14 def Football(self): 15 print("S,Football") 16 def Smoking(self): 17 super(Son,self).Smoking() # 1、在子类中执行父类中的方法 super(子类名,self).要执行的方法名() 18 Father.Smoking(self) # 2、在子类中执行父类中的方法 19 print("S,Smoking") 20 21 22 obj = Son() 23 obj.Smoking() 24 》》》F,smoking 25 F,smoking 26 S,Smoking
多继承:
1 class laowang(): #父类 2 def Smoking(self): 3 print("laowang,smoking") 4 def Drinking(self): 5 print("laowang,drinking") 6 def PermedHair(self): 7 print("laowang,PermedHair") 8 def OverWall(self): 9 print("laowang.OverWall") 10 11 class Father(): #父类 12 def Smoking(self): 13 print("F,smoking") 14 def Drinking(self): 15 print("F,drinking") 16 def PermedHair(self): 17 print("F,PermedHair") 18 19 20 class Son(Father,laowang): #子类,通过类名加载父类的属性 21 def basketball(self): 22 print("S,basketball") 23 def Football(self): 24 print("S,Football") 25 def Smoking(self): 26 print("S,Smoking") 27 28 29 obj = Son() 30 obj.Drinking() 31 》》》 F,drinking 32 obj.OverWall() 33 》》》 laowang.OverWall
默认情况下加载方法的顺序是根据子类加载父类的顺序从左往右一条道走到黑的依次加载,
多继承之公共父类:
1 class base(): 2 def boss(self): 3 print("base.boss") 4 class laowang(base): #父类 5 def Smoking(self): 6 print("laowang,smoking") 7 def Drinking(self): 8 print("laowang,drinking") 9 def PermedHair(self): 10 print("laowang,PermedHair") 11 def OverWall(self): 12 print("laowang.OverWall") 13 14 class Father(): #父类 15 def Smoking(self): 16 print("F,smoking") 17 def Drinking(self): 18 print("F,drinking") 19 def PermedHair(self): 20 print("F,PermedHair") 21 22 23 class Son(Father,laowang): #子类,通过类名加载父类的属性 24 def basketball(self): 25 print("S,basketball") 26 def Football(self): 27 print("S,Football") 28 def Smoking(self): 29 print("S,Smoking") 30 31 32 obj = Son() 33 obj.boss() 34 》》》base.boss
加载方法的顺序是根据子类加载父类的顺序从左往右一条道走到黑的依次加载,公共父类最后加载,当所加载的父类中都没有该方法时才会加载公共父类中的方法
多继承之方法的嵌套:
1 class laowang(): #父类 2 def Smoking(self): 3 print("laowang,smoking") 4 def Drinking(self): 5 print("laowang,drinking") 6 def PermedHair(self): 7 print("laowang,PermedHair") 8 def OverWall(self): 9 self.Smoking() # self 是调用者(obj),所以当执行这句话的时候程序会回到Son类中根据默认情况从左到右的依次加载 10 print("laowang.OverWall") 11 12 class Father(): #父类 13 def Smoking(self): 14 print("F,smoking") 15 def Drinking(self): 16 print("F,drinking") 17 def PermedHair(self): 18 print("F,PermedHair") 19 20 21 class Son(Father,laowang): #子类,通过类名加载父类的属性 22 def basketball(self): 23 print("S,basketball") 24 def Football(self): 25 print("S,Football") 26 def Smoking(self): 27 print("S,Smoking") 28 29 30 obj = Son() 31 obj.OverWall() 32 》》》S,Smoking 33 laowang.OverWall
5、类的成员
包括:
字段: 方法:
-- 普通字段 -- 普通方法
-- 静态字段 -- 静态方法
-- 类方法
1 class List(): 2 3 NativePlace="汉" # 静态字段 属于类 4 5 def __init__(self,name,age): 6 self.name=name # 普通字段 属于对象 7 self.age=age 8 9 def Show(self): # 方法 属于类 10 print("%s--%s--%s"%(self.name,self.age,self.NativePlace)) 11 12 13 obj=List("Adair",18) # 调用普通字段 14 obj.Show() # 调用方法 15 print(List.NativePlace) # 调用静态字段1 16 print(obj.NativePlace) # 调用静态字段2
1 class Member(): 2 3 def name(self,n): # 普通方法 4 print("My name is %s"%n) 5 6 @staticmethod #声明静态方法 7 def age(a): # 静态方法 8 print("My age is %d"%a) 9 10 @classmethod #声明类方式 11 def gender(cls,gd): # 类方法 12 print(cls) # cls 返回的类名 <class '__main__.Member'> 13 print("My gender is %s"%gd) 14 15 16 obj = Member() #调用普通方法 17 obj.name("Adair") 18 》》》My name is Adair 19 20 Member.age(18) # 调用静态方法 21 》》》My age is 18 22 23 Member.gender("m") # 调用类方法 24 》》》My gender is m
6、类中方法的属性
1 class name(): 2 3 @property # 添加上这个属性,在调用时可以不带括号 (obj.show) 4 def show(self): 5 print("My name is Adair") 6 7 obj = name() 8 obj.show # 调用带@property属性函数时不需要带括号
7、成员修饰符:
公有成员:在任何地方都可以访问
私有成员:只有在类的内部才可以访问 (私有成员命名时需要在前边添加两个下滑线)
注:内部指的是类的内部,不包括继承类
1 class List(): 2 3 gender="m" # 公有静态字段 4 __gender="m" # 私有静态字段,只能在内部调用 5 6 def __init__(self,name): # 构建方法 7 self.name = name # 公有字段 8 self.__name = name # 私有字段,只能在内部调用 9 10 def show(self): 11 print(self.__gender) #内部调用私有静态字段 12 print(self.__name) # 内有调用私有字段 13 14 obj = List("Adair") 15 print(obj.name) # 调用公有字段 16 print(List.gender) # 调用公有静态字段 17 obj.show() # 外部间接调用私有成员
8、类中的特殊成员:
1 class special(): 2 3 def __init__(self,name,age): # 构造方法,通过类创建对象时,自动触发执行 4 # print("init") 5 self.name = name 6 self.age = age 7 8 def __call__(self, *args, **kwargs): # 对象后面加括号,触发执行 9 return "call" 10 11 def __str__(self): # 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值 12 return "str" 13 14 def __add__(self, other): 15 ''' 16 self = obj 17 other = obj2 18 ''' 19 # return special(self.name, other.age) 20 return self.age + other.age 21 22 def __del__(self): # 析构方法,当对象被销毁时自动执行__del__方法 23 return 1 24 25 def __getitem__(self, item): 26 return item+10 27 28 def __setitem__(self, key, value): 29 print("asd") 30 31 def __delitem__(self, key): 32 print("delete") 33 34 35 obj = special("Adair",18) # 自动执行__init__()方法 36 obj2 = special("xiaohei",16) 37 print(obj()) # 或者 special()() , 自动执行 __call__()方法 38 print(obj) # 自动执行__str__()方法 39 print(obj + obj2) # 当两个对象相加,默认会自动执行第一个对象(obj)中的__add__方法,并把第二个对象当作参数传入到第一个对象的__add__方法中 40 print(obj.__dict__) # 将对象中封装的所有内容通过字典的形式展示出来 41 print(obj[2]) # 索引的方式执行对象时,默认会调用__getitem__方法 42 obj[99] = "123" # 使用这种方法调用对象时。默认会执行__setitem__方法 43 del obj[123] # 使用这种方法调用对象时。默认会执行__delitem__方法