20181213(面向对象编程,初步)

Posted realadmin

tags:

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

 

一、面向过程与面向对象的编程

1、面向过程的编程:将复杂问题拆分成若干小问题,按照步骤流程一一解决。也可以说是将复杂问题流程化,为其制定一个固定的实现流程。

优点:复杂问题简单化

缺点:可拓展性差,维护性差。一旦某一步骤出现问题,后续步骤可能无法进行。

应用场景:对扩展性要求较低的软件,如系统内核、脚本程序。

2、面向对象的编程:OOP(Object Oriented Programming)。将程序看作是一堆对象的集合,通过对象之间交互来实现功能。面向对象编程的本质就是使用不同的对象来完成程序。

优点:不用考虑实现步骤,从具体的执行者变成指挥者。扩展性高,对象与整体流程耦合度低;对象与对象之间的耦合度也低。可维护性高。

缺点:相比面向过程,更为复杂,无法预知执行结果。

应用场景:需要较高的扩展性(直接面向消费级用户的程序)。 ? 对于不需要扩展性的程序,使用面向对象的编程思维反而会使问题复杂。

 

二、类与对象

面向对象思想中最核心的概念就是 类与对象:

对象:一切皆对象,对象指的是具备某些特征与技能的结合体,是具体的物体(如我的手机)。对象本质上就是一种存放数据的容器。

类:类就是类型、类别、分类。类是一个抽象概念,是一些具备相同特征和技能对象的集合体。

类与对象的关系:

类的作用是表示对象与对象之间的相同点,通过类就能大致了解一个对象的特征。

对象是属于某个类的实例。

 

在现实世界,先有对象,后有类。

在程序中,先有类,后有对象。

 

类名要按照大驼峰的方式来书写,例如 ThisIsPerson 每个单词首字母都大写。在类中描述对象的特征和行为。

class Person:  # 此处没有括号
   # 用变量来描述共同特征
   name = "alex"
   sex = "man"
   age = 22
?
# 得到对象,通过调用类得到对象,也称之为实例化 或 创建对象
obj = Person()
print(obj)
输出结果为:
<__main__.Person object at 0x00000202FF209400>  #Person类下的一个对象,内存地址是0x00000202FF209400
?
# 使用对象的属性(也就是特征)
print(obj.name)
print(obj.sex)
print(obj.age)
输出结果为:
alex
man
22
?

类中的增删查改:

class Person:  
   name = "alex"
   
print(Person.name) # 查
Person.name = "egon" # 改
print(Person.name)
Person.age = 22 # 增
print(Person.age)
del Person.name  #删
?
只要对类的属性进行了修改,就会立刻反映给所有对象,而对象却无需修改。

 

每个对象的内存地址都是不同的,在创建对象时,计算机会申请一个新的内存空间,并将对象中的内容存进去

存储属性的位置有两个,分别是类中和对象中. 当每个对象的某个特征都相同时则放到类中. 当每个对象的某个特征都不同时则放到对象中.

#通过__dict__可以获取一个对象中包含的内容
print(obj.__dict__)
# 获取类中包含的内容
print(Student.__dict__)
?
当对象中不存在时,会到类中去寻找,类中没有,就去父类中查找。
如果对象中存在这个属性,优先访问对象中的属性
属性查找顺序:对象---->

 

当创建一个类的时候,会产生名称空间,存储类中的名称和值的绑定关系. 当创建一个对象的时候,会产生名称空间,存储对象中的名称和值的绑定关系.

类还有一个作用就是作为对象的模板, 所有属于同一个类的对象,都具备类的共同属性.

即使我们什么都不写,类中也会存在一些自带的属性,是从父类中继承的.

 

三、初始化函数

初始化函数应该与类是一个整体,应该将函数放入类中。 通常对象一旦创建就应该进行初始化,创建与初始化进行绑定。

初始化要用到init方法,该方法是对象产生之后才会执行,只用来为对象进行初始化操作。

class Person:
   # 初始化函数名称是固定的,该函数会在调用类时自动执行
   # self形参必须有,但会自动获取,无需实参。self名称可自定义,但不建议修改,毕竟约定俗成。
   def __init__(self,name,age):
       print("执行了__init__")
       print(self)  # self就是要进行初始化的对象,系统会自动传值
       self.name = name
       self.age = age
?
p1 = Person("alex",33)  #从类Person中获取一个名叫p1的对象,对应的参数是"alex",33
print(p1.__dict__)  #结果是一个字典
?
输出结果:
执行了__init__
<__main__.Person object at 0x000001DD789E9400> #类Person下一个对象的内存地址
{‘name‘: ‘alex‘, ‘age‘: 33}
?
?
__init__方法
强调:
 1、该方法内可以有任意的python代码
 2、一定不能有返回值

 

四、绑定方法

方法的定义:为了方便理解把函数称之为方法。

绑定方法:绑定方法是把对象与函数进行绑定。调用函数就变成了调用函数的方法。绑定方法就是将数据与处理数据的函数绑定在一起。

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

默认是绑定给对象的。

class Student:  #建立一个Student的类
   school = "BeiJing"  #类的共同属性是学校名叫BeiJing
?
   def __init__(self,name,sex,age): # 初始化函数,注意参数与定义的方法。
       self.name = name
       self.sex = sex
       self.age = age
?
   def sayHi(self):  #与函数的初始化同级
       print("hello my name is %s my age %s my sex %s" %(self.name,self.age,self.sex))
   # 默认情况下,在类中定义的函数都是绑定方法,共同点是都会将对象作为第一个参数self。即对象必定要有,并以参数身份传入函数中。
?
?
stu1 = Student("egon","male",22)
?
# 当用对象来调用类中的方法时,默认把对象传入方法中
# 用类名来调用时,则需要手动传入对象
stu1.sayHi()
Student.sayHi(stu1)
?
输出结果:
hello my name is egon my age 22 my sex male
hello my name is egon my age 22 my sex male
?
print(stu1.sayHi)
# 这是一个绑定方法,本质上是Student类中的sayHi函数绑定给了地址为。。。的对象
# 只要拿到对象,就同时拿到了数据和处理数据的方法
输出结果:
<bound method Student.sayHi of <__main__.Student object at 0x000002471E089B38>>

 

绑定给类的方法:

使用一个装饰器classmethod,必须有一个参数cls用来表示当前类,参数名可以自定义,但不建议修改(约定俗成,没有理由)。

class Student:
   school = "BeiJing"
?
   def __init__(self,name,sex,age):
       self.name = name
       self.sex = sex
       self.age = age
?
   @classmethod
   def print_school_name(self):
       print("学校名称为:%s" %Student.school)
?
   @classmethod  # 将此函数绑定给类,参数为cls
   def print_school(cls):
       print(cls.school)
?
stu1 = Student("kevin","male",11)
stu1.print_school()   # 调用的是加了装饰器的函数
Student.print_school()  # 没有传参,直接调用函数
输出结果为:
BeiJing
?
Student.print_school_name()
stu1.print_school_name()
输出结果为:
学校名称为:BeiJing
学校名称为:BeiJing

 

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

总结:

对象绑定方法,可以使用对象来调用,也可以使用类名来调用

在对象调用时会自动传入对象自己,类调用时不会自动传参

类的绑定方法,对象和类都能调用,并且都会自动传入这个类

类的绑定方法和对象的绑定方法的异同点
相同点:
  1.都会自动传值
  2.都可以被类和对象调用
不同点:
1.对象绑定方法在对象调用时,传的是对象自己,而类绑定方法自动传的是类自己.
2.第一个参数 一个cls 一个是self

 

五、非绑定方法

非绑定方法:即在类中的函数,既不绑定给类,也不绑定给对象。 特点:没有自动传参的效果,类和对象都能调用,就是一个普通函数。 应用场景:当你的这个功能既不需要访问类的数据,也不需要访问对象的数据,就可以作为一个非绑定方法。

 

class Teacher:
?
   def __init__(self,name,sex):
       self.name = name
       self.sex = sex
   # @staticmethod 用于定义一个非绑定方法
   @staticmethod
   def test_func(num):
       print("run %s" %num)
?
Teacher.test_func(1)
输出结果:
run 1

 

 

六、数据存取练习
import json
?
class Student:
?
   school = "beijing"
?
   def __init__(self,name,sex,age,classes):  #初始化
       self.name = name
       self.age = age
       self.sex = sex
       self.classes = classes
?
?
   def save(self):  # 默认绑定给对象的函数
       dic = {"name":self.name,"sex":self.sex,
              "age":self.age,"classes":self.classes}  # 需要自己去创建字典
       with open(self.name,"wt",encoding="utf-8") as  f:  # 文件名就是学生名
           json.dump(dic,f)  # 序列化数据
?
   @classmethod  # 类函数
   def get_obj(cls,name):  # 传入名字,调取储存的数据
       with open(name,"rt",encoding="utf-8") as  f:
           dic = json.load(f)
       obj = cls(dic["name"],dic["sex"],dic["age"],dic["classes"])
       return obj
?
?
stu1 = Student("阿尔法","man",20,"py5期")
stu2 = Student("张三","woman",20,"py5期")
?
stu1.save()
stu2.save()
?
?
stu = Student.get_obj("阿尔法")
print(stu)
print(stu.__dict__)
print(stu.name)
输出结果为:
<__main__.Student object at 0x000001CC57B10940>
{‘name‘: ‘阿尔法‘, ‘age‘: 20, ‘sex‘: ‘man‘, ‘classes‘: ‘py5期‘}
阿尔法

 

 












































































































































































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

VSCode自定义代码片段9——JS中的面向对象编程

Python面向对象_初步认识

面向对象初步

(转)面向对象编程初步

面向面试编程代码片段之GC

面向对象基础-初步介绍