Python——面向对象编程

面向对象编程

面向过程编程思想 与 面向对象的编程思想

面向过程编程思想
  • 核心 ‘过程’ 两字,过程指的是解决问题的步骤
  • 即:先干什么——>再干什么——>后干什么
  • 优点:一个复杂功能简单化、流程化
  • 缺点:可扩展性差,一动全动
面向对象的编程思想
  • 核心‘对象’两字,对象是特征(变量)与技能(函数)的结合体
  • 堪比创造世界,一切皆对象

对象是特征(变量)与技能(函数)的结合体,而类则是一系列对象相同的特征(变量)与技能(函数)的结合体。

  • 对象是具体存在的事物,而类则是一个抽象的概念
  • 站在不同的角度总结出的类与对象是不同的
  • 现实世界:先有一个个具体存在的对象,然后随着发展才会有类的概念
  • 程序中:先定义类,后调用了类来产生对象
  • 类的用途:
    • 类本质就是一个名称空间,可以对该名称空间进行增删改查
    • 调用类来产生对象
  • 类体包含 相同的特征(变量)和相同的技能(函数)
    • 类体中可以包含任意python代码
    • 类体代码会在类定义阶段立即执行,产生一个名称空间,用来将类体代码执行执行过程中产生的名字都丢进去

e.g. Case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
立信选课系统
对象1:
特征
学校 = ‘Lixin’
职业 = ‘student’
姓名 = ‘ooc’
年龄 = 22
性别 = ‘male’
技能
选课
对象2:
特征
学校 = ‘Lixin’
职业 = ‘student’
姓名 = ‘rachel’
年龄 = 18
性别 = ‘female’
技能
选课
对象3:
特征
学校 = ‘Lixin’
职业 = ‘teacher’
姓名 = ‘gu’
年龄 = 50
性别 = ‘male’
等级 = 10
技能
打分

学生类:
相似特征
学校 = ‘Lixin’
职业 = ‘学生’
相似技能
选课
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class LiXinStudent:
# 相似的特征
school = 'Lixin'
job = 'student'

def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender

# 相似的技能
def choose_course(self):
print('%s choose course' %self.name)


# 类对名称空间进行增删改查

# 查看当前名称空间
print(LiXinStudent.__dict__)
print(LiXinStudent.__dict__['school'])
# LiXinStudent.school # LiXinStudent.__dict['school']
LiXinStudent.add_element = 11111
print(LiXinStudent.__dict__) # 名称空间增加 add_element = 11111

# 调用类产生对象
stu1 = LiXinStudent('ooc', 22, 'male')
print(stu1)
# <__main__.LiXinStudent object at 0x10b774e48>
print(stu1.__dict__)
# {'name': 'ooc', 'age': 22, 'gender': 'male'}
# __init__的功能:就是在实例化时就为对象初始自己独有的特征
# 注意:不能有返回值

属性查找顺序

  • 先从对象自己的名称空间找,没有则去所属的类找,不回去全局找,所属类里找不到就报错。
  • 类中定义的变量是所有对象共享的,对象可以来用,类也可以来使用,类一旦改变自己的数据属性的值,所有的对象都能感知到。

绑定方法

类中定义的函数是类的函数属性,类可以用,类来调用就是一个普通的函数,但其实类中的定义的函数是给对象用的,而且是绑定给对象用的。

  • 类的函数:该传几个参数就传几个参数
  • 特殊之处是绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入
1
2
3
4
5
6
stu1 = LiXinStudent('ooc', 22, 'male')
print(stu1.__dict__)
# {'name': 'ooc', 'age': 22, 'sex': 'male'}
stu1 = choose_course()
# ooc choose course
# 绑定给谁就应该由谁来调用

继承

什么是继承?

在程序中继承是一种新建子类的方式,新创建的类称之为子类、派生类,被继承的类称之为父类、基类、超类。继承描述的是一种遗传关系,子类可以重用父类的属性。

为何用继承?

减少类与类之间的代码冗余的问题

如何继承

先抽象再继承

e.g. Case1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 单继承&多继承
class Parent1(object):
pass
class Parent2:
pass
class Sub1(Parent1):
pass
class Sub2(Parent1,Parent2):
pass

print(Sub1.__bases__)
# (<class '__main__.Parent1'>,)
print(Sub2.__bases__)
# (<class '__main__.Parent1'>, <class '__main__.Parent2'>)

print(Parent1.__bases__)
# (<class 'object'>,)
print(Parent2.__bases__)
# (<class 'object'>,) 在python3中你不在()中写object,也默认给你加了

# python2与python3在继承上的区别
# 新式类:但凡继承object类的子类,以及该子类的子子类,...都称之为新式类
# 经典类:没有继承object类的子类,以及该子类的子子类,...都称之为经典类

# 只有在python2中才区分新式类与经典类

e.g. Case2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 在子类派生出的新功能中如何重用父类的功能:
# 方式一:指名道姓地访问某一个类中的函数,与继承无关
class LixinPeople:
school = 'Lixin'

def __init__(self, name, age, gender):

self.name = name
self.age = age
self.gender = gender


class LixinStudent(LixinPeople):

def choose_course(self):
print('%s is choosing course' %self.name)

class LixinTeacher(LixinPeople):

def __init__(self,name,age,gender,level,salary):
LixinPeople.__init__(self,name,age,gender)

self.level = level
self.salary = salary

def score(self,stu,num):
stu.num=num # 同时把分数存到该学生的内存空间当中
print('老师%s给学生%s打分%s' %(self.name,stu.name,num))

tea = LixinTeacher('gu',50,'male',10,3000)
print(tea.__dict__)

stu1 = LixinStudent('ooc',22,'male')
print(stu1.__dict__)

stu1.choose_course()

tea.score(stu1,100)
print(stu1.__dict__)