27、面向对象

一、面向对象的介绍

1.1、面向对象以及面向过程的对比

1.1.1、面向过程:

  核心:过程

  目的:将程序流程化,按照步骤依次进行
1.1.2、面向对象:

  核心:对象

  目的:将程序整合,对象相当于容器,用来盛放数据和功能

1.1.3、面向类:

  核心:类(同类)
  目的:将程序整合,类也是容器,用来盛放同类对象相同的数据和功能,可以算是对象中的一种

1.1.4、面向对象的特点

  程序=数据+功能,即变量+函数。Python就是一种基于面向对象的语言,使其组合在一起。

  面向对象可以有效的提高程序的可延展性

1.2、对象的组合

1.2.1、对象不传值

def tell_stu_info(stu_obj):
    print('学生信息:名字:%s 年龄:%s 性别:%s' %(
        stu_obj['stu_name'],
        stu_obj['stu_age'],
        stu_obj['stu_gender']
    ))

1.2.2、对象传值

def set_info(stu_obj,x,y,z):
    stu_obj['stu_name']=x
    stu_obj['stu_age']=y
    stu_obj['stu_gender']=z

1.2.3、函数内套对象

stu_obj={
    'stu_school':'oldboy',
    'stu_name':'egon',
    'stu_age':18,
    'stu_gender':'male',
    'tell_stu_info': tell_stu_info,
    'set_info':set_info

二、实现面向对象的编程

2.1、先定义类

  类是相似的数据与功能的集合体

  所以类体中最常见的是变量以及函数,但类体也是可以包含其他任意代码的

  注意:类体代码是在定义时就会直接执行的,并且产生名称空间

2.2、类体的表达

class Student:     #先定义类体  class 类体名开头要大写
    # 1、变量的定义    
    stu_school='oldboy'

    # 2、功能的定义
    def tell_stu_info(stu_obj):
        print('学生信息:名字:%s 年龄:%s 性别:%s' %(
            stu_obj['stu_name'],
            stu_obj['stu_age'],
            stu_obj['stu_gender']
        ))

    def set_info(stu_obj,x,y,z):       #建立空对象
        stu_obj['stu_name']=x
        stu_obj['stu_age']=y
        stu_obj['stu_gender']=z

    # print('========>')      #类体在定义时直接执行

# print(Student.__dict__)      #查看类体在定义时的地址

2.3、属性访问的语法

  访问类体中属性的语法,需要分别访问数据以及功能的,他们的访问方式是不一样的

2.3.1、访问数据的语法        类体名.变量名

print(Student.stu_school) # Student.__dict__['stu_school']

2.3.2、访问功能的语法         类体名.函数名

# print(Student.set_info) # Student.__dict__['set_info']

2.4、调用类。也叫实例化对象,赋值给对象       赋值于变量名=类体( )

stu1_obj=Student()
stu2_obj=Student()
stu3_obj=Student()

2.5、为对象定制自己独有的属性

  会出现以下两个问题:

  1.代码重复

  2.属性的查找顺序

j.stu_name='egon'   # stu1_obj.__dict__['stu_name']='egon'
stu1_obj.stu_age=18        # stu1_obj.__dict__['stu_age']=18
stu1_obj.stu_gender='male' #  stu1_obj.__dict__['stu_gender']='male'
# print(stu1_obj.__dict__)     # 第一组数据

stu2_obj.stu_name='lili'
stu2_obj.stu_age=19
stu2_obj.stu_gender='female'
# print(stu2_obj.__dict__)      #第二组数据

stu3_obj.stu_name='jack'
stu3_obj.stu_age=20
stu3_obj.stu_gender='male'
# print(stu2_obj.__dict__)       #第三组数据

  解决问题一:

def init(obj,x,y,z):
    obj.stu_name=x
    obj.stu_age=y
    obj.stu_gender=z     #将一样的变量名进行赋值变量

init(stu1_obj,'egon',18,'male')
init(stu2_obj,'lili',19,'female')
init(stu2_obj,'jack',20,'male')            #再分别将变量进行赋值

  解决问题二:

# 一:先定义类
class Student:                                           #先建立类体
    # 1、变量的定义
    stu_school='oldboy'                               #设置变量

    # 空对象,'egon',18,'male'
    def __init__(obj,x,y,z):                        #设定共有的变量名,名称空间,即建立空对象
        obj.stu_name=x # 空对象.stu_name='egon'
        obj.stu_age=y  # 空对象.stu_age=18
        obj.stu_gender=z # 空对象.stu_gender='male'
        # return None

    # 2、功能的定义
    def tell_stu_info(stu_obj):                          #设定共有的输出格式      
        print('学生信息:名字:%s 年龄:%s 性别:%s' %(
            stu_obj['stu_name'],
            stu_obj['stu_age'],
            stu_obj['stu_gender']
        ))


# 二:再调用类产生对象                                #实例化对象,即给空对象赋值 stu1_obj=Student('egon',18,'male') # Student.__init__(空对象,'egon',18,'male')
# stu2_obj=Student('lili',19,'female')
# stu3_obj=Student('jack',20,'male')

2.6、实例化时发生的事

  1.先产生一个空对象

  2.python会自动调用类中的__init__方法然将空对象已经调用类时括号内传入的参数一同传给__init__方法

  3.返回初始完的对象

2.7、制定空对象时,__init__的使用方法

  1.会在调用类的时候自动触发,用来为对象初始化自己独有的数据
  2.__init__内存放的是为对象初始化属性的功能,也可以存放其他的代码,想要在调用时立即执行的代码都可以放到里面

  3.__init__方法必须返回None

三、属性查找

3.1、类中存放的是对象共有的数据与功能

3.1.1、类可以访问类的数据属性       类体名.变量名

print(Student.stu_school)

3.1.2、类可以访问类的功能属性         类体名.函数名

print(Student.set_info) # Student.__dict__['set_info'] 

3.2、类的数据属性

  由于类的数据属性都是共用的,所以访问的地址都是一样的

print(id(Student.stu_school))

print(id(stu1_obj.stu_school))
print(id(stu2_obj.stu_school))
print(id(stu3_obj.stu_school))     # id都一样

3.3、类的功能属性

  类的函数功能主要是给对象使用的,并且是绑定给对象,虽然大家访问到的属性的地址是相同的功能,但绑定到不同的对象就是不同的方法,内存地址各不相同。

  这就涉及到对象属性访问顺序了。

  如果对象有这个属性即用对象自己的,如果对象没有就从类里面找,找到就用找不到就报错。

  如果对象都没有添加其他的属性,那大家访问到的都是类中的,所以他们的id地址是相同的

  但如果某个对象偷偷添加了自己的属性,那的对象是不会变的。再次访问时,有这个属性的对象就用自己的,没有就用类的。

# 绑定方法的特殊之处在于:谁来调用绑定方法就会将谁当做第一个参数自动传入
# print(Student.tell_stu_info)
# print(stu1_obj.tell_stu_info)
# print(stu2_obj.tell_stu_info)
# print(stu3_obj.tell_stu_info)
原文地址:https://www.cnblogs.com/jingpeng/p/12656238.html