Python成长记九(面向对象)
面向对象
1、定义:用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。2、类命名规则:
(1)首字母大写
(2)总是使用首字母大写单词串,如:MyClassName(不建议下划线)
3、作用:封装一系列的变量和方法小提示:一个模块里可以定义多个类,类中的方法不能自行调用执行。建议一个模块用于定义类,在另一个模块中实例化调用
例如:
class Student():
name = '小明'
age = 10
def print_file(self):print('nmae:' + self.name)
print('age:' + str(self.age))
使用:(实例化)
student = Student()
student.print_file() #调用Student类下面的方法
4.类下面的方法与普通函数的区别:
(1)类下的方法必须传入自带self参数
(2)类下的方法是需要通过对象来调用的
(3)类下面的变量是类本身的数据成员(描述类的特征)
5.类和对象
类的概念:类是现实世界或思维世界中的实体在计算机中的反应,它将数据以及这些数据上的操作封装在一起
行为:方法
特征:数据成员
对象:类的实例化
区别:类是一个模板,通过类可以产生多个对象
小提示:多个对象的地址不相同
6.构造函数
例如:
class Student():
name = '小明'
age = 10
def __init__(self): #构造函数,实例化时自动调用,初始化对象的属性
print('student')
def print_file(self):
print('nmae:' + self.name)
print('age:' + str(self.age))
student = Student()
init = student.__init__()
print('init is:',init)
print(type(init))
打印结果:
student
student
init is: None
<class 'NoneType'>
作用:让模板生成不同对象
注意:构造函数不能有返回值
7.类变量和实例变量
类变量:和类相关联的变量
实例变量:和实例相关联的变量
实例:
class Student():
name = '小明' #类变量
age = 10 #类变量
def __init__(self,name,age): #构造函数,实例化时自动调用,初始化对象的属性
self.name = name #实例变量
self.age = age #实例变量
def print_file(self):
print('nmae:' + self.name)
print('age:' + str(self.age))
student1 = Student('小雷',18)
student2 = Student('小红',20)
print(student1.name, ":", student1.age)
print(student2.name, ":", student2.age)
print(Student.name) #调用的是类变量
结果:
小雷 : 18
小红 : 20
小明
8.类与对象的变量查找顺序
问题:试图访问实例变量
class Student():
name = '小明' #类变量
age = 0 #类变量
def __init__(self,name,age): #构造函数,实例化时自动调用,初始化对象的属性
name = name #实例变量
age = age #实例变量
def print_file(self):
print('nmae:' + self.name)
print('age:' + str(self.age))
student1 = Student('小雷',18)print(student1.name)
结果:小明
__dict__:存在于对象下面的内置变量,作用是保存相关对象下面的所有变量
小提示:当尝试查找的实例变量不存在时则会查找类变量
9.self与实例方法
self:当前调用某一个方法的对象(只和对象有关与类无关),即self代表的是实例
实例方法:第一个参数固定参数self,不需传入,调用时默认传入,即实例可以调用的方法
例如:
class Student():
sum = 0
name = '小明' #类变量
age = 0 #类变量
def __init__(self,name,age): #构造函数,实例化时自动调用,初始化对象的属性
self.name = name #实例变量
self.age = age #实例变量
print(name)
print(age)
#实例方法
def study(self):
print('study english')
student1 = Student('小雷',18)
std1 = student1.study()
10.在实例方法中访问实例变量与类变量
构造函数:用于初始化类的各种特征
实例方法:用于描述类的行为
访问实例变量:
class Student():
sum = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
print(self.name) #访问实例变量
print(name) #读取的形参的name
def study(self):
print('study english')
student1 = Student('小雷',18)
std1 = student1.study()
访问类变量:
方法1:
class Student():
count = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
print(Student.count) #访问类变量
def study(self):
print('study english')
student1 = Student('小雷',18)
std1 = student1.study()
方法2:
class Student():
count = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
print(self.__class__.count) #访问类变量
def study(self):
print('study english')
student1 = Student('小雷',18)
std1 = student1.study()
11.类方法
实例:(实例方法操作类变量)
class Student():
#表示学生数量
count = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
self.__class__.count += 1
print('当前计数为:' + str(self.__class__.count)) #访问类变量
def study(self):
print('study english')
std1 = Student('小雷',18)
std2 = Student('小兰',18)
std3 = Student('小明',18)
输出结果:
当前计数为:1
当前计数为:2
当前计数为:3
(1)定义类方法(添加装饰器classmethod)
作用:操作和类相关的变量
案例:
class Student():
#表示学生数量
count = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
self.__class__.count += 1
print('当前计数为:' + str(self.__class__.count)) #访问类变量
def study(self):
print('study english')
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
std1 = Student('小雷',18)
Student.plus_count() #类方法的调用
std2 = Student('小兰',18)
Student.plus_count() #类方法的调用
std3 = Student('小明',18)
Student.plus_count() #类方法的调用
输出结果:
当前计数为:1
2
当前计数为:3
4
当前计数为:5
6
(2)实例方法和类方法的区别
实例方法:与对象相关联
类方法:与类相关联
(3)用对象调用类的方法
例1:
class Student():
#表示学生数量
count = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
self.__class__.count += 1
print('当前计数为:' + str(self.__class__.count)) #访问类变量
def study(self):
print('study english')
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
std1 = Student('小雷',18)
std1.plus_count()
输出:
当前计数为:1
2
12.静态方法(添加装饰器 @staticmethod)
特点:与实例方法和类方法相比没有自带的内置参数
案例:
class Student():
#表示学生数量
count = 0
name = '小明'
age = 0
def __init__(self,name,age):
self.name = name
self.age = age
self.__class__.count += 1
print('当前计数为:' + str(self.__class__.count)) #访问类变量
def study(self):
print('study english')
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
#定义静态方法
@staticmethod
def add(x,y):
print('This is static method')
std1 = Student('小雷',18)
std1.add(1,2) #实例调用
Student.add(1,3) #类调用
输出结果:
当前计数为:1
This is static method
This is static method
静态方法里访问类变量:
......
#定义静态方法
@staticmethod
def add(x,y):
print(Student.count) #访问类变量
print('This is static method')
......
13.成员可见性:公开和私有
要点:通过方法保护实例变量
例如:
class Student():
count = 0
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = 0
self.__class__.count += 1
#行为与特征
def do_homework(self):
self.do_english_homework()
print('homework')
def do_english_homework(self):
print('study english')
def marking(self,score):
if score < 0:
score = 0
print('分数输入错误')
if score > 100:
score =100 #假设满分为100
self.score = score
print(self.name + '分数为'+ str(self.score))
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
#定义静态方法
@staticmethod
def add(x,y):
print('This is static method')
std1 = Student('小雷',18,80)
std1.marking(-1) #通过方法改变内部变量,可做判断,起到变量保护作用
#std1.score = -1 #防止改变内部变量
(1)成员的公开和私有
表示成员或者方法的可见性:在变量前或者方法前添加双下划线(__)
防止内部方法或者内部变量被调用:
例如:
class Student():
count = 0
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = 0
self.__class__.count += 1
#行为与特征
def do_homework(self):
self.do_english_homework()
print('homework')
def do_english_homework(self):
print('study english')
def __marking(self,score):
if score < 0:
score = 0
print('分数输入错误')
if score > 100:
score =100 #假设满分为100
self.score = score
print(self.name + '分数为'+ str(self.score))
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
#定义静态方法
@staticmethod
def add(x,y):
print('This is static method')
std1 = Student('小雷',18,80)
std1.marking(-1) #无法调用,报错,同样改成双下划綫调用也报错
#std1.score = -1 #防止改变内部变量
(2)私有变量的陷阱(打印了修改的私有变量)
class Student():
count = 0
def __init__(self,name,age,score):
self.name = name
self.age = age
self.__score = 0
self.__class__.count += 1
#行为与特征
def do_homework(self):
self.do_english_homework()
print('homework')
def do_english_homework(self):print('study english')
def marking(self,score):
if score < 0:
score = 0
print('分数输入错误')
if score > 100:
score =100 #假设满分为100
self.__score = score
print(self.name + '分数为'+ str(self.__score))
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
#定义静态方法
@staticmethod
def add(x,y):
print('This is static method')
std1 = Student('小雷',18,80)
std1.__score = -2 #动态语言特性,添加了新的实例变量
print(std1.__score)
输出:-2
陷阱:难道私有变量被改变了?
(3)解释陷阱
例如:class Student():
count = 0
def __init__(self,name,age,score):
self.name = name
self.age = age
self.__score = 0
self.__class__.count += 1
#行为与特征
def do_homework(self):
self.do_english_homework()
print('homework')
def do_english_homework(self):
print('study english')
def marking(self,score):
if score < 0:
score = 0
print('分数输入错误')
if score > 100:
score =100 #假设满分为100
self.__score = score
print(self.name + '分数为'+ str(self.__score))
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
#定义静态方法
@staticmethod
def add(x,y):
print('This is static method')
std1 = Student('小雷',18,80)
std2 = Student('小红',20,80)
std1.__score = -2 #动态语言特性,添加了新的实例变量
print(std1.__score)
print(std2.__score) #报错
结论:动态语言特性,添加了新的实例变量
(3)进一步解释(打印内置变量__dict__)
例如:
class Student():
count = 0
def __init__(self,name,age,score):
self.name = name
self.age = age
self.__score = 0
self.__class__.count += 1
#行为与特征
def do_homework(self):
self.do_english_homework()
print('homework')
def do_english_homework(self):
print('study english')
def marking(self,score):
if score < 0:
score = 0
print('分数输入错误')
if score > 100:
score =100 #假设满分为100
self.__score = score
print(self.name + '分数为'+ str(self.__score))
#定义类方法
@classmethod
def plus_count(cls):
cls.count += 1
print(cls.count)
#定义静态方法
@staticmethod
def add(x,y):
print('This is static method')
std1 = Student('小雷',18,80)
std2 = Student('小红',20,80)
std1.__score = -2 #动态语言特性,添加了新的实例变量
print(std1.__dict__)
print(std2.__dict__)
输出:
{'_Student__score': 0, 'age': 18, 'name': '小雷', '__score': -2}
{'name': '小红', 'age': 20, '_Student__score': 0}
(4)读取私有变量
通过 实例对象._Student__score访问私有变量
14.继承(python可多继承)
(1)创建父类parent.py
例如:
class Human():
count = 0
def __init__(self,name,age):
self.nane = name
self.age = age
def get_name(self):
print(self.get_name)
(2)创建子类main.py
例如:
from parent import Human
class Student(Human):
def __init__(self,school,name,age):
self.school = school
Human.__init__(self,name,age) #子类调用父类的构造函数
#行为与特征
def do_homework(self):
self.do_english_homework()
print('homework')
std1 =Student('某某中学','小明',80)
print(std1.nane)
print(std1.age)
15.子类方法调用父类方法,super关键字
(1)不推荐的调用方式(1.父类修改 2.多个函数调用实例方法)
例如:
from parent import Human
class Student(Human):
def __init__(self,school,name,age):
self.school = school
Human.__init__(self,name,age) #子类调用父类的构造函数 ---不推荐
#行为与特征
def do_homework(self):
print('homework')
std1 =Student('某某中学','小明',80)
Student.do_homework(std1) #父类调用子类实例方法
print(std1.nane)
print(std1.age)
(2)使用super关键字
例如:
from parent import Human
class Student(Human):
def __init__(self,school,name,age):
self.school = school
#Human.__init__(self,name,age) #子类调用父类的构造函数 ---不推荐
super(Student,self).__init__(name,age)
#行为与特征
def do_homework(self):
print('homework')
std1 =Student('某某中学','小明',80)
Student.do_homework(std1) #父类调用子类实例方法
print(std1.nane)
print(std1.age)
(3)父类方法和子类方法同名的情况(优先调用子类方法)
例如:在parent.py中添加
.....
def do_homework(self):
print('父类方法')
.....
结果:调用时执行子类的方法输出:homework
(4)如果调用父类的方法
例如:
from parent import Human
class Student(Human):
def __init__(self,school,name,age):
self.school = school
#Human.__init__(self,name,age) #子类调用父类的构造函数 ---不推荐
super(Student,self).__init__(name,age)
#行为与特征
def do_homework(self):
super(Student,self).do_homework()
print('homework')
std1 =Student('某某中学','小明',80)
std1.do_homework()
输出:
std1 =Student('某某中学','小明',80)
std1.do_homework()
类的总结:见如下思维导图