面向对象编程-类

day 21

一、面向对象概述

1、什么是面向对象:

1、面向过程的程序设计:

  面向过程,核心是过程,即解决问题的步骤,编写程序好比在设计一条流水线,为了得到合格的产品(程序),人为指定程序需要翔安什么再干什么。它是一种机械式的思维方式。

  优点:将复杂的问题流程化,进而简单化(将一个复杂的问题,拆分成一个个小的问题去实现,实现小的步骤就会变得比较简单。)

  缺点:可扩展性差(解决问题的指向性比较强,若需求有所变动,修改幅度较大)

  使用场景:对扩展性要求较低的软件,比如系统内核,脚本程序(运维工程师写的程序,其目的就是安装一堆软件),Apache HTTP服务器等; 当我们要开发的程序需非常高的扩展性时就不能再使用该方式了

2、面向对象的程序设计:

  面向对象:核心为对象二字,对象即特征与技能的结合体,基于面向对象的程序设计就好比在创造一个世界,而编写程序的人就相当于是这个世界的上帝,存在的一切皆为对象,不存在的也可以被创造出来,与面向过程机械的思维方式形成鲜明的对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。

  优点:a、可扩展性强(对某一个对象的单独修改,会立刻反映到整个体系中,例如在游戏中对人物参数特性和技能的修改都会变得很容易。);

       b、各个对象之间的耦合度较低,当其中一个对象出现了问题,不会对其他对象产生影响。

  缺点:a、编程的复杂程度高于面向过程;

       b、无法预知执行结果。

  使用场景:需要较高的可扩展性时使用(直接与用户发生交互的程序,如qq,微信);对不需要较高扩展性的程序而言,使用面向对象反而增加了复杂度。

2、为什么要使用面向对象:

  在开发一些需要与用户直接打交道的程序时,因用户的需求是不停的发生变化,所以我们要使用可扩展性较高的面向对象式编程(本质就是使用不同的对象来编写程序)方式来编写程序。

二、类与对象:

1、类:

  类十一个抽象的概念,类即种类、类别,是面向对象设计的重要概念,是一系列的对象的相同特征和技能的结合体。

  注:现实世界中是先有对象,再有类的概念。

    程序中是先定义类,然后在通过调用类来产生对象。

2、对象:

  对象是通过调用类来产生获得的,因此调用类的过程又称为类实例化的过程。调用类会得到一个返回值,该返回值就是类的一个具体存在的对象(实例)。

#在程序中,务必保证:先定义(类),后使用(产生对象)
PS:
  1. 在程序中特征用变量标识,技能(方法)用函数标识
  2. 因而类中最常见的无非是:变量(特征)和函数(方法)的定义
​
#程序中的类
class OldboyStudent:
    school='oldboy'
    def learn(self):
        print('is learning')
        
    def eat(self):
        print('is eating')
    
    def sleep(self):
        print('is sleeping')
​
#注意:
  1.类中可以有任意python代码,这些代码(函数体类的代码仍然存放在内存中,调用时才会执行)在类定义阶段便会执行
  2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看
  3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法
  4.点是访问属性的语法,类中定义的名字,都是类的属性
  5.类本省就是一个容器类型(名称空间),用来存放名字,这是类的用途之一。
#程序中类的用法
.:专门用来访问属性,本质操作的就是__dict__
OldboyStudent.school #等于经典类的操作OldboyStudent.__dict__['school']
OldboyStudent.school='Oldboy' #等于经典类的操作OldboyStudent.__dict__['school']='Oldboy'
OldboyStudent.x=1 #等于经典类的操作OldboyStudent.__dict__['x']=1
del OldboyStudent.x #等于经典类的操作OldboyStudent.__dict__.pop('x')
​
​
#程序中的对象
#调用类,或称为实例化,得到对象
s1=OldboyStudent()
s2=OldboyStudent()
s3=OldboyStudent()
​
#如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__
#注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值
class OldboyStudent:
    ......
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    ......
​
​
s1=OldboyStudent('李坦克','',18) #先调用类产生空对象s1,然后调用OldboyStudent.__init__(s1,'李坦克','男',18)
s2=OldboyStudent('王大炮','',38)
s3=OldboyStudent('牛榴弹','',78)
​
​
#程序中对象的用法
#执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间
s2.__dict__
{'name': '王大炮', 'age': '', 'sex': 38}
​
s2.name #s2.__dict__['name']
s2.name='王三炮' #s2.__dict__['name']='王三炮'
s2.course='python' #s2.__dict__['course']='python'
del s2.course #s2.__dict__.pop('course')

三、属性查找:

  类的两种属性分别为数据属性和函数属性

  1、类的数据属性:所有对象共享

  2、类的函数属性:绑定给对象使用

  注:属性查找的顺序:obj对象产生后自己会生成一块新的内存空间,obj需要调用属性是首先会先从自己的空间中进行查找,如果找不到就会到类的空间中去找,如果找不到就会到父类的空间中去找....最后找不到抛出异常。

#类的数据属性是所有对象共享的,id都一样
print(id(OldboyStudent.school))
print(id(s1.school))
print(id(s2.school))
print(id(s3.school))
'''
4377347328
4377347328
4377347328
4377347328
'''#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都是不一样
#ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
print(OldboyStudent.learn) #0x1021329d8
print(s1.learn)            #0x1021466d8
print(s2.learn)            #0x102146710
print(s3.learn)            #0x102146748
'''
<function OldboyStudent.learn at 0x1021329d8>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>
'''

四、类中的初始化函数

  __ init__函数用于初始化对象,它会在对象刚被创建时自动执行,并传入调用时传递的参数,第一个参数表示要初始化的对象本身。

  注:调用类时发生的两件事:

    a、创建一个空对象stu;

    b、自动触发类中的init功能的执行,并将空对象stu和调用类似括号中传入的参数一同传入。

#方式一、为对象初始化自己独有的特征
class People:
    country='China'
    x=1
    def run(self):
        print('----->', self)
​
# 实例化出三个空对象
obj1=People()
obj2=People()
obj3=People()
​
# 为对象定制自己独有的特征
obj1.name='egon'
obj1.age=18
obj1.sex='male'
​
obj2.name='lxx'
obj2.age=38
obj2.sex='female'
​
obj3.name='alex'
obj3.age=38
obj3.sex='female'# print(obj1.__dict__)
# print(obj2.__dict__)
# print(obj3.__dict__)
# print(People.__dict__)
#方式二、为对象初始化自己独有的特征
class People:
    country='China'
    x=1
    def run(self):
        print('----->', self)
​
# 实例化出三个空对象
obj1=People()
obj2=People()
obj3=People()
​
# 为对象定制自己独有的特征
def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
    obj.name = x
    obj.age = y
    obj.sex = z
​
chu_shi_hua(obj1,'egon',18,'male')
chu_shi_hua(obj2,'lxx',38,'female')
chu_shi_hua(obj3,'alex',38,'female')
​
​
​
​
​
#方式三、为对象初始化自己独有的特征
class People:
    country='China'
    x=1def chu_shi_hua(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
        obj.name = x
        obj.age = y
        obj.sex = z
​
    def run(self):
        print('----->', self)
​
​
obj1=People()
# print(People.chu_shi_hua)
People.chu_shi_hua(obj1,'egon',18,'male')
​
obj2=People()
People.chu_shi_hua(obj2,'lxx',38,'female')
​
obj3=People()
People.chu_shi_hua(obj3,'alex',38,'female')
​
​
​
​
# 方式四、为对象初始化自己独有的特征
class People:
    country='China'
    x=1def __init__(obj, x, y, z): #obj=obj1,x='egon',y=18,z='male'
        obj.name = x
        obj.age = y
        obj.sex = z
​
    def run(self):
        print('----->', self)
​
obj1=People('egon',18,'male') #People.__init__(obj1,'egon',18,'male')
obj2=People('lxx',38,'female') #People.__init__(obj2,'lxx',38,'female')
obj3=People('alex',38,'female') #People.__init__(obj3,'alex',38,'female')
​
​
# __init__方法
# 强调:
#   1、该方法内可以有任意的python代码
#   2、一定不能有返回值
class People:
    country='China'
    x=1def __init__(obj, name, age, sex): #obj=obj1,x='egon',y=18,z='male'
        # if type(name) is not str:
        #     raise TypeError('名字必须是字符串类型')
        obj.name = name
        obj.age = age
        obj.sex = sex
​
​
    def run(self):
        print('----->', self)
​
​
# obj1=People('egon',18,'male')
obj1=People(3537,18,'male')
​
# print(obj1.run)
# obj1.run() #People.run(obj1)
# print(People.run)
​
!!!__init__方法之为对象定制自己独有的特征

 

五、给对象绑定方法:

1、绑定方法:

  绑定方法即将对象与函数方法绑定到一起(通过将对象本身传入函数来进行绑定),此后调用函数就变成了调用对象的方法。

  注:当用对象来调用类中的方法时,默认会将对象传入函数方法中,

    而用类名来调用时,则需要手动传入对象。

#改写
class OldboyStudent:
    school='oldboy'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def learn(self):
        print('%s is learning' %self.name) #新增self.name
def eat(self):
        print('%s is eating' %self.name)
​
    def sleep(self):
        print('%s is sleeping' %self.name)
#注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。
​
s1=OldboyStudent('李坦克','',18)
s2=OldboyStudent('王大炮','',38)
s3=OldboyStudent('牛榴弹','',78)
​
s1.learn()
OldboyStudent.learn(s1) #效果同上
2、绑定方法分类:

  绑定方法有两种,一种是绑定给类的方法,一种是绑定给对象的方法。

  绑定给类的方法需要使用一个装饰器@classmethod,必须要有一个参数(类本身,默认为cls,可以自己定义,但是约定俗成的写成使用cls)。

class Student:
    school = "beijing"def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
​
    # 绑定方法分为两种 一种是绑定给对象的,一种绑定给类的
    # 绑定给类的方法 使用一个装饰器叫classmethod,必须有一个参数,表示当前类,参数名也可以自己定义,建议不要修改
    @classmethod
    def print_school(cls):  # 输出类里面叫school的属性
        print(cls.school)
​
    # def print_school2(self):  # 输出类里面叫school的属性
    #     print(self.school)
# 这是绑定给对象的方法
    def sayHello(self):
        print(self.name, " 说: 你好")
​
# Student.print_school_name()
# Student.print_school()

  总结:两种绑定方法的使用场景:

    a、当要处理的的数据包含在类中时,就应该绑定给类;

    b、当要处理的数据包含在对象中时,就应该绑定给对象。

3、非绑定方法:

  非绑定方法即在类中即不绑定给类,也不绑定给对象。

  特点:没有自动传参的效果,类和对象都能调用,就是一个隶属于类中的普通函数。

  应用场景:当这个功能不许要访问类中的数据,也不需要访问对象的数据时,就可以作为一个非绑定方法,应用场景较少。

import json
 class Student:
     school = "oldboy"
     def __init__(self,name,gender,age,cla):
        self.name = name
        self.gender = gender
        self.age = age
        self.cla = cla
     def save(self):
         with open("%s.json"%self.name,"wt",encoding="utf-8") as f:
             json.dump(self.__dict__,f)
     #此处既可以使用非绑定方法也可以使用绑定给类的方法:
     @staticmethod    #非绑定方法
     def get_obj(name):
         with open("%s.json"%name,"rt",encoding="utf-8") as f:
             dic = json.load(f)
             stu = Student(dic["name"],dic["gender"],dic["age"],dic["cla"])
             return stu
 # stu1 = Student("yuyu","male",18,"5")
 # stu1.save()
 stu1 = Student.get_obj("yuyu")
 print(stu1.gender)
 
原文地址:https://www.cnblogs.com/peng-zhao/p/10116052.html