-
面向对象的设计思想是抽象出Class(类),根据Class创建Instance(实例)。
-
类是一个相对抽象的概念,而实例是其具体化。例如将学生视为类,那么李华,王丽等具体的学生就是实例。
-
类由属性和方法组成,属性用来描述其特征,例如学生的姓名、成绩等;方法用来描述其拥有的动作行为,例如格式化输出学生的成绩,判断成绩的等级等
1、创建类与实例#
1.1 创建类#
-
使用class
关键字定义类,类名的首字母通常大写。
-
通过__init__
方法创建类的属性,注意第一个参数为self
-
创建类的方法时,类似之前的创建函数的方式。注意第一个参数为self
,可以调用类自身的属性self.xxx
数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class Student():
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
'格式化输出学生成绩'
print('%s: %s' % (self.name, self.score))
def get_grade(self):
'将成绩分为不同的等级'
if self.score >= 90:
return 'A'
elif self.score >= 60:
return 'B'
else:
return 'C'
|
1.2 创建实例#
- 来源同一类的不同实例的属性一般不同,但都有相同的方法
- 创建实例后,仍然可以修改实例的属性值,甚至增删属性。
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
|
#(1)注意需要提供与 __init__ 参数顺序一致的属性数据
stuA = Student("LiHua",95)
stuB = Student("WangZi",88)
#(2)查看属性值
stuA.name
stuB.score
#(3)调用方法
stuA.print_score()
## LiHua: 95
stuB.get_grade()
## 'B'
#(4)修改属性
stuA.score=100
stuA.score
#(5)增删属性
stuA.age = 17
stuA.age
## 17
del stuA.age
stuA.age
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'Student' object has no attribute 'age'
#(5)查看属性和方法
##查看所有属性与方法
dir(stuA)
# 返回列表,包含所有属性与方法名
##判断是否有某属性
hasattr(stuA, "name")
# True
##获得对象的属性值,如果没有该属性则返回默认值
getattr(stuA, "newscore", 404)
# 404
|
2、私有属性#
- 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线
__
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
|
class Student():
def __init__(self, name, score):
'双下划线设置私有变量'
self.__name = name
self.__score = score
def get_name(self):
'方法仍可以调用私有变量'
return self.__name
def set_score(self, score):
'方法仍可以修改私有变量;通过引入if语句可添加参数检查步骤'
self.__score = score
def print_score(self):
print('%s: %s' % (self.__name, self.__score))
stuA = Student("zhangsan", 66)
##(1) 无法通过正常访问对象属性的方式查看实例的私有属性
stuA.name #无法访问
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'Student' object has no attribute 'name'
stuA.__name #无法访问
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'Student' object has no attribute '__name'
##(2)但是仍可以通过方法访问、修改私有属性
stuA.get_name()
# 'zhangsan'
stuA.set_score(99)
stuA.print_score()
# zhangsan: 99
|
3、类与子类#
3.1 继承#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#(1)创建类以及类的实例
class Animal():
def __init__(self, name, age):
self.name = name
self.age = age
def run(self):
print(self.name,'is running...')
aniA = Animal("Xiaochai", 5)
aniA.run()
## Xiaochai is running...
#(2)创建子类以及子类的实例
class Dog(Animal):
def eat(self, food):
print("Look, This is a dog and it is eating",food)
##继承父类的属性
dogA = Dog("Xiaobai","3")
##继承父类的方法
dogA.run()
# Xiaobai is running...
##调用自己的方法
dogA.eat("meat")
# Look, This is a dog and it is eating meat
|
当子类新定义的方法名与从父类继承的方法名相同时,会优先调用前者。
3.2 多态#
- 定义一个class的时候,我们实际上就定义了一种数据类型。
- 可以使用
isinstance()
判断是否为某个类型
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
40
|
a = [1,2,3]
isinstance(a, list)
# True
b = 'anything'
isinstance(b, str)
#True
#(1)定义父类
class Animal():
def run(self):
print('Animal is running...')
##实例化父类
aniA = Animal()
##判断实例的类型
isinstance(aniA, Animal)
# True
#(2)定义子类
class Dog(Animal):
pass
##实例化子类
dogA = Dog()
##判断实例的类型:既属于父类,也属于子类
isinstance(dogA, Dog)
# True
isinstance(dogA, Animal)
# True
isinstance(aniA, Dog)
# False
#(3) 多态的应用之一:编写函数
##编写一个接受Animal类型的变量
def run_twice(animal):
animal.run()
animal.run()
run_twice(aniA)
run_twice(dogA)
#任何依赖父类(Animal)作为参数的函数或者方法都可以不加修改地正常运行子类(Dog),原因就在于多态。
|