标签:描述 基本结构 习惯 属性重名 私有 显示 函数 需求 ret
什么是面向过程
自上而下顺序执行,逐步求精
其程序结构是按功能划分为若干个基本模块,这些就是树状结构
各模块之间的关系尽可能简单,在功能上相对独立
每一模块内部均是由顺序、选择和循环三种基本结构
其模块化实现的具体方法是使用子程序
程序流程在写程序时就决定了
什么是面向对象
把数据及对数据的操作方法放在一起,作为一个相互依赖的整体——对象
对同类对象抽象出其共性,形成类
类中的大多数数据,只能用本类的方法进行处理
类通过一个简单的外部接口与外界发生关系,
程序流程由用户在使用中决定
理解面向对象
面向对象是相对面对过程而言
面向对象和面向过程都是一种思想
面向过程
强调的是功能行为
关注的是解决问题需要哪些步骤
面向对象
将功能封装进对象,强调具备了功能的对象
关系的是解决问题需要哪些对象
面向对象是基于面向过程的
面向对象的特点
是一种符号人们思考习惯的思想
可以将复杂的事情简单化
将程序员从执行者转换成了指挥者
完成需求时
先要去找具有所需的功能的对象来用
如果该对象不存在,那么创建一个具有所需功能的对象
类与对象的关系
使用计算机语言就是在不断的在描述现实生活中的事物
Python中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义
对象即使该类事物实实在在存在的个体
类的定义
生活中描述事物无非就是描述事物的名称/属性/行为
python中用类来描述事物也是如此
属性: 对应类中的成员变量
行为: 对应类中的成员方法
定义类其实在定义类中的成员(成员变量和成员方法)
拥有相同(或者类似)属性和行为的对象都可以
类的设计
只关心3样东西
事物名称(类名) : 人(Person)
属性: 身高(height) 、年龄(age)
行为(功能): 跑(run) 、打架(fight)
创建类
设计类
类名:见名知意,首字母大写,其他遵循驼峰原则
属性:见名知意,其他遵循驼峰原则
行为(方法/功能):见名知意,其他遵循驼峰原则
创建类
类: 一种数据类型,本身并不占内存空间,跟所学过的number,string,boolean等类似。用类创建实例化对象(变量),对象占内存空间
格式:
class 类名(父类列表):
属性
行为
定义一个简单的类
object: 基类,超类,所有类的父类,一般没有合适的父类就写object
class Person(object):
#定义属性(定义变量)
name = ""
age = 0
height = 0
weight = 0
#定义方法(定义函数)
#注意: 方法的参数必须以self当第一个参数
#self 代表类的实例(某个对象)
def run(self):
print("run")
def eat(self,food):
print("eat" + food)
def openDoor(self):
print("我已经打开了冰箱门")
def fillEle(self):
print(“我已经把大象装进冰箱了”)
def colseDoor(self):
print("我已经关闭了冰箱门")
def __ init__(self,name,age,height,weight)
self.name = name
self.age = age
self.age = height
self.age = weight
self代表当前类创造的对象,然后把当前类创造的对象的属性值给修改了
def __ del__(self):
print("这里是析构函数")
使用类实列化对象
实列化对象
格式: 对象名 = 类名(参数列表)
注意: 没有参数,小括号也不能省略
per1 = Person()
per2 = Person()
per1和per2没有一点关系,仅仅类型相同
访问对象的属性与方法
访问属性
格式: 对象名.属性名
赋值: 对象名.属性名 = 新值
per.name = "xiaoxin"
per.age = 18
per.height = 160
per. weight = 42
访问方法
格式: 对象名.方法名(参数列表)
per.openDoor()
per.fillEle()
per.closeDoor()
per.eat("apple")
问题: 目前来看Person创建的所有对象属性都是一样的
对象的初始状态(构造函数)
构造函数:
__ init__() 在使用类创建对象的时候自动调用
注意: 如果不显示的写出构造函数,默认会自动添加一个空的构造函数
per = Person("xiaoxin","18","160","140") __ init __函数里面的参数列表(形参)接受的值,是在构造对象的时候给Person的小括号传的值
以后我们就在__ init __里面定义属性了,这样我们创建出来的人就不一样了
self
self代表类的实例,而非类
哪个对象调用方法,那么该方法中的self就代表哪个对象(self就等价于per)
self.__ class__ 代表类名
#self不是关键字,换成其他的标识符也是可以的,但是帅的人都是用self
析构函数
__ del __() 释放对象时自动调用
per =Person()
del per 释放对象
对象释放以后就不能再访问了
在函数里定义的对象,会在结束时自动释放,这样可以用来减少内存空间的浪费
重写 __ repr __ 与__ str__函数
重写 :将函数重写定义写一遍
__ repr__()
给机器用的,在python解释器里面直接敲对面名在回车后调用的方法
__ str__()
在调用print打印对象时自动调用,给用户用的,是一个描述对象的方法
注意:在没有__ str __ 时 ,且有 __ repr __ , __ str__ = __ repr__
优点: 当一个对象的属性值很多,并且都需要打印,重写了 __ str __ 方法后,简化了代码
访问限制
如果 要让内部的属性不被外部直接访问,在属性前加两个下划线( __ ),在python中如果在属性前加两个下划线,那么这个属性就变成了私有属性
外部不能使用,在类的内部可以使用,我们可以通过类的内部的方法,去修改私有属性
所以我们可以在类的内部定义两个函数,一个赋值,一个取值
可以通过类的内部自定义的方法实现对私有属性的赋值与取值
外部不能直接访问per.__ money 是因为Python 解释器把 _Person __ money,但是仍然可以用 _ Person __money 去访问,但是强烈建议不要这么干(帅的人都不这么干),不同的解释器可能存在解释的变量名不一致
在Python中 __ XXX__属于特殊变量,可以直接访问
在Python中 _XXX 变量, 这样的实例变量外部是可以访问的,但是,按照约定的规则,当我们看到这样的变量时,意思是"虽然我可以被访问,但是请把我视为私有变量,不要直接访问我"
继承
有两个类,A类和B类,当我们说A类继承自B类的时候,那么A类就拥有B类中的所有的属性和方法
object类是所有类的父类,还可以称为基类或超类
注意:继承者称为子类,被继承者称为父类
继承的作用
优点
简化了代码,减少冗余
提高了代码健壮性
提高了代码的安全性
是多态的前提
缺点:
耦合与内聚是描述类与类之间的关系的。耦合性越低,内聚性越高,代码越好
单继承的实现
详细见代码
多继承的实现
在子类中调用父类的初始化方法格式就是: 父类名. init(self)
super().__ init __ (父类中的属性)相对于类名 . __ init__,在单继承上用法基本无差
多态
一种事物的多种形态
最终目标:人可以喂任何一种动物
对象属性与类属性
class Person(object)
#这里的属性实际上属于类属性(用类名来调用)
name = “person”
def __ init __(self,name)
#对象属性
self.name = name
Person.name # 可以这样调用 输出person
per = Person("tom")
#对象属性的优先级高于类属性
per.name 输出tom
#动态的给对象添加对象属性
per.age = 18 #只针对于当前对象生效,对于类创建的其他对象没有作用
Person.name 输出person
per2 = Person("lilei")
per2.age #没有age属性
.
del per.name #删除对象中的那么属性,在调用会使用到同名的类属性
注意:以后千万不要将对象属性与类属性重名,因为对象属性会屏蔽掉类属性。但是当删除对象属性后,在使用又能使用类属性了
动态给实例添加属性和方法并使用 __ slots__
#创建一个空类
class Person(object):
__ slots__("name","age") #现在只能给Person对象添加这两个属性
per = Person()
#动态添加属性,这体现了动态语言的特点(灵活)
per.name = "tom"
#动态添加方法
引入模块 from types import MethodType
def say(self):
print("my name is " + self.name)
per.speak = MethodType(say,per) #将say函数 添加给per对象里面的speak
per.speak() #调用方法
如果我们想要限制实例的属性怎么办?
比如,只允许给对象添加,name,age,height,weight属性
解决:定义类的时候,定义一个特殊的属性(__ slots __), 可以限制动态添加的属性
比如在定义类的时候 写
__ slots__("name","age") #现在只能给Person对象添加这两个属性
@property方法的使用
class Person(object)
def __ init __(self,age)
#属性直接对外暴露
#self.age = age
#限制访问
self__ age = age
#方法名为受限制的变量去掉双下划线
@property
def age(self):
return self.__age
@age.setter #去掉下划线.setter
def age(self,age)
if age <0 :
age = 0
self.__age = age
‘’‘
def getAge(self):
return self.__age
def setAge = (self,age)
if age<0:
age = 0
self.__age = age
‘’‘’
per = Person(18)
属性直接对外暴露,不安全,没有数据的过滤
per.age = -10
使用限制访问,需要自己写set和get方法才能访问
per.setAge(15)
per.getAge() 输出15
per.age = 100 # 相当于调用setAge
per.age 就输出100 #相当于调用 getAge
@property 可以让你对受限制访问的属性使用点语法
运算符重载
不同的类型用加法会有不同的解释
class Person(object)
def __ init__(self,num):
self.num = num
def __ add __(self,other):
return Person(self.num + other.num)
def __ str__(self):
return "num = " + str(self.num)
per1 = Person(1)
per2 = Person(2)
print(per1+per2) 输出3 per1+per2 === per1. __ add __(per2)
标签:描述 基本结构 习惯 属性重名 私有 显示 函数 需求 ret
原文地址:https://www.cnblogs.com/fengzi759/p/12001173.html