面向对象

Posted fengzi759

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象相关的知识,希望对你有一定的参考价值。

  1. 什么是面向过程

    • 自上而下顺序执行,逐步求精

    • 其程序结构是按功能划分为若干个基本模块,这些就是树状结构

    • 各模块之间的关系尽可能简单,在功能上相对独立

    • 每一模块内部均是由顺序、选择和循环三种基本结构

    • 其模块化实现的具体方法是使用子程序

    • 程序流程在写程序时就决定了

  2. 什么是面向对象

    • 把数据及对数据的操作方法放在一起,作为一个相互依赖的整体——对象

    • 对同类对象抽象出其共性,形成类

    • 类中的大多数数据,只能用本类的方法进行处理

    • 类通过一个简单的外部接口与外界发生关系,

    • 程序流程由用户在使用中决定

  3. 理解面向对象

    • 面向对象是相对面对过程而言

    • 面向对象和面向过程都是一种思想

    • 面向过程

      • 强调的是功能行为

      • 关注的是解决问题需要哪些步骤

    • 面向对象

      • 将功能封装进对象,强调具备了功能的对象

      • 关系的是解决问题需要哪些对象

    • 面向对象是基于面向过程的

  4. 面向对象的特点

    • 是一种符号人们思考习惯的思想

    • 可以将复杂的事情简单化

    • 程序员从执行者转换成了指挥者

    • 完成需求时

      • 先要去找具有所需的功能的对象来用

      • 如果该对象不存在,那么创建一个具有所需功能的对象

  5. 类与对象的关系

    • 使用计算机语言就是在不断的在描述现实生活中的事物

    • Python中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义

    • 对象即使该类事物实实在在存在的个体

  6. 类的定义

    • 生活中描述事物无非就是描述事物的名称/属性/行为

    • python中用类来描述事物也是如此

      • 属性: 对应类中的成员变量

      • 行为: 对应类中的成员方法

    • 定义类其实在定义类中的成员(成员变量和成员方法)

    • 拥有相同(或者类似)属性和行为的对象都可以

  7. 类的设计

    • 只关心3样东西

      • 事物名称(类名) : 人(Person)

      • 属性: 身高(height) 、年龄(age)

      • 行为(功能): 跑(run) 、打架(fight)

  8. 创建类

    • 设计类

      • 类名:见名知意,首字母大写,其他遵循驼峰原则

      • 属性:见名知意,其他遵循驼峰原则

      • 行为(方法/功能):见名知意,其他遵循驼峰原则

  • 创建类

    • 类: 一种数据类型,本身并不占内存空间,跟所学过的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)

以上是关于面向对象的主要内容,如果未能解决你的问题,请参考以下文章

224 面向对象编程介绍,面向过程与面向对象

面向对象-面向对象和面向过程的区别

面向对象分析与设计面向对象设计包括哪些内容

面向对象

面向过程面向对象及面向对象的三大特征

Python面向对象学习 1 (什么是面向对象,面向对象的应用场景)