python面向对象--类/函数/继承
面向对象与面向过程
python是一门面向对象的编程语言,面向对象是一种编程思想,与之相对应的是面向过程。
1、面向过程
面向过程其实就是把过程当做设计核心,根据问题的发展顺序,依次解决问题,尽可能的把过程中涉及到的问题完善解决。他有他的优点,当拿到一个问题时,可以方便的按执行的步骤写代码,但是当逻辑关系变得复杂时,有一个地方出现差错就会导致整个程序无从下手。面向对象的编程语言还是很多的,例如C++、Java等等。
优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。
缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
2、面向对象
面向对象程序设计把计算机程序的执行看做一组对象的集合,每个对象之间进行消息的传送处理。有一个显著的优点就是,对某个对象进行修改,整个程序不会受到影响,自定义数据类型就是面向对象中的类的概念,而我们需要把他们的接口处理好就可以。
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。
类与对象
1、类:用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。即类是一个种类,一个模型。
2、对象(实例):类的实例。即根据模型制造出来的具体某个东西
3、实例化:从类到对象的过程。即从模型到成品东西的过程。
4、方法:类里面的函数
5、属性:类里面的变量就为类的属性。类有两种属性:静态属性和动态属性
6、类的定义和使用实际操作:
self:代表的本类对象。在类中,代表本类对象;在类外,需要用具体的实例名代替self。My.say(m) 等同于m.say()
cls:在类中,代表本类;在类外,需要用具体的类名代替cls。
类变量:就在直接在类下面定义的变量,没有加self的,每个实例都可以用
class Car: #定义类 wheel =4 #类变量,公共的,调用的时候没有时,从公共变量中找。防止每个实例都定义的时候浪费内存 def __init__(self,color,brand): #self.wheel=wheel self.color = color #实例变量 self.brand = brand def help(self): #类中的方法 print('汽车有%s个轮子'%self.wheel) print('汽车的颜色是%s'%self.color) print('='*10) my = Car('赤橙黄绿青蓝紫','我的') #类实例化 my.help()
类的函数
1、构造函数:类在实例化的时候会自动执行的一个函数
- 定义格式:
class 类名: def __init__(self,参数-若有):
- 调用:
#类外调用如下: 对象名=类名(参数-若有) # 1、创建实例对象并自动调用构造函数。 类名.__init__(对象名,参数-若有) # 2、已创建对象实例的前提下,执行构造函数。 对象名.__init__(参数-若有) # 3、实例.方法查找顺序:实例方法→类方法
2、析构函数:实例在销毁的时候自动执行的函数。一般关闭数据库连接、关闭文件等操作可以写在析构函数。
- 定义格式:
class 类名: def __del__(self):
- 调用:
# 类外调用如下 : # 1、无显式销毁实例时,则当程序运行结束后,自动销毁实例,自动调用析构函数 del 对象名 # 2、显式销毁实例后,则立即自动调用析构函数 类名.__del__(对象名) # 3、直接调用析构函数。并没有销毁实例。
3、类方法:@classmethod标识
- 不需要实例化就可以调用
- 它可以使用类变量
- 调用其他的类方法。
- 它不可以使用实例方法、实例变量
- 如果类里面的这个方法,它并没有使用到其他的实例变量、或者其他实例方法,那么就给他定义成类方法
定义格式:
class 类名: @classmethod def 方法名(cls,参数-若有):
调用:
#类内、类外调用如下: 类名.类方法(参数-若有) #类外调用如下: 对象名.类方法(参数-若有) # 实例.方法查找顺序:实例方法→类方法 #类内调用如下: class 类名: @classmethod def 方法名(cls,参数-若有): cls.类方法(参数-若有) class 类名: def 方法名(self,参数-若有): self.类方法(参数-若有) # 方法名指所有能传self的方法。 # self.方法查找顺序:实例方法→类方法
class Car: wheel = 4 #类变量 def __init__(self,color,p): self.color = color #实例变量 self.p = p def help(self): print('汽车有%s个轮子'%self.wheel) print('汽车的颜色是%s'%self.color) print('牌子%s'%self.p) print('='*10) #self.haha() self.check_wheel() @classmethod #类方法 def check_wheel(cls): print('cls的内存地址',id(cls)) print(cls.wheel) Car.check_wheel()
4、静态方法:@staticmethod 标识
- 不需要实例化就可以调用的
- 它就是一个定义在类里面的普通函数,不能使用实例变量、实例方法、不能使用类变量、类方法。
- 可以用静态方法调用另一个静态方法,如果改用类方法调用静态方法,可以让cls代替类,让代码看起来精简一些。也防止类名修改了,不用在类定义中修改原来的类名。
- 定义格式:
class 类名: @staticmethod def 方法名(参数-若有):
- 调用:
#类外调用如下: 对象名.静态方法 # 注意末尾没有括号 #类内调用如下: class 类名: @classmethod def 方法名(cls,参数-若有): cls.静态方法(参数-若有) class 类名: def 方法名(self,参数-若有): self.静态方法(参数-若有) # 方法名指所有能传self的方法。
class Car: wheel = 4 #类变量 def __init__(self,color,p): self.color = color #实例变量 self.p = p @staticmethod #静态方法,谁都可以调用 def help2(): print('这个类的作用是造汽车,它里面有xxx方法') Car.help2()
5、属性方法:@property 标识
适用于需要获取方法返回值,而且没有入参时使用。
看起来像变量的一个函数。
1、实例方法
2、调用不能有入参
3、用它的时候,直接m.func,把它当做一个变量用就ok了,不需要加括号调用
4、它是获取函数的返回值
- 定义格式:
class 类名: @property def 方法名(self,参数-若有):
- 调用:
#类外调用如下: 对象名.属性方法 # 注意末尾没有括号 #类内调用如下: class 类名: def 方法名(self,参数-若有): print(self.属性方法) # 方法名指所有能传self的方法。
class Car: wheel = 4 #类变量 def __init__(self,color,p): self.color = color #实例变量 self.p = p @staticmethod #静态方法,谁都可以调用 def help2(): print('这个类的作用是造汽车,它里面有xxx方法') @property #属性方法 def yesterday(self): #昨天 import datetime res = datetime.date.today() + datetime.timedelta(-1) return str(res) Car.help2() my = Car('赤橙黄绿青蓝紫','我的') print(my.yesterday)#注意没有括号
6、实例方法:正常定义的类里的self函数都是实例方法,必须得实例化之后才可以使用。
- 定义格式:
class 类名: def 方法名(self,参数-若有):
- 调用:
#类外调用如下: 对象名.实例方法(参数-若有) #类内调用如下: class 类名: def 方法名(self,参数-若有): self.实例方法(参数-若有) # 方法名指所有能传self的方法。
class Car: wheel = 4 #类变量 def __init__(self,color,p): self.color = color #实例变量 self.p = p def help(self): print('汽车有%s个轮子'%self.wheel) print('汽车的颜色是%s'%self.color) print('牌子%s'%self.p) print('='*10) self.haha() self.check_wheel() @classmethod def check_wheel(cls): print('cls的内存地址',id(cls)) print(cls.wheel) cls.haha() @classmethod def haha(cls): print('哈哈哈') cls.help2() @staticmethod def help2(): print('这个类的作用是造汽车,它里面有xxx方法')
7、私有方法:私有方法只能在类里面调用 ,不能在类外调用,子类也不可以调用。比如说连接数据库client。私有变量也一样,只能在类中使用
- 定义格式:
class 类名: #第一种 @classmethod def __方法名(cls,参数-若有):4 class 类名: #第二种 def __方法名(self,参数-若有):
- 调用:
#类内调用如下: class 类名: #第一种 @classmethod def 方法名(cls,参数-若有): cls.私有方法(参数-若有) class 类名: #第二种 def 方法名(self,参数-若有): self.私有方法(参数-若有) # 方法名指所有能传self的方法。
class My: def test(self): self.__password=123456#私有变量,在类中可以用,出了类就不能使用 def say(self): self.__password=7890 def update(self): self.__set_password()
m= My()
m.test()
m.say()
m.update() #类外面不能使用,则报错
变量
1、实例变量
什么时候用到实例变量?如一个变量值在本类的多个函数中都要用到的,可以声明为实例变量。如连接数据库使用频繁,为了避免每次处理数据都要连接一次,可以将连接数据库放在构造函数中。当然这个也可以放在实例方法中,具体看应用的频繁程度。
- 定义格式:
class 类名: def 方法名(self,参数-若有): self.变量名 = 变量值 # 方法名指所有能传self的方法。 类方法、静态方法中不能定义实例变量。
- 调用:
如下: 对象名.实例变量 #第一种 #类内调用如下: self.实例变量 #第一种
2、私有变量
私有变量只能在类里面调用 ,不能在类外调用,子类也不可以调用。比如说连接数据库client不想在类外被修改,所以使用私有变量__client就不会被修改到。私有变量会比较安全。
- 定义格式:
class 类名: #第一种 def 方法名(self,参数-若有): self.__变量名 = 变量值 # 方法名指所有能传self的方法。 class 类名: #第二种 @classmethod def 方法名(cls,参数-若有): cls.__变量名 = 变量值 # 方法名指类方法。
- 调用:
#类内调用如下: self.__私有变量 #第一种 # 私有变量查找顺序:非类私有变量->类私有变量 cls.__私有变量 #第二种:类私有变量
3、局部变量
- 定义格式:
class 类名: def 方法名(self/cls-若有,参数-若有): 变量名 = 变量值 # 方法名指所有方法。
- 调用
1 #本函数内调用如下: 2 局部变量名
4、全局变量
- 定义格式:
class 类名: def 方法名(self/cls-若有,参数-若有): global 变量名 变量名 = 变量值 # 方法名指所有方法。
- 调用:
1 #全局变量定义至程序结束作用域内调用如下: 2 全局变量名
面向对象特性--继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
class ParentClass1: #定义父类 pass class ParentClass2: #定义父类 pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 pass
class Lm: money=1000000 house = 5 def driver(self): print('开车') class Mcb(Lm):#继承了父类,父类中有的他都有 def about_me(self): print('我有%s钱,%s房子'%(self.money,self.house)) self.driver() def driver(self): #子类有的时候,就不会继承父类的方法 print('dddddd开车') print(Mcb.money) m=Mcb() m.about_me()
更多参考:
http://www.cnblogs.com/Eva-J/articles/7293890.html
https://www.cnblogs.com/benric/p/5064169.html
https://blog.csdn.net/qq_42156420/article/details/80567052