1、面向对象术语

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类属性(类变量):类属性在整个实例化的对象中是公用的。类属性定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量:定义在方法中的变量,只作用于当前实例的类。
  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系。
  • 实例化:创建一个类的实例,类的具体对象。
  • 方法:类中定义的函数。
  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

2、类定义

Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。

对象可以包含任意数量和类型的数据。

  1. class test(object): #定义一个类,在3.5中必须指定基类object
  2. i = 123 #类变量
  3. def func(self): #类方法
  4. print('第一个类')
  5. return 'hell python'
  6.  
  7. s = test() #通过类实例化对象
  8. str = s.func() #对象调用类方法
  9. print(test.i) #通过类名调用类变量
  10. print(str) #类返回值
  11.  
  12. #output
  13. 第一个类
  14. 123
  15. hell python

类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性和方法;实例化类后可以使用其属性,也可以动态的为实例对象添加属性而不影响类对象。

可以使用点(.)来访问对象的属性,也可以使用函数的方式来访问属性:

  1. class A(object):
  2. def __init__(self,x):
  3. self.x = x
  4. def static_func(y=5):
  5. print(y)
  6.  
  7. d = A(10) #类实例化对象
  8. print(getattr(d,'x')) #getattr访问对象的属性
  9. print(hasattr(d,'x')) #hasattr检查对象属性是否存在
  10. print(setattr(d,'y','zhang')) #设置对象的属性,如果属性不存在则创建新属性
  11. print(d.y) #打印实例对象属性值
  12. delattr(d,'y') #defattr删除对象属性
  13. print(hasattr(d,'x'))
  14.  
  15. #output
  16. 10
  17. True
  18. None
  19. zhang
  20. True

python3内置类属性:

__dict__:类的属性(包含一个字典,由类的数据属性组成)

__doc__:类的文档字符串

__name__:类名

__module__:类定义所在的模块(类的全名是‘__main__.className’,如果类位于一个导入模块mymod中,那么className.__module__等于mymod)

__bases__:类的所有父类构成元素(包含了以上所有父类组成的元组)

  1. class myclass(object):
  2. class_n = 'foo'
  3. def __init__(self,x,y,z):
  4. self.x = x
  5. self.y = y
  6. self.z = z
  7. def func_class(self):
  8. print('out:',self.x,self.y,self.z)
  9.  
  10. t = myclass('','','')
  11. t.func_class() #调用实例方法
  12.  
  13. print('__dict__:',myclass.__dict__) #返回类的属性
  14. print('__dict__:',t.__dict__) #返回实例属性
  15. print('__name__:',myclass.__name__) #返回类名
  16. print('__doc__:',myclass.__doc__)
  17. print('__module__:',myclass.__module__) #返回类属在的模块
  18. print('__mro__:',myclass.__mro__)
  19. print('__bases__:',myclass.__bases__) #返回类对象
  20.  
  21. #output
  22. out: 10 20 50
  23. __dict__ {'__init__': <function myclass.__init__ at 0x0000004249F0F378>, '__doc__': None, 'func_class': <function myclass.func_class at 0x0000004249F0F400>, 'class_n': 'foo', '__dict__': <attribute '__dict__' of 'myclass' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'myclass' objects>}
  24. __dict__ {'x': '', 'z': '', 'y': ''}
  25. __name__: myclass
  26. __doc__: None
  27. __module__: __main__
  28. __mro__: (<class '__main__.myclass'>, <class 'object'>)
  29. __bases__: (<class 'object'>,)

类的专有方法:

  • __init__ 构造函数,在生成对象时调用

  • __del__ 析构函数,释放对象时使用

  • __repr__ 打印,转换

  • __setitem__按照索引赋值

  • __getitem__按照索引获取值

  • __len__获得长度

  • __cmp__比较运算

  • __call__函数调用

  • __add__加运算

  • __sub__减运算

  • __mul__乘运算

  • __div__除运算

  • __mod__求余运算

  • __pow__乘方

__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法,类定义了__init__()方法后,类的实例化操作会自动调用__init__()方法,__init__()可以由参数,会传递到类的实例化操作上。

self代表类的实例,而非类本身,在类的内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含self,且为第一个参数,self代表的是类的实例。

  1. class test(object):
  2. def __init__(self,name,age,salary): #初始化类属性
  3. self.name = name
  4. self.age = age
  5. self.salary = salary #实例化对象会将类初始化到实例对象上
  6.  
  7. def buygo(self):
  8. print('%s的工资是%s元' %(self.name,self.salary)) #调用类属性
  9.  
  10. #通过类实例化对象
  11. zhansan = test('zhansan',20,8888)
  12. lisi = test('lisi',22,6000)
  13. #调用类方法
  14. zhansan.buygo()
  15. lisi.buygo()
  16.  
  17. #output:
  18. #zhansan的工资是8888元
  19. #lisi的工资是6000元
  1. class test1(object):
  2. a = 10
  3. b = 20
  4. def get(self):
  5. print('取幂:',self.a.__pow__(self.b))
  6. print('求余数:',self.b.__mod__(self.a))
  7. print('乘:',self.b.__mul__(self.a))
  8. print('减:',self.b.__sub__(self.a))
  9. print('加:',self.b.__add__(self.a))
  10. print('输出:',self.b.__repr__())
  11.  
  12. d = test1()
  13. d.get()
  14.  
  15. #output
  16. 取幂: 100000000000000000000
  17. 求余数: 0
  18. 乘: 200
  19. 减: 10
  20. 加: 30
  21. 输出: 20

实例方法,类方法,静态方法,类属性,实例属性:

  1. #实例方法,就是类的实例能够使用的方法
  2. class myclass(object):
  3. def __init__(self,name):
  4. self.name = name
  5. def instancefunc(self):
  6. print('调用实例方法%s'%self.name)
  7.  
  8. if __name__ == "__main__":
  9. inst = myclass('zhangsan') #通过类创建实例
  10. inst.instancefunc() #实例使用实例方法
  11. myclass.instancefunc(inst) #类使用实例方法,需要传递实例参数
  1. #类方法是将类本身作为对象进行操作的方法,类方法使用@classmethod装
  2. #饰器定义,其第一个参数是类,约定为cls,也可以自己定义,类对象和实例
  3. #都可以调用类方法,类方法只能调用类属性,不能调用实例属性。
  4.  
  5. class A(object):
  6. number = 10 #定义类属性
  7. def __init__(self,name): #初始化类属性
  8. self.name = name
  9. def car(self): #定义实例方法
  10. print('实例方法:%s'%self.name)
  11. @classmethod #定义类方法
  12. def cat(cls):
  13. print('类方法:%s'%cls.number) #此处不能调用类属性name,只能调用类属性number
  14.  
  15. d = A('sb')
  16. d.car() #实例调用实例方法
  17. d.cat() #实例调用类方法
  18. A.cat() #类调用类方法
  19.  
  20. #output
  21. 实例方法:sb
  22. 类方法:10
  23. 类方法:10
  1. #静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类
  2. #型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可
  3. #以调用静态方法,静态方法不能调用类属性和实例属性,但可以调用传参。
  4.  
  5. class A(object):
  6. number = 10
  7. def __init__(self,name):
  8. self.name = name
  9. def car(self):
  10. print('实例方法:%s'%self.name)
  11. @staticmethod #定义静态方法
  12. def cat(x,y): #定义调用传参
  13. print('静态方法:%s'%(x*y))
  14.  
  15. d = A('sb') #实例化类
  16. d.car() #实例方法
  17. d.cat(5,4) #实例调用静态方法
  18. A.cat(6,3) #类调用静态方法
  19.  
  20. #output
  21. 实例方法:sb
  22. 静态方法:20
  23. 静态方法:18
  1. #类属性与实例属性在实例方法,类方法,静态方法中的调用关系
  2. class A(object):
  3. number = 10 #定义类属性
  4. def __init__(self,name):
  5. self.name = name #实例属性
  6. def car(self): #实例方法可以调用类属性和实例属性
  7. print('实例方法:%s[%s]'%(self.name,self.number))
  8. @classmethod
  9. def cae(cls): #类方法只能调用类属性
  10. print('类方法:%s'%cls.number)
  11.  
  12. @staticmethod
  13. def cat(x,y): #静态方法不能调用类属性和实例属性
  14. print('静态方法:%s'%(x*y))
  15.  
  16. d = A('sb')
  17. d.car()
  18. A.car(d)
  19. d.cae() #实例调用方法
  20. A.cae() #类调用方法
  21. d.cat(5,4)
  22. A.cat(6,3)
  23.  
  24. #output
  25. 实例方法:sb[10]
  26. 实例方法:sb[10]
  27. 类方法:10
  28. 类方法:10
  29. 静态方法:20
  30. 静态方法:18

3、类的封装

封装是面向对象的特征之一,是对象和类概念的主要特性。

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

python通过变量名命名来区分属性和方法的访问权限,默认权限相当于c++和java中的public

类的私有属性: __private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs

类的私有方法:__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods

  1. class myclass(object):
  2. def __init__(self,name,age): #构造方法,根据类创建对象时自动执行
  3. self.name = name
  4. self.age = age
  5. def func(self):
  6. print('%s今年%s'%(self.name,self.age))
  7.  
  8. #根据类创建对象,会自动执行类的__init__方法
  9. obj1 = myclass('zs',18) #会将zs和18分别封装到类的self的name和age属性中
  10. obj2 = myclass('ls',20)
  11.  
  12. print(obj1.name,obj1.age) #直接调用obj1对象的属性
  13. print(obj2.name,obj2.age)
  14.  
  15. obj1.func() #默认会将obj1传递给self参数,即:obj1.func(obj1),所以此方法的内部self=obj1,self.name是zs
  16. obj2.func()
  17.  
  18. #output
  19. zs 18
  20. ls 20
  21. zs今年18
  22. ls今年20
  1. class fater(object):
  2. __name = '私有属性'
  3. age = "公有属性"
  4. def func(self):
  5. print(self.age)
  6. print(self.__name)
  7. def __foo(self): #定义私有方法
  8. print(self.__name)
  9. class son(fater):
  10. def show(self):
  11. print(fater.age)
  12. #print(fater.__name)
  13.  
  14. print(fater.age)
  15. print('----------------')
  16.  
  17. obj1 = fater()
  18. obj1.func()
  19. print('----------------')
  20. #obj1.__foo() #直接调用会报错,只有通过"_类名__方法"的形式调用
  21. obj1._fater__foo() #调用私有方法
  22. print(obj1.age)
  23. #print(obj1.__name) #直接调用会报错,通过“_类名__属性”方法调用
  24. print(obj1._fater__name) #调用私有属性
  25.  
  26. print('-------son----')
  27. obj2 = son()
  28. obj2.show() #调用父类属性
  29. obj2.func()
  30. obj2.__foo() #调用父类方法错误
  31. obj2._fater__foo() #正确调用父类方法
  32.  
  33. #output
  34. 公有属性
  35. ----------------
  36. func: 公有属性
  37. func: 私有属性
  38. ----------------
  39. __foo: 私有属性
  40. 公有属性
  41. 私有属性
  42. -------son----
  43. show: 公有属性
  44. func: 公有属性
  45. func: 私有属性
  46. __foo: 私有属性

4、类继承

  1. 继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子类继承了父类的所有公有实例变量和方法。
    继承实现了代码的重用。重用已经存在的数据和行为,减少代码的重新编写。
    python在类名后用一对圆括号表示继承关系,括号中的类表示父类或基类
  1. #经典类和新式类的区别:当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
  2. class old: #经典类写法
  3. pass
  4.  
  5. class new(object): #新式类写法
  6. pass

在python中类继承的特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。使用super().__init__()或parentClassName.__init__()

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

  1. class test(object): #定义父类
  2. def __init__(self,name,age,salary):
  3. self.name = name
  4. self.age = age
  5. self.salary = salary
  6.  
  7. def buygo(self):
  8. print('%s[%s]岁就有%s元的工资了' %(self.name,self.age,self.salary))
  9.  
  10. class test_student(test): #调用父类
  11. def __init__(self,name,age,salary,nb):
  12. test.__init__(self,name,age,salary) #重写父类构造方法
  13. self.nb = nb
  14. def buygo(self): #覆写类方法
  15. print('%s[%s]岁就有%s元的工资了,很%s' %(self.name,self.age,self.salary,self.nb))
  16.  
  17. #通过类实例化对象
  18. zhansan = test_student('zhansan',20,8888,'牛逼哦')
  19. lisi = test_student('lisi',22,6000,'得瑟吧')
  20.  
  21. zhansan.buygo()
  22. lisi.buygo()
  23.  
  24. #output:
  25. zhansan[20]岁就有8888元的工资了,很牛逼哦
  26. lisi[22]岁就有6000元的工资了,很得瑟吧

如果父类中的方法名相同于子类中的方法名,子类方法将覆盖父类方法。

多继承的优先级顺序是:在新式类中是从左往右查找,找到即停止;而经典类是深度查找的从左到右如:A(B,C),B(D),那么顺序是A->B->D->C

5、多态

多态依赖于继承,多态的作用,就是为了类在继承和派生的时候,保证继承类中实例的某个属性或方法的调用,实现了接口的重用。class A(object):    def __init__(self):

  1. self.name = 'ZHANGSAN'
  2. def show(self):
  3. print('A.show:',self.name)
  4. class B(A):
  5. def show(self):
  6. print('show_b:',self.name)
  7. class C(A):
  8. def show(self):
  9. print('show_c:',self.name)
  10. def func(obj): #定义函数,传递对象
  11. obj.show() #通过类实例对象调用类下的方法
  12. A_obj = A()
  13. B_obj = B()
  14. C_obj = C()
  15. func(A_obj)
  16. func(B_obj)
  17. func(C_obj)
  18. #output

A.show: ZHANGSAN
show_b: ZHANGSAN
show_c: ZHANGSAN

  1.  

6、总结

  • 面向对象的知识总计如下:
  • 面向对象时一个编程方式,此编程方式的实现是基于对类和对象的使用
  • 类是一个模版,模版中包装了多个‘函数’供使用
  • 对象根据模块创建实例,实例可以调用被包装在类中的函数
  • 继承实现了多个类直接的方法属性调用,减少代码的重用性
  • 多态在继承的基础上解决了方法调用的重用,而不被子类给覆盖。
  • 面向对象的三大特性:封装、继承和多态

python3之面向对象的更多相关文章

  1. [Python3] 024 面向对象 第四弹

    目录 11. 类和对象的三种方法 12. 抽象类 12.1 抽象方法 12.2 抽象类 12.3 抽象类的使用 13. 自定义类 接上一篇 [Python3] 023 面向对象 第三弹 11. 类和对 ...

  2. [Python3] 023 面向对象 第三弹

    目录 7. 类相关函数 8. 类的成员描述符(属性) 9. 类的内置属性 10. 类的常用魔术方法 10.1 操作类 10.2 描述符 10.3 属性操作 10.4 运算分类相关魔术方法 接上一篇 [ ...

  3. [Python3] 022 面向对象 第二弹

    目录 6. 面向对象的三大特性 6.1 封装 6.1.1 私有 private 6.1.2 受保护 protected 6.1.3 公开 public 6.2 继承 6.2.1 继承的概念与作用 6. ...

  4. Python3中面向对象 OOP

    Python3中面向对象 OOP 定义: python中通过关键字 class 实现类的定义: class ClassName(object): pass 获取成员变量:ClassName.变量名 修 ...

  5. 【Python3之面向对象的程序设计】

    一.面向对象的程序设计的由来 1.第一阶段:面向机器,1940年以前 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据. 简单来说,就是直接编写 0 和 1 ...

  6. [Python3] 021 面向对象 第一弹

    目录 1. 面向对象概述 1.1 OOP 思想 1.2 几个名词 1.3 类与对象 2. 类的基本实现 2.1 类的命名 2.2 如何声明一个类 2.3 如何实例化一个类 2.4 如何访问对象成员 2 ...

  7. Python3 day6面向对象

    http://www.cnblogs.com/alex3714/articles/5188179.html ====================生活中==================== 世界 ...

  8. 【Python3之面向对象进阶】

    一.isinstance和issubclass 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pass obj=Foo() p ...

  9. 笔记||Python3之面向对象

    面向对象编程:简称OOP. 是一种程序设计思想.oop把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 在python中,所有数据类型都可以视为对象,也可以自定义对象.自定义的对象数据类 ...

随机推荐

  1. 【回文】leetcode - Shortest Palindrome

    题目: Shortest Palindrome Given a string S, you are allowed to convert it to a palindrome by adding ch ...

  2. 《Effective Modern C++》翻译--简单介绍

    北京时间2016年1月9日10:31:06.正式開始翻译.水平有限,各位看官若有觉得不妥之处,请批评指正. 之前已经有人翻译了前几个条目,有些借鉴出处:http://www.cnblogs.com/m ...

  3. Hibernate学习(二补充)关系映射----基于外键的双向一对一

    刚刚写的是基于外键的单向一对一.  那么双向一对一就是在单向一对一的基础上稍微改动就可以了. account.java和account.hbm.xml都不用变动  只要我们小小的变动address.j ...

  4. 【Sqlserver系列】初级思维导图

    1   概述 本篇文章主要概述Sqlserver思维导图. 2   具体内容 3   参考文献 [01]https://mp.weixin.qq.com/s/USNMslpvu7pWosMZnVTPd ...

  5. redis集群配置,spring整合jedis,缓存同步

    前台的商品数据(图片等加载缓慢)查询,先从redis缓存查询数据. redis是一个nosql数据库,内存版数据库,读取速度11w/s.本身具有内存淘汰机制,是单线程服务器(分时操作系统),线程安全. ...

  6. JavaScript--AJAX页面传值

    1.首先 闲话不说 直接代码走起,都是我工作闲事的积累干货 //重要 js 运行 $(function (){ 代码 }); 2.ajax 传值 //第一种 输入框 <input type=&q ...

  7. JavScript--表单提交

    前台代码 <div > <div id="show">asdasdas</div> <form id="form"&g ...

  8. ed命令

  9. js判断文件类型大小并给出提示

    上传文件是工作中常用的功能,不同的场景对不同的文件类型和文件大小都有不同的要求: <form id="uploadForm" method="post" ...

  10. Xamarin Android Fragment的两种加载方式

    android Fragment的重点: 3.0版本后引入,即minSdk要大于11 Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的Fra ...