一、课程导入
上节课我们学习了类的实例,认识了类的基本概念、创建类和对象的方法,本节课我们将更加深入的学习类相关的知识点。
二、知识回顾
# 1.实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结 # 得出来的编程方式类别,即为编程范式。 # 2. Python支持面向过程编程和面向对象编程,这两种编程范式。 # 3.把大问题分解成多个小问题或子过程,是面向过程的编程范式。 # 4.将事物分类,创建类和对象来管理程序是面向对象的编程范式。 # 5.类:具有相同特征和行为的一类事物,创建类时,类名一般大写 # 6.对象:具体的某一个事物,是根据类实例化得到的 # 7.实例化:根据类来创建对象的过程,对象有相同方法,但属性不一定相同 # 8.属性:描述某个对象有什么特征,定义属性:对象.属性名=属性值 # 9.方法:在类中定义的函数,用来做什么,定义时有一参数self,指实例本身
案例回顾:创建一个学生类,为其定义年龄、性别、年龄等属性和相对应的方法。
分析:
学生对象1 特征 school='miaoxiaocheng' name='张三' sex="男" age="12岁" 技能 学习 学生对象2 特征 school='miaoxiaocheng' name='刘二丫' sex="女" age='10岁' 技能 学习
# 创建类: class Students: # 创建类的属性,相同的特征 school="miaoxiaocheng" # 定义方法,相同的技能 def learn(self): print('is learning') # 创建类的对象 s1=Students() s2=Students() # 定义对象的属性 s1.name="张三" s1.sex="男" s1.age="12岁" s2.name="刘二丫" s2.sex="女" s2.age="10岁" # 调用方法 s1.learn() print("s1同学的姓名,性别,年龄为:",s1.name,s1.sex,s1.age) print("s2同学的姓名,性别,年龄为:",s2.name,s2.sex,s2.age)
通过观察会发现,这样写代码会有几个缺点:
1.如果想要打印多个学生的信息,要定义多个对象和属性,会拉低效率,也会出现大面积的重复代码。
2.如果修改了调用学生(如不传入s1的属性,改为传入s2),那么在函数中也要做相应的修改。
3.这个动作不是针对所有全体的,如果定义其他种类的属性,按照上述的编写,也可以调用此函数,那么怎么实现此动作只适应这一类呢?
总结:
“姓名”、“年龄”、“性别”是学生具备的属性,行为动作就是learn(),现在用另外建立类的编程方法就可以解决上述的一些问题。
# 这是一个学生类 class Students: # 创建类的属性,相同的特征 school="miaoxiaocheng" # s1,'张三',"男","12岁" def __init__(self, name, sex, age): self.name = name #s1.name="张三" self.sex = sex #s1.sex='男' self.age = age #s1.age="12岁" # 定义方法,相同的技能 def learn(self): print('%s is learning,性别:%s,年龄:%s'%(self.name,self.sex,self.age)) s1=Students('张三','男','12岁') #__init__(s1,'张三','男','12岁') s2=Students('刘二丫','女','10岁') #__init__(s2,'李四','女','10岁') s1.learn() s2.learn() # 总结__init__的功能: 是在实例化时就为对象初始自己独有的特征
三、初始化方法
# 创建类时,可以定义一个初始化的方法,叫__init__(), # 创建这个类的对象时,就会运行这个方法, # 这个方法是所有对象共用的,就像构造了一个模板, # 因此__init__()方法也叫构造函数。
1.创建初始方法
class student(): def __init__(self,name,score): self.name = name self.score = score # 创建初始化方法用def和 __init__(),在类中函数都叫方 法,__init__()是一个特殊的 方法,可以给它定义参数。
class Student: def __init__(self,name,score): self.name = name self.score = score # init方法的第一个参数是self,可以把各种属性绑定到self, # self.name中的name和init方法括号中的参数name没有任何关系, # 它们两个往往一样,是因为大家都不愿再去想一个新的, # 如果写成self.xxx = name,也是可以的。
2.显示成绩
现在要打印某个班级学生的成绩,像下面这样, 我们可以采用建立Student这个类来编写程序
Sky your score is 90 come up!
Tim your score is 100 come up!
class Student: def __init__(self,name,score): self.name = name self. score = score def info(self,c): print ("%s your score is %s %s"%(self.name,self. score,c)) Sky_score = Student("Sky","90") Tim_score = Student("Tim","100") Sky_score.info("come up") Tim_score.info("come up") # 创建实例Sky_score后,将自动调用__init__()方法, # 方法info()中的第一个参数是self,调用的时候self是自动传递的。
3.优化程序
将上节课运动员的程序运用此方法优化程序(程序设计的基本原则就是尽量少写代码)
# 创建类,类名采用驼峰体 class Player: # 定义类的属性 role="people" # 创建构造方法 def __init__(self,height,weight,age): self.height=height self.weight=weight self.age=age # 创建类的方法 def attack(self): print("出拳攻击") def defence(self): print("立刻闪躲") # 创建类对象 player1=Player("180cm","70kg","26岁") player2=Player("175cm","48kg","24岁") player1.attack() player2.defence() print("1号选手的身高,体重,年龄,分别是:",player1.height,player1.weight,player1.age) print("2号选手的身高,体重,年龄,分别是:",player2.height,player2.weight,player2.age)
4.给属性指定默认值
# 类中定义的每个属性都必须有初始值,有时也可以设置一个默认值, # 默认值可以是任意数据类型,在模拟上面的拳击游戏时, # 可以设置运动员默认所在的国家,例如“中国”。
# 创建类,类名采用驼峰体 class Player: # 定义类的属性 role="people" # 创建构造方法 def __init__(self,number,height,weight,age): self.number=number self.height=height self.weight=weight self.age=age self.country="中国" # 初始值一直是中国==》默认属性不需要在__init__()方法中设置形参 def info(self): print("%s号选手来自%s,他的身高,体重,年龄,分别是:%s%s%s"%(self.number,self.country,self.height,self.weight,self.age)) def attack(self): print("%s号出拳攻击"%self.number) def defence(self): print("%s号立刻闪躲"%self.number) # 创建类对象 player1=Player(1,"180cm","70kg","26岁") player2=Player(2,"175cm","48kg","24岁") player1.info() player2.info() player1.attack() player2.defence()
5.修改属性的值
属性值被定义也可以被修改,修改属性的值有三种方法
# 修改属性的值: # 1.直接修改属性的值 # 2.用方法修改属性的值 # 3.用方法对属性的值递增
5.1 直接修改属性的值
# 创建类,类名采用驼峰体 class Player: # 定义类的属性 role="people" # 创建构造方法 def __init__(self,number,height,weight,age): self.number=number self.height=height self.weight=weight self.age=age self.country="中国" # 初始值一直是中国 def info(self): print("%s号选手来自%s,他的身高,体重,年龄,分别是:%s%s%s"%(self.number,self.country,self.height,self.weight,self.age)) def attack(self): print("%s号出拳攻击"%self.number) def defence(self): print("%s号立刻闪躲"%self.number) # 创建类对象 player1=Player(1,"180cm","70kg","26岁") player2=Player(2,"175cm","48kg","24岁") player1.country="美国" # 访问并设置运动员的属性country player1.info() player2.info() player1.attack() player2.defence()
5.2 用方法修改属性的值
# 创建类,类名采用驼峰体 class Player: # 定义类的属性 role="people" # 创建构造方法 def __init__(self,number,height,weight,age): self.number=number self.height=height self.weight=weight self.age=age self.country="中国" # 初始值一直是中国 def update(self,a): self.country=a # 接收一个值,并存储到self.country中 def info(self): print("%s号选手来自%s,他的身高,体重,年龄,分别是:%s%s%s"%(self.number,self.country,self.height,self.weight,self.age)) def attack(self): print("%s号出拳攻击"%self.number) def defence(self): print("%s号立刻闪躲"%self.number) # 创建类对象 player1=Player(1,"180cm","70kg","26岁") player2=Player(2,"175cm","48kg","24岁") player1.update("英国") # 提供实参 player2.update("美国") player1.info() player2.info() player1.attack() player2.defence()
5.3 用方法对属性值递增
# 创建类,类名采用驼峰体 class Player: # 定义类的属性 role="people" # 创建构造方法 def __init__(self,number,height,weight,age): self.number=number self.height=height self.weight=weight self.age=age self.country="中国" # 初始值一直是中国 def update(self,a): self.country=a # 接收一个值,并存储到self.country中 def add(self,b): # 修改体重 self.weight += b def info(self): print("%s号选手来自%s,他的身高,体重,年龄,分别是:%s%s%s"%(self.number,self.country,self.height,self.weight,self.age)) def attack(self): print("%s号出拳攻击"%self.number) def defence(self): print("%s号立刻闪躲"%self.number) # 创建类对象 player1=Player(1,"180cm",70,"26岁") player2=Player(2,"175cm",60,"24岁") player1.update("英国") # 提供实参 player2.update("美国") player1.add(10) player2.add(20) player1.info() player2.info() player1.attack() player2.defence()
四、总结
# 1.面向对象重要的概念就是类和实例,类是抽象的模板, # 而实例是根据类创建出来的一个个具体的“对象”, # 每个对象都拥有相同的方法,但各自的数据可能不同。 # 2.类是我们自己构造的,它的基本结构也是我们自己手动构造的。 # 在类中,基本结构写在__init__()这个方法里面; # 故这个函数称为构造函数,担负着对类进行初始化的任务。