小学Python系列少儿编程课程《第7章 神秘的类和对象》课件(共52张PPT)

资源下载
  1. 二一教育资源

小学Python系列少儿编程课程《第7章 神秘的类和对象》课件(共52张PPT)

资源简介

(共52张PPT)
Python少儿编程
第七章 神秘的类和对象
目录
1.1
“小海龟”的自我介绍
1.2
“小海龟”的画布
1.3
“小海龟”的画笔
1.4
多彩的图画
1.5
多彩的图画
PART 01
面向对象的编程世界
面向对象的编程世界
1
传统的程序设计方法被称为面向过程的程序设计。面向过程程序设计的核心是过程,即解决问题的步骤。
面向对象程序设计(object oriented programming,OOP)是将所有预处理的问题抽象为对象,并将相应的属性和行为封装起来,以提高软件的重用性、灵活性和扩展性。
现实世界中,对象就是客观存在的某一事物,如一个人、一辆自行车等。而面向对象的编程世界中,对象具有属性和行为两个特征,每个对象都有各自的属性和行为。而类是对这些具有共同特征的对象的概括、归纳和抽象表达。例如,将人抽象为“人”类,它具有名字、性别等属性,行走、吃饭等行为,那么具体的名字为“小明”“小红”的个体就是“人”类的对象,具体关系如图7-1所示。
面向对象的编程世界
1
图7-1 类和对象的关系
面向对象程序设计思想是把事物的属性和行为包含在类中。其中,事物的属性作为类的变量,事物的行为作为类的方法,而对象则是类的一个实例。因此,想要创建对象,需要先定义类。
PART 02
真实事物的抽象
类的定义
2.1
Python中定义类的语法格式如下。
class 类名:
类体
其中,class是Python的关键字,用于声明类;类名必须是合法标识符,通常是一个有意义的名称;类体定义类的内部实现,一般包括变量和方法的定义。
定义类时应注意以下几点。
(1)类名的首字母一般需要大写,如Car。
(2)类名后必须紧跟冒号。
(3)类体相对于class关键字必须保持一定的空格缩进。
例如,定义一个Person类,包含姓名属性和说话行为,可以用下面代码实现。
类的定义
2.1
class Person: #定义Person类
name = '小蓝' #定义姓名变量
def speak(self): #定义说方法
print('大家好!')
在上述代码中,使用class定义了一个名为Person的类,类中有一个name变量和一个speak()方法。从代码中可以看出,方法的定义格式和函数是一样的,主要区别在于,方法必须显式地声明一个self参数,且须位于参数列表的开头。self参数将在7.2.3节中详细介绍。
创建对象
2.2
对象名 = 类名()
Python中创建对象的语法格式如下。
创建对象后,可以使用它来访问类中的变量和方法,其语法格式如下。
对象名.变量名
对象名.方法名([参数])
创建对象
2.2
【例7-1】 创建对象,访问类中的变量和方法。
【运行结果】 程序运行结果如图7-2所示。
【参考代码】
class Person: #定义Person类
name = '小蓝' #定义姓名变量
def speak(self): #定义说方法
print('大家好!')
person = Person() #创建对象
person.speak() #调用类中的方法
print('我是{}'.format(person.name)) #访问类中的变量
图7-2 例7-1程序运行结果
self参数
2.3
在Python中,一个类可以生成无数个对象,当一个对象的方法被调用时,对象会将自身的引用作为第一个参数(即方法的self参数),传递给该方法。这样,Python就知道需要操作哪个对象的方法了。
带self参数的方法也称作实例方法,在类的实例方法中访问实例变量时,须以self为前缀,但在外部通过对象名调用实例方法时不需要传递该参数。
【例7-2】 self参数的使用。
【参考代码】
class Person: #定义Person类
def named(self, name): #定义命名的方法
self.name = name #赋值
def speak(self): #定义显示名字的方法
print('我的名字是{}'.format(self.name)) #输出名字
self参数
2.3
【运行结果】 程序运行结果如图7-3所示。
【参考代码】
xiaolan = Person() #创建对象xiaolan
xiaolan.named('小蓝') #xiaolan调用named()方法
xiaowu = Person() #创建对象xiaowu
xiaowu.named('小舞') #xiaowu调用named()方法
xiaolan.speak() #xiaolan调用speak()方法
xiaowu.speak() #xiaowu调用speak()方法
图7-3 例7-2程序运行结果
构造方法
2.4
构造方法的固定名称为__init__(),当创建类的对象时,系统会自动调用构造方法,实现对象的初始化操作。
【例7-3】 构造方法示例。
【参考代码】
class Person: #定义Person类
#构造方法,定义变量并赋初值
def __init__(self):
self.name = '小蓝'
self.snack = '薯条'
def eat(self): #定义方法,输出变量
print('{}喜欢的零食是{}'.format(self.name, self.snack))
xiaolan = Person() #创建对象
xiaolan.eat() #调用eat()方法
构造方法
2.4
【运行结果】 程序运行结果如图7-4所示。
图7-4 例7-3程序运行结果
【程序说明】 在该程序中,第3~5行实现了__init__()方法,给Person类添加了name和snack属性并赋初值,在eat()方法中访问了name和snack的值。
上例中,无论创建多少个Person类的对象,name和snack变量的初始值都是默认值。如果想要为不同对象初始化不同的值,可使用有参构造方法,即在构造方法中设置形参。创建对象时,为不同对象传入不同的实参,并将每个对象的变量初始化为实参的值。
构造方法
2.4
【例7-4】 有参构造方法示例。
【参考代码】
class Person: #定义Person类
#构造方法,定义变量并赋初值
def __init__(self, name, snack):
self.name = name
self.snack = snack
def eat(self): #定义方法,输出变量
print('{}喜欢的零食是{}'.format(self.name, self.snack))
xiaolan = Person('小蓝', '薯条') #创建对象xiaolan
xiaolan.eat() #xiaolan调用eat()方法
xiaowu = Person('小舞', '冰激凌') #创建对象xiaowu
xiaowu.eat() #xiaowu调用eat()方法
构造方法
2.4
【运行结果】 程序运行结果如图7-5所示。
图7-5 例7-4程序运行结果
【程序说明】 在该程序中,第3~5行定义了带参数的构造方法,定义了两个参数name和snack,创建对象时,可为不同对象传入不同的参数值。
析构方法
2.5
创建对象时,Python解释器会默认调用构造方法;当需要删除一个对象来释放其所占的资源时,Python解释器会调用析构方法。析构方法的固定名称为__del__(),程序结束时会自动调用该方法,也可以使用del语句手动调用该方法删除对象。
【例7-5】 比较下面两个程序,分析输出结果。
【参考代码】
【代码一】
class Person():
def __init__(self): #构造方法
print('---调用构造方法创建对象---')
def __del__(self): #析构方法
print('---调用析构方法删除对象---')
person = Person() #创建对象
print('---程序结束---')
析构方法
2.5
【参考代码】(续)
【代码二】
class Person():
def __init__(self): #构造方法
print('---调用构造方法创建对象---')
def __del__(self): #析构方法
print('---调用析构方法删除对象---')
person = Person() #创建对象
del person #删除对象
print('---程序结束---')
析构方法
2.5
【运行结果】 代码一运行结果如图7-6所示,代码二运行结果如图7-7所示。
图7-6 代码一运行结果 图7-7 代码二运行结果
【程序说明】 以上两段代码的区别在于:代码二在程序结束前使用del语句手动调用析构方法删除对象,因此,先输出“---调用析构方法删除对象---”;而代码一没有使用del语句,因此,在程序结束时才调用析构方法,后输出“---调用析构方法删除对象---”。
PART 03
类变量和实例变量
类变量和实例变量
3
Python类中定义的变量包括两种:类变量和实例变量,它们有以下两点区别。
(1)类变量是在类中所有方法外定义的;实例变量一般是指在构造方法__init__()中定义的,在类中定义和使用时必须以self作为前缀。
(2)类变量属于类,可以通过类名或对象名访问;而实例变量属于实例(即对象),在主程序中(或类的外部)只能通过对象名访问。
与很多面向对象程序设计语言不同,Python允许在类外部动态地为类和对象增加变
这是Python动态类型特点的重要体现。
提示
类变量和实例变量
3
【参考代码】
class Toy: #定义Toy类
type = '小车' #初始化类变量
def __init__(self, color):
self.color = color #初始化实例变量
toy = Toy('红色') #创建对象
#访问类变量和实例变量并输出
print(Toy.type, toy.type, toy.color)
Toy.wheelNum = 4 #增加类变量
toy.price = 5 #增加实例变量
#访问增加的类变量和实例变量并输出
print(Toy.wheelNum, toy.wheelNum, toy.price)
类变量和实例变量
3
【运行结果】 程序运行结果如图7-8所示。
图7-8 例7-6程序运行结果
【程序说明】 Toy类中定义的type和动态为类增加的wheelNum都为类变量,因此,它们都属于类,可以通过类名或对象名访问。但构造方法中定义的color和动态为对象toy增加的price都为实例变量,因此,它们只能通过对象名访问,如果用类名进行访问会提示错误信息。例如,在程序的末尾增加一条语句“print(Toy.color)”,程序运行出错,提示Toy对象没有color属性,运行结果如图7-9所示。
类变量和实例变量
3
图7-9 错误提示
如果类中有相同名称的类变量和实例变量,通过对象名访问变量时获取的是实例变量的值,通过类名访问变量时获取的是类变量的值。
类变量和实例变量
3
【例7-7】 类中有相同名称的类变量和实例变量示例。
【参考代码】
class Toy: #定义Toy类
color = '白色' #初始化类变量
def __init__(self):
self.color = '红色' #初始化实例变量
toy = Toy() #创建对象
print(Toy.color, toy.color) #访问类变量和实例变量并输出
类变量和实例变量
3
【运行结果】 程序运行结果如图7-10所示。
图7-10 例7-7程序运行结果
【程序说明】 从程序运行结果可以看出,类变量和实例变量的名字相同,都为color,通过类名Toy访问color(Toy.color)时获取的是类变量的值“白色”,而通过对象名toy访问color(toy.color)时获取的是实例变量的值“红色”。
PART 04
面向对象编程的三大特征
封装
4.1
封装是面向对象编程的核心思想,它将对象的属性和行为封装起来(其载体是类),隐藏其实现细节,用户只需通过接口来操作对象。好比用户使用计算机时,通过键盘就可以实现一些功能,无须知道计算机内部是如何工作的。 具体来说,封装有两个层面的含义。
(1)将客观事物封装成抽象的类,类中的变量和方法只能通过类名或对象名加“.”的方式来访问,前面介绍的例子其实都是这一层面的封装。
(2)将类的某些变量和方法隐藏在类内部,不允许用户直接访问,或者留下少量的方法供外部访问。下面重点介绍第二层面的封装。
为了更好地实现数据的封装和保密性,可以将类中的变量和方法设置成私有的,然后在类中定义一个方法(也称接口函数),在它内部访问被隐藏的变量和方法,而外部可以通过接口函数进行访问。
在Python中,私有化变量或方法时只需在名字前加两个下划线“__”即可。
封装
4.1
【例7-8】 私有化变量和方法。
【参考代码】
class People: #定义People类
def __init__(self, name, age):
self.name = name
self.__age = age #定义私有变量__age
def __sayHello(self): #定义私有方法
print('Hello,大家好')
def greeting(self): #定义接口函数,调用私有方法
self.__sayHello()
def getAge(self): #定义接口函数,返回私有变量__age的值
return self.__age
xiaolan = People('小蓝', 10) #创建对象
xiaolan.greeting() #调用接口函数
#访问实例变量和调用接口函数并输出
print('我叫{},今年{}岁了。'.format(xiaolan.name, xiaolan.getAge()))
封装
4.1
【运行结果】 程序运行结果如图7-11所示。
图7-11 例7-8程序运行结果
封装
4.1
如果在类外部调用私有方法或访问私有变量,就会提示错误信息。例如,在程序的末尾增加两条语句“xiaolan.__sayHello()”和“print(xiaolan.__age)”,程序运行出错,结果如图7-12所示。出现上述问题的原因是“__sayHello()”为私有方法,类的外部无法调用类的私有方法。同理,如果程序执行到“print(xiaolan.__age)”时,也会提示类似的错误信息。
图7-12 错误提示
继承
4.2
1.单继承
在Python中,当一个子类只有一个父类时称为单继承。定义子类的语法格式如下。
class 子类名(父类名):
子类可以继承父类的所有公有变量和公有方法,但不能继承其私有变量和私有方法。
【例7-9】 单继承示例。
【参考代码】
class Animal: #定义Animal类
type = '动物' #定义变量type
food = '食物' #定义变量food
def eat(self): #定义方法输出type和food
print('{}吃{}'.format(self.type, self.food))
继承
4.2
1.单继承
【参考代码】(续)
class Cat(Animal): #定义Cat类继承Animal类
pass #空语句
cat = Cat() #创建对象
cat.eat() #调用父类方法
cat.type = '猫' #修改type
cat.food = '鱼' #修改food
cat.eat() #调用父类方法
【运行结果】 程序运行结果如图7-13所示。
图7-13 例7-9程序运行结果
【程序说明】 上述代码中定义了Animal类,包含type和food变量,以及eat()方法;然后定义了Cat子类继承Animal类,不执行任何操作;最后创建Cat类对象,修改父类中的变量,并调用父类中的方法。从程序的运行结果可以看出,子类继承了父类的变量和方法。
继承
4.2
2.多继承
多继承指一个子类可以有多个父类,它继承了多个父类的特性。例如,沙发床是沙发和床的功能的组合,儿子喜欢做爸爸和妈妈喜欢做的事。
多继承可以看作是对单继承的扩展,其语法格式如下。
class 子类名(父类名1, 父类名2……):
【例7-10】 多继承示例。
【参考代码】
class DadLikeDo: #定义DadLikeDo类
def basketball(self): #定义打篮球方法
print('打篮球')
继承
4.2
2.多继承
【参考代码】(续)
class MomLikeDo: #定义MomLikeDo类
def sing(self): #定义唱歌方法
print('唱歌')
#定义SonLikeDo类,继承DadLikeDo类和MomLikeDo类
class SonLikeDo(DadLikeDo, MomLikeDo):
def dance(self): #定义跳舞方法
print('跳舞')
son = SonLikeDo() #创建对象
print('儿子喜欢做的事:')
son.basketball() #调用DadLikeDo类的方法
son.sing() #调用MomLikeDo类的方法
son.dance() #调用SonLikeDo类的方法
继承
4.2
2.多继承
【运行结果】 程序运行结果如图7-14所示。
图7-14 例7-10程序运行结果
【程序说明】 上述代码中定义了DadLikeDo类,包含basketball()方法,以及定义了MomLikeDo类,包含sing()方法;然后定义了继承DadLikeDo类和MomLikeDo类的子类SonLikeDo,包含dance()方法;最后创建SonLikeDo类的对象,分别调用basketball()、sing()和dance()方法。从程序输出的结果可以看出,子类同时继承了多个父类的方法。
继承
4.2
3.方法重写
当父类中的方法无法满足子类需求或子类具有特有功能时,可以在子类中重写父类的方法,即子类中的方法会覆盖父类中同名的方法,以实现不同于父类的功能。
【例7-11】 重写父类的方法示例。
【参考代码】
class Student: #定义Student类
name = 'xx' #定义变量name
def category(self): #定义方法category()
print(self.name + '是学生')
继承
4.2
3.方法重写
【参考代码】(续)
class Pupil(Student): #定义Pupil类继承Student类
def category(self): #重写category()方法
print(self.name, '是小学生')
class Junior(Student): #定义Junior类继承Student类
def category(self): #重写category()方法
print(self.name, '是初中生')
xioalan = Pupil() #创建Pupil类对象
xioalan.name = '小蓝' #修改name
xioalan.category() #调用category()方法
xiaoming = Junior() #创建Junior类对象
xiaoming.name = '小明' #修改name
xiaoming.category() #调用category()方法
继承
4.2
3.方法重写
【运行结果】 程序运行结果如图7-15所示。
图7-15 例7-11程序运行结果
【程序说明】 从程序的输出结果可以看出,在调用Pupil类和Junior类对象的category()方法时,只调用了子类中重写的方法,不会再调用父类的category()方法。
如果需要在子类中调用父类的方法,可以使用内置函数super()或通过“父类名.方法名()”来实现。
继承
4.2
3.方法重写
【例7-12】 子类调用父类的方法示例。
【参考代码】
class Student: #定义Student类
def __init__(self, name, age): #构造方法,传递name和age
self.name = name
self.age = age
def showInfo(self): #定义showInfo()方法,输出name和age
print('姓名:{};年龄:{}'.format(self.name, self.age))
继承
4.2
3.方法重写
【参考代码】(续)
class Pupil(Student): #定义Pupil类继承Student类
#构造方法,传递name、age和sex
def __init__(self, name, age, sex):
super().__init__(name, age) #调用父类构造方法
self.sex = sex
def showInfo(self):
Student.showInfo(self) #调用父类showInfo()方法
print('性别:{}'.format(self.sex)) #输出sex
xiaolan = Pupil('小蓝', 10, '女') #创建对象
xiaolan.showInfo() #调用showInfo()方法
继承
4.2
3.方法重写
【运行结果】 程序运行结果如图7-16所示。
图7-16 例7-12程序运行结果
【程序说明】 以上代码中定义了Student类,在该类的__init__()方法中定义了name和age变量。然后定义了继承Student类的子类Pupil,在该类中重写了构造方法__init__(),使用super()函数调用父类的构造方法,并添加了自定义变量sex,使Pupil类既拥有自定义的sex,又拥有父类的name和age;还重写了showInfo()方法,使用父类名调用了父类的showInfo()方法输出name和age,又输出了sex。
多态
4.3
在Python中,多态指的是一类事物有多种形态,如一个父类有多个子类,因而多态的概念依赖于继承。而多态性可以这样描述:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应同一消息(调用函数)。
【例7-13】 多态示例。
【参考代码】
class Person: #定义Person类
def __init__(self, name): #构造方法,定义name
self.name = name
def who(self): #定义who()方法
print('我是一个人, 我的名字是{}'.format(self.name))
多态
4.3
【参考代码】(续)
class Student(Person): #定义Student类,继承Person类
def __init__(self, name, score): #重写构造方法
super().__init__(name)
self.score = score
def who(self): #重写who()方法
print('我是一个学生, 我的名字是{},我的语文成绩是{}'
.format(self.name, self.score))
class Teacher(Person): #定义Teacher类,继承Person类
def __init__(self, name, course):#重写构造方法
super().__init__(name)
self.course = course
def who(self): #重写who()方法
print('我是一个老师, 我的名字是{},我教{}'
.format(self.name, self.course))
多态
4.3
【参考代码】(续)
def showInfo(x): #定义函数用于接收对象
x.who() #调用who()方法
#创建对象
p = Person('小蓝')
s = Student('小明', 88)
t = Teacher('唐果', '语文')
#调用函数
showInfo(p)
showInfo(s)
showInfo(t)
多态
4.3
【运行结果】 程序运行结果如图7-17所示。
图7-17 例7-13程序运行结果
【程序说明】 上述代码中首先定义了Person类,包含who()方法;然后定义了继承Person类的两个子类Student和Teacher,分别在这两个类中重写了who()方法;接着定义了带参数的showInfo()函数,在该函数中调用了who()方法;最后分别创建了Person类的对象p、Student类的对象s和Teacher类的对象t,并将其作为参数调用了showInfo()函数。从程序运行结果可以看出,通过向函数中传入不同的对象,who()方法输出不同的结果。
PART 05
类方法和静态方法
类方法
5.1
类方法是类所拥有的方法,须用修饰器“@classmethod”来标识。对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(同self一样只是一个习惯),可以通过对象名调用类方法,也可以通过类名调用类方法。
【例7-14】 类方法示例。
【参考代码】(续)
class Book: #定义Book类
type = '课外书' #定义类变量并赋值
#类方法,用classmethod进行修饰
@classmethod
def getType(cls):
return cls.type #返回类变量的值
book = Book() #创建对象
print(Book.getType()) #通过类名调用类方法
print(book.getType()) #通过对象名调用类方法
类方法
5.1
【运行结果】 程序运行结果如图7-18所示。
图7-18 例7-14程序运行结果
【程序说明】 上述代码中定义了一个Book类,在其中添加了类变量type,然后在类方法getType()中返回type的值。从运行结果可以看出,用对象名调用类方法和用类名调用类方法的效果是一样的。
静态方法
5.2
要在类中定义静态方法,须在方法前加上“@staticmethod”标记符,以表示下面的方法是静态方法。使用静态方法的好处是,不需要实例化对象即可调用该方法。
静态方法没有self参数,所以它无法访问类的实例变量;静态方法也没有cls参数,所以它也无法访问类变量。静态方法既可以通过对象名调用,也可以通过类名调用。
【例7-15】 静态方法示例。
【参考代码】
class Book: #定义Book类
type = '课外书' #定义类变量并赋值
#静态方法,用@staticmethod进行修饰
@staticmethod
def printType():
print('---书的类别---')
静态方法
5.2
【参考代码】(续)
book = Book() #创建对象
book.printType() #通过对象名调用静态方法
Book.printType() #通过类名调用静态方法
print(book.type) #输出type
【运行结果】 程序运行结果如图7-19所示。
图7-19 例7-15程序运行结果
感谢观看

展开更多......

收起↑

资源预览