面向对象

面向过程

一. 面向过程(一种编程思想)

  过程:解决问题的步骤,目的是将一个复杂的问题拆分成若干小问题,按步骤解决,将问题流程化。

  优点:复杂问题简单化

  缺点:由于实现流程固定,一旦中间某个步骤发生了修改,导致整体需要修改(如果增加新功能,需要全部修改)

     扩展性差,维护性差

  应用场景:不需要扩展的程序,如cmd, 记事本,操作系统内核,脚本程序

  不适应场景:扩展性高的程序,如QQ.

面向对象

一. 面向对象(oop: object oriented pargramming)

  是一种编程思想,即编写代码的方式

  实际是找一堆对象,让他们完成任务

  将程序看做一堆对象的集合,实现功能的方式就是通过对象间的交互来实现

  1. 对象: 具备某些特征与技能的结合体,是实实在在存在的物体

  2. 类: 是一个抽象的概念,不是实际存在的,是根据一些具备相同特征和技能的对象抽取得到的

    类与对象的关系:类包含了一系列相同特征和技能的对象,对象是属于某个类的实例

    类和对象的先后关系: 先有对象,根据对象的特征和技能得到一个类型

  程序中:先有类,通过类产生对象。先确定类具备什么特征和行为才能产生对象

  3.面向对象优点:不用考虑繁琐的实现步骤

          扩展性高,当需要一个新功能时,搞一个具备新功能的对象,命令该对象去完成任务

          对象与整体实现流程的耦合度低(当一个对象出现问题,其他对象无影响)

          可维护性高

  4.面向对象缺点:面向对象的复杂性比面向 过程高

          无法预测执行结果

  5. 使用场景: 需要较高扩展性的程序(例如直接与用户发生交互的程序)

         因为程序与用户打交道,用户需求千变万化,对扩展性要求高

   6. 定义类: 大驼峰(首字母全部大写), 在类中描述对象的特征和行为

   class Person:   ====> 定义Person类

    name='egon'     ======> 用变量来描述特征

    gender='women'                                                                     创建对象: 申请内存地址,将对象内容放进去                                                  

    age=20                                                                                    name, gender, age 声明在类中,每个对象使用都是一样的内容

   obj1 = Person()   =====>  调用类(实例化,创建对象)

   print( obj )   ===>  <__main__.Person object at 0x00000000021DE518>  在类Person 下生成一个对象,内存地址为 0x00000000021DE518

   使用对象的属性(用对象名加点访问): obj.name      obj.gender    obj.age

  定制属性:     obj1.name = 'alex'     print( obj1.name)   ====> alex

   存放属性的位置:(共同特征)放在类 中

             独有特征(如姓名)放在对象中

  obj.__dict__获取对象中包含的内容   print(obj1.__dict__)   ====>  {'name': 'alex'}

  Person.__dict__  获得类中包含的内容  ===》 

  {'__module__': '__main__', 'name': 'ego', 'gender': 'women', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

  类自带一些属性,从父类中得到的

  属性的访问顺序: 对象  ===>   类

          当对象中存在属性,优先访问对象中的属性,当对象不存在时,在类中找

  类: 可以总结为 === >   对象的模板(类如果相同, 具备类中的公共内容)

  初始化函数: 简化为每个对象设置值,定义一个函数,用于为对象设置属性

# 初始化函数( 为对象初始化自己独有的特征)
class Student:
  school='oldboy'
  def set_sttr(obj,name,sex,age):
    obj.name=name
    obj.sex=sex
    obj.age=age
stu1= Student() # 调用类,实例化
Student.set_sttr( stu1, 'egon', 'women', 17 )

set_sttr 这个函数的目的在于设置对象的属性,如果没有对象,则该函数没有意义,因此初始化函数和类应该是一个整体

  上述方法缺点: 对象的创建和初始化分开

  解决方法: 带有__开头_结尾的函数,特殊的内置函数,会自动触发执行

class Person:
  country = 'China'
  def __init__(obj,x,y,z):
    obj.name = x
    obj.age = y
    obj.sex = z
  def run(self):
    print('---->', self)
obj1=Person('egon', 18, 'male') # obj1 相当于__init__函数中的obj
print(obj1) ----> <__main__.People object at 0x0000000001EB6048> 创建了一个对象
print(obj1.run) --> <bound method People.run of <__main__.People object at 0x0000000001E5EF98>>
             绑定方法,本质是People类中的run函数,把这个函数绑给了内存地址

obj1.run == People.run(obj1) -----> <__main__.People object at 0x0000000002236048>

print(People.run) ---> <function People.run at 0x000000000239F268> 就是一个函数

__init__函数在调用类时候自动执行
总结: 将对象的创建和初始化合并,简化操作

__init__方法 : 该方法内可以有任意的python代码

        一定不能有返回值

 类定义中的函数分成两大类: 

什么是绑定: 在没学习类之前,数据和调用数据的函数时分离的,每次调用函数都要传入一堆参数

       绑定就是将数据与操作数据的函数绑定到一起

如何绑定: 对象

绑定方法:(绑定给谁,谁来调用就自动将他本身(stu1)当做第一个参数传入)

  1. 绑定给对象的方法: 默认

    为对象量身定制

    对象.boud_method() 自动将对象当做第一个参数传入

#绑定给对象的方法:
class Student:
  school = 'beijing'
  def __init__(self,name,age):
    self.name = name
    self.age = age
  def sayhi(self):
    print(' hello my name is %s, my age is %s' %(name,age))

stu1 = Student('egon',18) 创建对象,和初始化(为对象设置属性) 此后可以获得 stu1.name 或 stu1.age
stu1.sayhi() 用对象来调用类中方法,把对象传入 --- 》 hello my name is egon my age:18
Student.sayhi(stu1) 用类名来调用,手动传入对象

总结: 只要拿到了对象,就同时拿到了数据和处理方法!!

  

# 绑定给类的方法
class Student:
  school = 'beijing'
  def __init__(self, name, age):
    self.name = name
    self.age = age
  @classmethon 装饰器classmethod 声明绑定给类
  # 有一个参数,该参数表示当前类 cls
  def print_school( cls): 输出类里面school的属性
    print(cls.school)
注意 : 类的绑定方法,对象和类都能调用,并且都会自动传入这个类

Student.print_school() # 类调用,不需要手动传参,自动传入 cls

stu1 = Student('egon', 18) # 对象调用要先创建对象和初始化
stu1.print_school() # 通过对象来调用,无需手动传参,自动传入cls

 判断一个方法(类中的函数)到底应该绑定给对象还是类 ???   

    当处理的数据包含在类中,就绑定给类

    当处理的数据包含在对象中,就绑定给对象

总结:1. 为什么绑定:传递参数,必须手动传递,还要注意传参顺序

          每次处理数据,都需要手动传参

          当处理的数据特别多,列表存放变量,当每次处理,都需先获取数据,在传递给函数

    绑定为了简化代码,提高效率

   2. 类的绑定方法和对象的绑定方法的相同和不同点:

    相同: 都会自动传值

        都可以被类和对象调用

    不同点:对象绑定方法在  对象调用时,传的是对象自己,而类绑定方法传的是类自己

        第一个参数,对象叫self , 类叫cls

非绑定方法:
  在类中,既不绑定给类,也不绑定给对象
  特点: 没有自动传参数的效果,类和对象都能调用,就是一个普通函数
  使用场景: 当功能不需要访问类的数据,也不需要访问对象的数据
# 非绑定方法
class Teacher():
  def __init__(self,name,age):
    self.name = name
    self.age = age

  @staticmethod 声明定义非绑定方法
  def test_func(num):
    print('test_func run!') # 既没有用到类的数据,也没用到对象的数据
    print(num)

# 调用
类调用: Teacher.test_func(1)
 对象调用: test1 = Teacher('egon',18)
       test1.test_func(1)

 绑定方法总结:

绑定: 是将数据和类下面定义的函数绑定

绑定方法: 绑定给类(默认): 调用方法:通过类调用 和 通过 对象调用

      绑定给对象(@classmethod 声明): 调用方法: 通过类调用和对象调用(自动传参)

非绑定方法:既不绑给类,也不绑给对象,调用方法: 通过类调用和通过对象调用

所有函数的调用都可以通过类调用和对象调用

通过对象调用时: 第一步 要创建对象和初始化  , 第二步调用(注意: 当绑定给对象时,通过对象调用要手动传参)



 

  

  

原文地址:https://www.cnblogs.com/Afrafre/p/10113577.html