Python笔记-类和实例、继承和多态
来源:互联网 发布:恒生期货软件使用方法 编辑:程序博客网 时间:2024/05/19 02:01
类和实例
1、通过class关键字创建一个类
class Student(object): pass
(object)表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类都会继承的类。
2、创建实例是通过类名+()实现的。如果类有必须绑定的属性,则在类内需要定义一个特殊的__init__方法(这个方法名不能改成其他的,前后各两条横线)。
比如学生类必须有姓名和分数属性:
class Student(object): def __init__(self, name, score): #self指向正在被创建的对象本身 self.name = name self.score = score
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去
>>> Bart = Student('Bart Simpson', 59)
要在类里面定义一个方法,除了第一个参数是self外,其他和普通函数一样。
要调用类里面一个方法,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入。
class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print('%s: %s' % (self.name, self.score))>>> Bart.print_score()Bart Simpson: 59
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量。
class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print('%s: %s' % (self.__name, self.__score))
此时已经无法从外部访问实例变量.__name和实例变量.__score了。
如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法。
class Student(object): ... def get_name(self): return self.__name def get_score(self): return self.__score
如果又要允许外部代码修改score怎么办?可以再给Student类增加set_score方法:
class Student(object): ... def set_score(self, score): if 0 <= score <= 100: self.__score = score else: raise ValueError('bad score')
需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
3、如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称>>> s = Student() # 创建新的实例>>> s.name = 'Michael' # 绑定属性'name'>>> s.score = 99 # 绑定属性'score'(出错了,没有score属性)
使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
继承和多态
1、一个名为Animal的class,有一个run()方法
class Animal(object): def run(self): print('Animal is running...')
编写Dog和Cat类时,就可以直接从Animal类继承:
class Dog(Animal): passclass Cat(Animal): pass
可以对子类增加一些方法,比如Dog类:
class Dog(Animal): def run(self): print('Dog is running...') def eat(self): print('Eating meat...')
当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。
2、在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。
3、多继承
class Parrot(Bird): passclass Ostrich(Bird): pass
要给动物再加上Runnable和Flyable的功能,只需要先定义好Runnable和Flyable的类:
class Runnable(object): def run(self): print('Running...')class Flyable(object): def fly(self): print('Flying...')
对于需要Runnable功能的动物,就多继承一个Runnable,例如Dog:
class Dog(Mammal, Runnable): pass
对于需要Flyable功能的动物,就多继承一个Flyable,例如Bat:
class Bat(Mammal, Flyable): pass
鸭子类型
1、对于静态语言来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则将无法调用run()方法。
2、对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。
3、这就是动态语的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
class Quote(): def __init__(self, person, words): self.person = person self.words = words def who(self): return self.person def says(self): return self.words + '.'class QuestionQuote(Quote): def says(self): return self.words + '?'class ExclamationQuote(Quote): def says(self): return self.words + '!'hunter = Quote('Elmer Fudd', "I'm hunting wabbits")hunted1 = QuestionQuote('Bugs Bunny', "What's up, doc")hunted2 = ExclamationQuote('Daffy Duck', "It's rabbit season")print(hunter.who(), 'says:', hunter.says())print(hunter1.who(), 'says:', hunter1.says())print(hunter2.who(), 'says:', hunter2.says())结果:Elmer Fudd says: I'm hunting wabbits.Bugs Bunny says: What's up, doc?Daffy Duck says: It's rabbit season!
三个不同版本的says()为上面三种类提供了不同的响应方式,这是面向对象的语言中多态的传统形式。
Python中,无论对象的种类是什么,只要包含 who() 和says(),你便可以调用它。我们再来定义一个 BabblingBrook 类,它与我们之前的猎人猎物(Quote 类的后代)什么的没有任何关系:
class BabblingBrook(): def who(self): return 'Brook' def says(self): return 'Babble'def who_says(obj): print(obj.who(), 'says', obj.says())brook = BabblingBrook()print(who_says(hunter))print(who_says(hunter1))print(who_says(hunter2))print(who_says(brook ))结果:Elmer Fudd says I'm hunting wabbits.Bugs Bunny says What's up, doc?Daffy Duck says It's rabbit season!Brook says Babble
- Python笔记-类和实例、继承和多态
- python学习笔记 继承和多态
- Python 笔记 : 类和继承
- 【Python学习笔记】面向对象编程:继承和多态
- 【Python】学习笔记——-7.3、继承和多态
- Python 继承和多态
- python 继承和多态
- Python面向对象编程(类和实例 访问限制 继承和多态 获取对象信息 实例属性和类属性)
- Python 类的定义和实例化,类继承
- python继承和重写init方法--实例
- Python类和继承
- python学习笔记 类和实例
- python学习笔记-类和实例
- Python学习笔记2:类的定义和继承
- python中的多继承和多态
- Python中继承和多态
- python的继承和多态
- Python基础-继承和多态
- 数据库第5天
- 蓝桥 打印图形
- Material Design之RippleDrawable详解
- 【Linux init】systemd 服务单元管理
- 算法导论B树
- Python笔记-类和实例、继承和多态
- Spreadsheet Tracking
- Python爬虫之——爬取妹子图片
- # VMWARE上的 RHEL 7扩展lv
- Ubuntu系统下IPython Notebook的安装和远程访问配置
- Score UVA
- hdu 6020 MG loves apple //bc Round #93 1002
- Jmeter使用嵌套循环实现读取2个文件的参数来进行组合参数化
- 计算24点(Java)