面向对象封装继承多态五大基本原则魔法方法反射
目录
面向对象
三大基本特征
五大基本原则
魔法方法
反射
面向对象
什么是面向对象
使用模板的思想,将世界万事万物使用对象来表示一个类型
面向对象和面向过程的区别:
- 面向对象的不就是使用程序处理事情时以对象为中心去分析
- 面向过程关心处理的逻辑、流程等问题,而不关心事件主体
- 面向对象即面向主体,所以我们在解决问题时应该先进行对象的封装
面向对象编程主要优点:
易维护,易扩展,效率高
- 其实OOP编程的主要作用和函数一样也是使你的代码修改和扩展变的更容易
- 函数编程与OOP的主要区别就是OOP可以使程序更加容易扩展和易更改
- OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述
- 使用面向对象编程的原因一方面是因为它可以使程序维护和扩展变得更简单,并且可以大大提高程序开发效率
- 另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容
Class 类(模板)
1. 一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。
2. 在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
Object 对象(实例)
1.一个对象即是一个类的实例化后实例
2. 一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性
3. 就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
类中的一些名词
1. __init__ # 构造函数 2. Self.name = name # 实例变量、普通属性 或者叫 普通字段 3. public_object = "public" # 类变量、公有属性 或则叫 静态字段 4. self.__heart= "Normal" # 私有属性 在外面无法访问 5. def shot(self) # 类方法
三大基本特征
面向对象的三个基本特征是:封装、继承、多态
封装
封装,也就是对类中属性和方法进行一种封装,隐藏了实现细节
封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员。
封装的优点:
- 将变化隔离
- 便于使用
- 提高复用性
- 提高安全性
继承
继承是面向对象的基本特征之一,当一个类继承自另一个类,它就被称为一个子类/派生类,继承自父类/基类/超类。它会继承/获取所有类成员(属性和方法)
继承机制允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承的作用:
继承能让我们重新使用代码,也能更容易的创建和维护应用。
继承的分类:
- 单继承:一个类继承自单个基类
- 多继承:一个类继承自多个基类
- 多级继承:一个类继承自单个基类,后者则继承自另一个基类
- 分层继承:多个类继承自单个基类
- 混合继承:两种或多种类型继承的混合
继承概念的实现方式有三类:
实现继承、接口继承和可视继承。
Ø 实现继承是指使用基类的属性和方法而无需额外编码的能力;
Ø 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;
Ø 可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。
多态
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。“一个接口,多种实现”
实现多态的两种方式:
覆盖,是指子类重新定义父类的虚函数的做法。
重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
多态的优点:
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
五大基本原则
1、单一职责原则(SRP)
一个类应该有且只有一个去改变它的理由,这意味着一个类应该只有一项工作。
比如在职员类里,将工程师、销售人员、销售经理这些情况都放在职员类里考虑,其结果将会非常混乱,在这个假设下,职员类里的每个方法都要if else判断是哪种情况,从类结构上来说将会十分臃肿。
2、开放封闭原则(OCP)
对象或实体应该对扩展开放,对修改封闭。
更改封闭即是在我们对模块进行扩展时,勿需对源有程序代码和DLL进行修改或重新编译文件!这个原则对我们在设计类的时候很有帮助,坚持这个原则就必须尽量考虑接口封装,抽象机制和多态技术!
3、里氏替换原则(LSP)
在对象 x 为类型 T 时 q(x) 成立,那么当 S 是 T 的子类时,对象 y 为类型 S 时 q(y) 也应成立。(即对父类的调用同样适用于子类)
4、依赖倒置原则(DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。具体实现应该依赖于抽象,而不是抽象依赖于实现。
5、接口隔离原则(ISP)
不应强迫客户端实现一个它用不上的接口,或是说客户端不应该被迫依赖它们不使用的方法,使用多个专门的接口比使用单个接口要好的多!
魔法方法
1、何为魔法方法:
Python中,一定要区分开函数和方法的含义
- 函数:类外部定义的,跟类没有直接关系的;形式: def func(*argv)
- 方法:class内部定义的函数(对象的方法也可以认为是属性)
- python自动产生的(魔法方法):一般形式为 func(),python会在对应的时机自动调用该函数
- 人为自定义的方法:一般和普通函数没有区别,只是定义在了class中而已
方法与函数的区别:
- 方法可认为是函数的特殊情况
- 方法定义在class内部
- 方法的第一个参数应为 cls(类方法) 或者 self(实例方法)
2、魔法方法调用的顺序
class Student(object):def __new__(cls, *args, **kwargs):print('__new__')return object.__new__(cls) # 必须返回父类的__new__方法,否则不不执行__init__方法,无法创建实例def __init__(self,name):print('__init__')self.name = namedef __str__(self): # 作用:打印实例时显示指定字符串,而不是内存地址print('__str__')return self.namedef __call__(self, *args, **kwargs): # 当执行C()(*args) 或者 s1(*args) 就会执行__call__print('__call__',*args)def __del__(self): # 作用:清除无用的实例对内存的暂用print('__del__')
1、实例化时机会执行__new__、init
2、执行 实例() 就会执行__call__ 方法,并将参数传递给__call__函数
3、当打印实例时就会执行 str 方法下返回的字符串(默认返回的实例地址)
4、析构方法:当删除实例时就会调用 del 方法
魔法方法汇总:
基本方法
__int__(self) 定义当被 int() 调用时的行为 __float__(self) 定义当被 float() 调用时的行为 __round__(self[, n]) 当被round()调用时的行为 round(digit[, n]) 将digit数字保留n位精度 __hash__(self) 定义能被 hash() 调用的行为 __bytes__(self) 定义被 bytes() 调用的行为 __bool__(self) 定义被 bool() 调用的行为 返回True(1) 或 False(0) __format__(self, form) 定义被 format()调用的行为
运算符方法
__add__(self, other) 加法:+
__sub__(self, other) 减法:-
__mul__(self,other) 乘法:*
__truediv(self, other) 除法:/ 注意是 truediv
__floordiv(self, other) 整数除法:// floor()即为向下取整的意思
__mod__(self, other) 求余:%
__pow__(self, other[, mod]) 乘方:** pow(x,y[,z]),若无Z,则为 return x**y若有Z,则为 return x**y%z
__divmod__(self, other) divmode() 返回值为元祖 (商值,余数)
__lshift__(self, other) 左移:<<
__rshift__(self, other) 右移:>>
__and__(self, other) 按位与:& 注意以下均为按位操作,非逻辑操作
__or__(self, other) 按位或:|
__xor__(self, other) 按位异或:^
反运算符方法
__radd__(self, other) 加法,如a+b,当a不支持__add__()操作时,调用此函数; 即在运算符的基础上加上 'r' 即可,以下雷同 __rsub__(self, other) other - self
增量赋值运算方法
__iadd__(self, other) 赋值加法:+= 即在赋值运算符之前加 'i' ,以下雷同
__isub__(self, other) 赋值减法:-= self = self - other
一元运算符方法
__pos__(self) 定义正号:+x
__neg__(self) 定义负号:-x
__abs__(self) 取绝对值
__invert__(self) 按位求反:~x
比较运算符方法
__gt__(self, other) 大于:>
__ge__(self, other) 大于等于:>=
__lt__(self, other) 小于:<
__le__(self, other) 小于等于:<=
__eq__(self, other) 相等:==
__ne__(self, other) 不等:!=
属性操作
__getattr__(self, name) 当用户访问一个不存在的属性时调用 注意 object/super() (所有类的基类) 是无该方法的
__getattribute(self, name) 访问存在的属性时调用 先调用此函数,如找不到该属性,再去调用上面的属性
__setattr__(self, name, value) 设置属性时调用
__delattr__(self, name) 删除一个属性时调用
__get__(self, instance, owner) 描述符被访问时调用 想详细了解,请点击这里__set__(self, instance, value) 描述符被改变时调用 __delelte__(self, instance, value) 删除描述符时调用
容器类型操作
__len__(self) 求容器的大小(注意与capacity的区别) 可变和非尅便容器均具备 __len__ 和 __getitem__
__getitem__(self, key) 获取容器中指定元素的行为
__setitem__(self, key, value) 设置容器中指定元素的行为 只有可变容器拥有 __setitem__ 和 __delitem__
__delitem__(self, key) 删除容器中指定元素的行为
__iter__(self) 定义迭代器中元素的行为
__reversed__(self) 当调用reversed()函数时
__contains__(self, item) 成员运算符in/ not in的行为
PS:
- 以上所有的魔法方法,采用__xx__形式(__为双 “_”,双下划线)
- 以上魔法方法为Python解释器自动调用,当然也可以手动调用
- 魔法方法Python解释器自动给出默认的,因此除非需要改变其内部功能,其它时刻刻使用默认魔法方法
- 魔法方法是针对class而言的,脱离了”类“谈magic_method是没有意义的
- *argv为可变的参数列表,类似C语言的va(variable argument),注意与指针的区别,python中暂时忘掉指针,因为python的内存机制都是解释器自动完成的
反射(hasattr和getattr和setattr和delattr)
反射机制简介:
通过字符串的形式导入模块
通过字符串的形式,去模块中寻找指定的函数,并执行
规定用户输入格式 模块名/函数名 通过__import__的形式导入模块,并通过 hasattr和getattr 检查并获取函数返回值
反射的概念:
反射指的是通过 “字符串” 对 对象的属性进行操作。
- hasattr: 通过 “字符串” 判断对象的属性或方法是否存在
- hasattr(ogj,name_str) 判断一个对象里是否有对应的字符串方法
- 当然对于python的对象而言,属性包含变量和方法;有则返回True,没有则返回False;
- 需要注意的是name参数是string类型,所以不管是要判断变量还是方法,其名称都以字符串形式传参;
class Dog(object):def eat(self,food):print("eat method!!!")
d = Dog()#hasattr判断对象d是否有eat方法,有返回True,没有返回False
print(hasattr(d,'eat')) #True
print(hasattr(d,'cat')) #False
- getattr: 通过 “字符串” 获取对象的属性或方法
- getattr(obj,name_str) 根据字符串去获取obj对象里的对应的方法的内存地址
- 获取object对象的属性的值,如果存在则返回属性值,如果不存在分为两种情况:
- (1)没有default参数时,会直接报错;
- (2)给定了default参数,若对象本身没有name属性,则会返回给定的default值;
- 如果给定的属性name是对象的方法,则返回的是函数对象,需要调用函数对象来获得函数的返回
- 值;
- 调用的话就是函数对象后面加括号,如func之于func();
class Dog(object):def eat(self):print("eat method!!!")
d = Dog()if hasattr(d,'eat'): # hasattr判断实例是否有eat方法func = getattr(d, 'eat') # getattr获取实例d的eat方法内存地址func() # 执行实例d的eat方法
#运行结果: eat method!!!
- setattr: 通过 “字符串” 设置对象的属性或方法。
- 使用stattr给类实例对象动态添加一个新的方法
- 给object对象的name属性赋值value,如果对象原本存在给定的属性name,则setattr会更改属性的值为给定的value
- 如果对象原本不存在属性name,setattr会在对象中创建属性,并赋值为给定的value;
def abc(self):print("%s正在交谈"%self.name)class Person(object):def __init__(self,name):self.name = namep = Person("星珲)
setattr(p,"talk",abc) # 将abc函数添加到对象中p中,并命名为talk
p.talk(p) # 调用talk方法,因为这是额外添加的方法,需手动传入对象# 打印结果 星珲正在交谈setattr(p,"age",30) # 添加一个变量age,复制为30
print(p.age)
- delattr: 通过 “字符串” 删除对象的属性或方法。
class Person(object):def __init__(self,name):self.name = namedef talk(self):print("%s正在交谈"%self.name)p = Person("星珲)delattr(p,"name") # 删除name变量
print(p.name)
面向对象封装继承多态五大基本原则魔法方法反射相关推荐
- 大数据笔记8—java基础篇4(面向对象-封装-继承-多态)
面向对象 一.面向对象 1.面向过程 1.2.举例 1.3.总结 二.面向对象 1.简述 2.举例 3.思想特点 2.1.类的定义格式 2.1.1.简述 2.2.2.格式 2.3.3.示例 三.类的使 ...
- (十)Core Java 面向对象(封装,继承,多态,接口) -02 (96)
目录 : 24 ). 面向对象(聚集关系) 25 ). 面向对象(子父类中变量的特点) 26 ). 面向对象(子父类中函数的特点-覆盖) 27 ). 面向对象(子父类中构造函数的特点 ...
- 猜丁壳(面向对象 封装 继承 多态)
创建三个包: util包中的Constans是用来存储常量的: util包中的MyUtil是用来存储工具类的: service包中的Player定义玩家的共同属性及方法: service包中的Comp ...
- c语言编程 菲薄拉,C语言设计模式-封装-继承-多态
快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...
- python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)
面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...
- python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态
六.Python面向对象--类与对象\封装\继承\多态 1.什么是面向对象编程 1.1 程序设计的范式:程序可控,易于理解 1.2 抽象并建立对象模型 1.3 程序是不同对象相互调用的逻辑.每个对象在 ...
- python--编写程序:实现乐手弹奏乐器,乐手可以弹奏不同的乐器而发出不同的声音------使用类的封装继承多态的问题/使用面向对象的思想,设计自定义类,描述出租车和家用轿车的信息
编写程序:实现乐手弹奏乐器,乐手可以弹奏不同的乐器而发出不同的声音 ------使用类的封装继承多态的问题 class Instrumnet():#乐器类def make_sound(self):pa ...
- Day55-每日一道Java面试题-Java 面向对象编程三大特性: 封装 继承 多态
Java 面向对象编程三大特性: 封装 继承 多态 封装 封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问.但是如果一个类没有 ...
- 一木.溪桥学Python-13:多继承、多态、常用魔法方法、单例模式
一木.溪桥 在Logic Education跟Amy学Python 逻辑教育 :https://logicedu.ke.qq.com 12期:Python基础课 一木.溪桥学Python-13:多继承 ...
最新文章
- 基础的重要性(程序猿之路)
- 用户变量和系统变量的区别是什么?
- 毕业论文写作Tips
- .Net+MySQL组合开发(二) 数据访问篇
- 北大读博手记:怎样完成自己的博士生涯?
- mysql-日常命令使用汇总
- html合并pdf文件,PDF Mergy:合并PDF
- abaqus帮助文档翻译,中英对照
- 监控行业常见视频格式
- XUI框架实现自带的tablayout(TabBar指示器)+viewpage实现页面切换?
- 接口授权时已经有access_token了为啥还需要refresh_token
- 51单片机教程(从原理开始基于汇编)
- 关于微信群的一个新玩法 (月末总结)
- 台式计算机硬件办公配置清单,颜值满分的办公台式电脑,分享配置清单
- [源码和文档分享]基于JAVA的实现学生卡管理系统
- uniapp 图片上传 删除
- 矩阵初等变换的“打洞技巧”与“分块矩阵的行列式公式”
- Redmi11T Pro +值不值得买 Redmi11T Pro +配置如何
- 仿ofo单车做一个轮播效果
- JAVA基础-字符串
热门文章
- mysql 语句怎样修饰约束_MySQL中的约束,添加约束,删除约束,以及一些其他修饰讲解...
- 票务系统思维导图_最全思维导图分享,告诉你如何系统的学好软件测试。
- 计算机上检查视力表,视力检测(30cm视力表自测)
- 成功解决利用pandas的read_csv函数读取csv文件的时候出现中文乱码问题
- 成功解决SyntaxError: (unicode error) ‘unicodeescape‘ codec can‘t decode bytes in position 0-1: malformed
- Py之GraphLab:graphlab库的简介、安装、使用方法之详细攻略
- DayDayUp:那些年-程序猿的爱情故事
- Dataset之谷歌地图数据集:谷歌地图数据集的简介、安装、使用方法之详细攻略
- DL之AF:机器学习/深度学习中常用的激活函数(sigmoid、softmax等)简介、应用、计算图实现、代码实现详细攻略
- Python之tkinter:动态演示调用python库的tkinter带你进入GUI世界(Find/undo事件)