目录
一、面向对象概述
1.对象
2.类
3.面向对象程序设计的特点
二、类的定义和使用
1.定义类
2.类的实例化
3.创建__init__()方法
4.创建类的成员和访问
4.1 创建实例方法并访问
4.2 创建属性成员并访问
5.访问限制
三、属性(property)
1.用于计算的属性
2.为属性添加保护机制
四、继承
1.继承的基本语法
2.方法重写
3.子类调用父类的__init__()方法
记述python中关于面向对象程序设计的使用。
面向对象(Object Oriented),简称OO;
面向对象编程(Object Oriented Programming),简称OOP。
英文为Object,表示任意示食物,与显示世界的实际事物一一对应。
对象包括:静态的属性和动态的行为。
对对象的封装。
class ClassName:
"""类的注释"""
statement
ClassName(parameterlist)
类似于C#中的构造方法,创建实例时自动运行,用来声明类的参数信息。
# 定义类
class ClassNmae:
"""ClassName"""
def __init__(self):
statement
def functionName(self,parameterlist):
block
可以通过类的实例名称和"."进行访问:
instanceName.functionName(parametersvalue)
4.2.1 类属性
在类中定义的属性,可以在所有实例化对象中使用,类的所有实例之间共享值,类似于C#中的静态属性。
# _*_ coding:utf-8 _*_
# 定义类
class ClassNmae:
"""ClassName"""
parameter1 = value1
parameter2 = value2
def __init__(self):
statement
示例:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
name = "Student"
remuneration = 10000
num = 1
def __init__(self):
print("My sn:",Work.num)
print("I'm work:",Work.name)
print("Remuneration:",Work.remuneration)
Work.num += 1
work1 = Work()
work2 = Work()
Work.year = 2022
work3 = Work()
print(work1.year)
print(work2.year)
print(work3.year)
结果:
========================== RESTART: D:\Desktop\Demo.py =========================
My sn: 1
I'm work: Student
Remuneration: 10000
My sn: 2
I'm work: Student
Remuneration: 10000
My sn: 3
I'm work: Student
Remuneration: 10000
2022
2022
2022
>>>
注意:
调用类属性时需要以"类命.属性名"的形式调用,否则会报错NameError。
4.2.2 实例属性
只定义在类方法中的属性,只作用于当前实例。
# _*_ coding:utf-8 _*_
# 定义类
class ClassNmae:
"""ClassName"""
def __init__(self):
parameter1 = value1
parameter2 = value2
statement
示例:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
def __init__(self):
self.name = "Student"
self.remuneration = 10000
self.num = 1
print("My sn:",self.num)
print("I'm work:",self.name)
print("Remuneration:",self.remuneration)
self.num += 1
work1 = Work()
work2 = Work()
work1.name = "Student1"
work1.name = "Student2"
print(work1.name)
print(work1.name)
结果:
My sn: 1
I'm work: Student
Remuneration: 10000
My sn: 1
I'm work: Student
Remuneration: 10000
Student2
Student2
python通过在方法和属性添加下划线来进行访问权限限制
标识 | 说明 | 备注 |
---|---|---|
首尾双下划线 | 定义特殊方法,一般是系统定义名字 | 如:__init__() |
单下划线开头 | protected(保护)类型 只允许本身和子类进行访问,不能使用”from module import *”导入,可以使用实例进行访问 |
如:_name = "a" |
双下划线开头 | private(私有)类型; 只允许定义该方法的类本身访问,而且也不能通过类的实例访问。 可以通过“类的实例名._类名__xxx”进行访问 |
示例:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
_name = "work"
__remuneration = 10000
def __init__(self):
print("I'm work:",Work._name)
print("Remuneration:",Work.__remuneration)
work1 = Work()
work2 = Work()
print("Work._name:",Work._name) # 访问保护变量
print("work1._name:",work1._name)
print("work2._name:",work2._name)
print("Work.__remuneration:",work1._Work__remuneration) # “实例名._类命__xxx”访问私有变量
print("Work.__remuneration:",Work.__remuneration) # 直接访问私有变量会报错
结果:
I'm work: work
Remuneration: 10000
I'm work: work
Remuneration: 10000
Work._name: work
work1._name: work
work2._name: work
Work.__remuneration: 10000
Traceback (most recent call last):
File "D:\Desktop\Demo.py", line 20, in
print("Work.__remuneration:",Work.__remuneration)
AttributeError: type object 'Work' has no attribute '__remuneration'
>>>
通过@property装饰器将一个方法转换为属性,转换为属性后可直接通过方法名访问方法,不在需要添加“()”,类似于C#中用{get;set;}访问器访问属性。
格式如下:
@property
def methodName(self):
block
示例:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
_name = "work"
__remuneration = 10000
def __init__(self):
print("I'm work:",Work._name)
print("Remuneration:",Work.__remuneration)
@property #将方法转换为属性
def name(self):
return self._name
work1 = Work()
print("Work._name:",Work._name)
print("work1.name:",work1.name)
work1.name = "new name"
结果:
I'm work: work
Remuneration: 10000
Work._name: work
work1.name: work
Traceback (most recent call last):
File "D:\Desktop\Demo.py", line 21, in
work1.name = "new name"
AttributeError: can't set attribute
>>>
转换后为只读的,进行赋值的话会直接报错。
示例1,没有添加setter标识,显示双方法:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
_name = "work"
__remuneration = 10000
def __init__(self):
print("I'm work:",Work._name)
print("Remuneration:",Work.__remuneration)
@property #将方法转换为属性
def name(self):
return self._name
def name(self,value):
self._name = value
work1 = Work()
print("Work._name:",Work._name)
print("work1.name:",work1.name)
print("work1.name:",work1.name)
print("work1.name:",work1.name)
work1.name = "work1"
print("work1.name:",work1.name)
结果:
I'm work: work
Remuneration: 10000
Work._name: work
work1.name: >
work1.name: >
work1.name: >
work1.name: work1
注意:
不适用setter标识程序不会报错,不过未使用拦截器修改时调用该属性会提示重复方法,无法获取准确值,但是当使用拦截器修改属性后,再次获取就又是正常的了。
示例2,添加setter标识后:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
_name = "work"
__remuneration = 10000
def __init__(self):
print("I'm work:",Work._name)
print("Remuneration:",Work.__remuneration)
@property #将方法转换为属性
def name(self):
return self._name
@name.setter
def name(self,value):
self._name = value
work1 = Work()
print("Work._name:",Work._name)
print("work1.name:",work1.name)
work1.name = "work1"
print("work1.name:",work1.name)
结果:
I'm work: work
Remuneration: 10000
Work._name: work
work1.name: work
work1.name: work1
添加setter之后拦截器有正常识别到,不会别错误识别。
通过继承,可以继承父类的一些属性和方法,以达到代码复用的目的,大大提高开发效率。
class ClassName(baseclasslist):
"""类的帮助信息"""
statement
示例:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
def __init__(self):
self.name = "Obj work"
self.work = "work"
print("I'm {},my work is {}.".format(self.name,self.work))
def name(self):
return self.name
class Teacher(Work):
"""Teacher class"""
def __init__(self):
self.name = "Teacher"
self.work = "to teach student"
print("I'm {},my work is {}".format(self.name,self.work))
work1 = Work()
teacher = Teacher()
print(teacher.name)
结果:
I'm Obj work,my work is work.
I'm Teacher,my work is to teach student
Teacher
>>>
与C#相似,子类若需要根据自己需要修改基类的方法,可以在子类直接重写该方法。
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
def name(self):
statement
class Teacher(Work):
"""Teacher class"""
def name(self):
new statement
子类实例化时并不会调用父类的__init__()方法,此时如果调用父类在__init__()中声明的参数,或者调用父类的方法中调用到__init__()会报错,需要在父类中调用父类的__init__()进行初始化。
super().__init__()
使用super()函数调用父类的函数。
示例1,为调用父类__init__()方法,直接报错:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
def __init__(self):
self.name = "Obj work"
self.work = "work"
print("I'm {},my work is {}.".format(self.name,self.work))
def name(self):
return self.name
class Teacher(Work):
"""Teacher class"""
def __init__(self):
print("I'm {},my work is {}".format(self.name,self.work))
self.name = "Teacher"
self.work = "to teach student"
print("I'm {},my work is {}".format(self.name,self.work))
def name(self):
return self.name
work1 = Work()
teacher = Teacher()
print(work1.name)
print(teacher.name)
结果:
I'm Obj work,my work is work.
Traceback (most recent call last):
File "D:\Desktop\Demo.py", line 29, in
teacher = Teacher()
File "D:\Desktop\Demo.py", line 19, in __init__
print("I'm {},my work is {}".format(self.name,self.work))
AttributeError: 'Teacher' object has no attribute 'work'
>>>
示例2,初始化时调用父类的__init__()函数:
# _*_ coding:utf-8 _*_
# 定义类
class Work:
"""Work class"""
def __init__(self):
self._name = "Obj work"
self._work = "work"
print("I'm {},my work is {}.".format(self._name,self._work))
def name(self):
return self._name
class Teacher(Work):
"""Teacher class"""
def __init__(self):
super().__init__()
self.name = "Teacher"
self.work = "to teach student"
print("I'm {},my work is {}".format(self.name,self.work))
def basename(self):
return super().name()
work1 = Work()
teacher = Teacher()
print(work1.name())
print(teacher.name)
print(teacher.basename())
结果:
I'm Obj work,my work is work.
I'm Obj work,my work is work.
I'm Teacher,my work is to teach student
Obj work
Teacher
Obj work
>>>