chapter8.1、面向对象
面向对象
面向机器,机器指令,代表是汇编语言
面向过程,规范化,分支,循环等,将要完成的事按步骤进行,问题规模小,可以步骤化,规模较大时也可以使用,也是一套方法论。代表是C语言
抽象对象增多时,解决方法较复杂,不适合工业化
面向对象,OOP,方法论,问题规模的增多,需要的人,物增加,从人,物的角度出发,考虑问题,C++,Java,Python
编程范式,假如模式是武功的招式,那么范式就是武功的内功。
认知世界,分析世界的方法论,将万事万物都抽象成类
类class
抽象的概念,是万事万物的抽象,是一类事物的共同特征,
属性和方法
对象 instance object
对象是类的具象,是一个实体
属性,对象状态的抽象,数据结构描述,保存
操作,对象行为的抽象,操作名和操作方法
类决定了该有的属性,不能保存具体的值
每个对象的具体属性有差异,不能保存在类上,人类的每个实例的基本属性各有不同,所以属性保存在每个实例的人身上
哲学
一切皆对象
对象是数据和操作的封装
对象是独立的,但对象之间可以相互作用
目前OOP是最接近人类认知的编程范式
面向对象的3要素
封装
组装,将数据和操作组装到一起
隐藏数据,对外暴露一些接口,开汽车不需要知道汽车怎么跑。暴露一些属性和方法,比如你知道车怎么开,可以选择颜色,但不用知道怎么操作发动机。
继承
多复用,继承,动物类有的,人类可以继承,父类有的子类就可以继承,继承来了就不用再写
多继承少修改,OCP(Open-closed Principle),使用继承来改变,来体现个性,人类也吃,但吃法不同于其他的动物类,要继承下来修改,继承就是为了修改
多态
多种表现,灵活,动态绑定
人类就是封装
人类继承自动物类,孩子继承父母特征,分为单一继承,多继承
多态,继承自动物类的人类、猫类的操作“吃”不同,动态绑定
Python的类
class ClassName
关键字,必须使用class,其他命名不能使用关键字
类名必须使用大驼峰命名,每个单词首字母大写
类对象,用标识符和类对象绑定
class MyClass:"""example"""x = 'abc'def foo(self):return "My class"print(MyClass.x)print(MyClass.__doc__)
类对象,类定义就会形成一个类对象
类的属性,类中的变量和方法都是类的属性
类变量,上例中x就是类的变量
上例中foo是类的方法对象(method),和普通函数不同,要求至少有一个参数,第一个是self,指当前的实例本身
a=MyClass(),实例化,只能生成一个具体的实例,每次都产生完全不同的对象,调用实例化和初始化方法
实例化__new__,有这个方法,一般不用自己调,不用自己写
Python实例化后,会自动调用__init__方法,也就是初始化(构造器,构造方法)方法,这个方法第一个参数必须留给self,,其他参数根据情况决定。
只要实例化,一定会初始化,__init__可以不定义,没有会在实例化时隐式调用,从父类中一定会有调用,实例化就是生产,构造一个实例,初始化就是为了能让产品使用,出场配置__init__
初始化可以配参数,__init__函数要求必须返回None,不能返回任何值
self指代实例本身,后边可以传入类的对象的属性,可以加缺省值,也可以要求创建时加入
self.name=name,为当前实例添加属性,每个单独的实例都有自己的属性,都在不同的内存位置
实例调用方法时,对象调用类的方法,隐含着self参数,self指实例本身
tom.showage() 对象调用类的方法,隐含着self参数
Person.showage(tom) 类调用属性,参数是实例,必须加参数
class Person:address = 'Beijing'##类的属性,对象在自己的字典里没有的话,就到类这里来找def __init__(self,name,age=3):##初始化函数,每次创建新的对象就会调用一次self._name = name##实例的属性,每个对象单独保存各自的属性self.age =agedef showage(self):##类的属性,也是类的方法print ('{} is {}'.format(self.name,self.age))print(Person.__dict__) tom = Person('tom',12)##创建对象 print(Person.__dict__)##调用类不会改变类的属性 Person.age = 14##!!注意只是在类中增加了属性,不会影响__init__方法中的缺省值3 jerry = Person('jerry')##这里的age使用了__init__中的缺省值print(jerry.__dict__)##对象的字典,不能用类查看 jerry.age+=2##修改对象的属性 print(Person.__dict__)##修改对象的属性,不影响类的属性 print(jerry.__dict__)##对象的字典更新 print(jerry.address)##从字典看出,jerry没有address的属性,就去类中取了Beijing tom.address = 'shanghai'##给类的对象tom增添属性 print(tom.__dict__)##查看对象的字典,增添了新的属性
以上print语句可以一条条打,观察变化
实例变量,实例变量保存在实例对象上,是每个实例自己独有的变量,类变量是类的变量,是类的所有实例共享的属性和方法
__name__ 对象名, __class__.__name__ 返回对象的类的类名,类型是str
__class__ 对象的类型,对象.__class__ 等同于 type(对象),大部分对象可以通过字典看内部变化
__dict__ 对象的属性和字典,对象.__class__.__dict__ 查看对象的类的属性字典
__qualname__ 类的限定名
对象都会动态的为自己增加属性__dict__,可以通过实例.__dict__.[变量名]和实例.变量名查看
实例.变量名 : 访问实例的属性,优先访问自己的__dict__里找属性,没有就去访问类的字典,在没有就报AttributeError;
实例.__dict__.[变量名] : 通过字典访问时,访问谁的字典就去谁的字典找,不会去别的字典找,找不到就报KeyError
实例的同名变量会隐藏类变量,或者说覆盖这个类变量,就是在实例的字典里找到了,就不去类的字典里找了
实例变量是每一个实例自己的变量,是自己独有的;类变量是类的变量,是类的所有实例共享的属性和方法
全大写表示常量,一般开发遵守的原则,不是强制规定
可以用装饰器传参来给类添加属性↓
def add_name(name):def warpper(cl):cl.NAME = namereturn clreturn warpper@add_name('tom') class Person:AGE = 20 Person.__dict__
类属性的定义,无第一参数也可以,将函数放在类下。类可以调用,但类的实例不可以调用 ,会提示少参数,禁止这样写
类方法和静态方法
类方法:加装饰器@classmethod
类方法,必须传入至少一个参数,传入的第一个参数是类对象,就算用实例调用,传入的第一个参数也是类对象,习惯用cls表示参数,这是为了易读,不要改。可以通过cls直接操作类的属性。
class Person:@classmethoddef class_method(cls):print(cls) Person.class_method()##类调用,打印类对象 Person().class_method()##实例调用,打印类对象
静态方法:装饰器中间没有符号,@staticmethod,
静态方法,不要形参,不会隐式传入其他形参,直接是本身的参数传入,只是表明方法的命名空间,方便组织管理,不论是类调用,还是实例调用,都不会隐式传入参数
class Person:@staticmethoddef static_method():print('1111') Person.static_method()##类调用,打印1111 Person().static_method()##实例调用,打印1111
类的属性只能通过类和实例访问
类几乎可以调用所有的方法,但是对于普通的函数,需要加对象,实例作为第一参数
实例几乎可以调用所有类中定义的方法,包括类方法和静态方法,但要找到实例的类。普通方法传入实例自身,括号中不用在写自己
访问控制
私有属性(private),私有成员,使用双下划线开头,通过方法来访问私有属性,可以在方法中加入控制,使用双下划线时,python解释器会将其改名,在字典中保存为 _类名__变量名 的名称,但还是可以通过该名称来修改,没有真正的隐藏,类内可修改,类外不可修改
class Person:__x = 200##类的私有属性def __init__(self,name,age=19):self.name = name##对象的公有属性self.__age = age##对象的私有属性def getage(self):##通过getage访问私有属性return self.__agedef growup(self,incr=1):if incr<50 and incr>0:##粗略的判断一下self.__age += incrtom = Person('tom') print(tom.getage()) tom.growup() print(tom.getage()) tom.__age = 1000##这里改变了对象的属性,相当于又在对象上加了一条属性,不会影响类 print(tom.getage()) tom.growup(incr=200)##没有通过判断,不会改变 print(tom.getage()) print(tom._Person__age)##其实藏在这里,还是可以修改得
保护属性,保护成员,保护方法,使用一个下划线来控制,是开发者约定,解释器不做特殊处理
class Person:_x = 200##类的保护属性def __init__(self,name,age=19):self.name = name##对象的公有属性self._age = age##对象的保护属性 tom = Person('tom') print(tom._age)##并没有被修改, print(tom.__dict__)##解释器不会修改字典的内容
共有成员,共有属性,共有方法,其他的方法都是
开发者约定,使用_,__,仅是提醒或警告,除非必要,不要修改或者使用
没有绝对安全的私有成员或者保护成员
改名仅在类定义内实现,在外部使用下划线只会修改实例的字典内的属性
补丁
通过修改或者替换类的成员,使用者调用方式不变,但是类的功能可能已经改变了
Monkey Patch
在运行时对属性,方法,函数等进行动态的替换
目的往往是通过替换、修改来增强功能,扩展原有代码的能力
黑魔法,慎用
属性装饰器@property#gatter getter就是以后的属性名,获取值,有了getter至少是只读属性
@age.setter设置值,与属性名同名,接受两个参数,第一个是self,第二个是将要赋的值,属性可写
@age.deleter清除值,很少用,删除属性
使用property装饰器的这三个方法同名,
必须有gatter,才有setter
类的实例消亡时,会调用__del__,(其他语言叫析构函数),将清理工作放在里边,会释放占用的资源,比如释放连接
注意并不能真正的销毁对象,对象消亡由tc管,不是他管,他只是对象销毁时会调用它。
使用del语句删除实例,引起计数减一,当引用计数为0时,会自动调用__del__
由于python的垃圾回收机制,不能确定何时执行垃圾回收。
除非明确·知道自己的目的,否则不要使用这个方法
overload,方法重载,其他语言中静态语言会由传入的参数的类型和数目决定要调用的函数,函数同名
python中没有重载,不能重载,不需要重载
或者说python本身就实现了重载
Encapsulation封装
将数据和操作组织起来到类中,即属性和方法
将数据隐藏起来,给使用者提供方法,使用者通过操作就可以获取或者修改数据,getter和setter
通过访问控制,暴露适当的数据和操作提供给用户,将该隐藏的隐藏起来,例如保护成员和私有成员
转载于:https://www.cnblogs.com/rprp789/p/9642929.html
chapter8.1、面向对象相关推荐
- 【AJAX】JavaScript的面向对象
Ajax中后端数据返回后需要前端通过JavaScript来实现动态数据更新的问题.所以,在Ajax中加深了一遍JavaScript面向对象的印象. 基础部分: JavaScript中创建对象并简单对象 ...
- 面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?
AutoSAR入门到精通系列讲解 将从2019年开始更新关于AutoSAR的知识,从入门到精通,博主xyfx和大家一起进步 雪云飞星 ¥29.90 去订阅 简单地说结构化分析方法主要用来分析系统的功能 ...
- 2021年大数据常用语言Scala(二十八):scala面向对象 MAVEN依赖和类
目录 scala面向对象 MAVEN依赖 类 - 掌握 创建类和对象 - 掌握 getter/setter - 了解 类的构造器 - 掌握 scala面向对象 MAVEN依赖 <?xml ver ...
- php面向对象程序设计,PHP面向对象程序设计类的定义与用法简单示例
本文实例讲述了PHP面向对象程序设计类的定义与用法.分享给大家供大家参考,具体如下: class Person { private $name; private $sex; private $age; ...
- java面向过程和面向对象
面向过程(Procedure Oriented):说的是功能的行为 面向对象(Object Oriented,简称OO):说的是功能的对象 面向过程理解: 当学习java的时候先了解java语言优良的 ...
- day22_面向对象
面向过程: 优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可. 缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身. 面向对象: 优点是:解决了程序的扩展性.对 ...
- java面向对象-------静态初始化块
1.构造方法用于对象的初始化!静态初始化块,用于类的初始化操作,在静态初始化块中不能直接访问非static成员. package java面向对象; /** * 测试静态初始化块 */public c ...
- 7.12 其他面向对象设计原则3: 依赖倒置原则DIP
其他面向对象设计原则3: 依赖倒置原则DIP The Dependency Inversion Principle 7.1 依赖倒置原则DIP The Dependency Inversion P ...
- Day-16 面向对象03 类与类之间的关系
一.类与类之间的依赖关系 我用着你,但是你不属于我,这种关系是最弱的,比如,公司和雇员之间,对于正式员工,肯定要签订劳动合同,还得小心伺候着,但是如果是兼职,那无所谓,需要了你就来,不需要你就可以拜拜 ...
最新文章
- [转]SIFT特征提取分析
- ExtJS中给Tree节点加click事件
- apk ionic 破损_cordova – ionic build android不生成任何.apk文件或错误
- python定时器5秒执行一次_PLC编程之“自切断”定时器
- spring-retry_使用Spring-Retry重试处理
- 数学的威力:一个方程提升中国卫星图像质量30%
- Path Sum I, II
- FlashBuilder找不到所需要的AdobeFlashPlayer调试器版本的解决方案
- 搭建elasticsearch可视化插件
- C语言 头哥习题答案截图
- pd虚拟机专用windows系统镜像(m1/intel)「新增:Intel Mac win7专业版懒人包镜像」
- BFS算法(广度优先搜索)java
- 2020-04-03-功能性光学脑成像
- R语言怎么写积分_2. 角速度的积分
- 玩转用户身份权益——详解闲鱼身份权益体系的实现
- H G W S哪一个不是状态函数_师大版成语词典发布!不学不是师大人!
- 人工智能在脑神经科学的应用创新与热点——脑机接口
- 最新-2020年必须缴费注册苹果开发者账号才能申请ios证书
- 王小川谈创业必须突破的六大槛:人、产品、渠道、体制、资本、移动
- 安卓web开发!你还在把Java当成Android官方开发语言吗?建议收藏