一、面向对象
面向对象是一种符合人类思维的编程方法,现实世界就是由对象和对象构成的,所以我们可以用代码将现实世界映射到开发中。 每一个对象都有他自己的状态和行为,以汽车为例:
状态:油耗,颜色,轴距,速度,材质......
行为:启动,行使,加减速,刹车......
二、类
类是构建对象的状态和行为的模板,以汽车为例,类就是汽车的设计图或者骨架图,而实例则是根据设计图制造出来的实物,被称作为对象。
例如:宝马88系中 红色,蓝色,黑色等。
定义一个类:
def car (object):
pass
#所有的类都会继承object类,不知道填什么就填这个类
三、类的属性和方法
类中定义的函数叫类的方法,类方法与普通函数的区别在于,其第一个参数固定为self,表示实际使用时对应的实例本身,可以使用init方法将一些强制的属性绑定进去。
1:定义一个Student类
class Car(object):
#由于类是模板,当创建实例时,可以使用__init__构造方法将强制的属性绑定进去,self参数指向实例本身
def __init__(self,speed):
#给car定义speed属性
self.speed = speed
#定义一个打印汽车速度的方法(函数)
def run(self):
print('现在速度为:',self.speed)
return self.speed
2:传入参数
#创建student的实例,并传入数据
baoma = Car(100)
3:访问对象的属性
class Car(object):
# speed = 0 #共用的类属性
def __init__(self,speed,):
self.speed = speed
def run(self):
print('现在速度为:',self.speed)
return self.speed
#创建Car的实例,并传入数据
baoma = Car(100)
#调用baoma对象的speed属性。
print(baoma.speed)
#调用baoma的打印速度方法:
baoma.run()
运行结果:
L:/python项目库/面向对象编程/面向对象.py
100
现在速度为: 100
进程已结束,退出代码0
4:类的封装
因为在Student类中已经含有对象的属性,所以没必要在外部重新定义新的函数访问,我们可以在Student类中定义函数,这样的就叫封装。封装的好处是可以在类中新增方法。
新增打印汽车型号的方法。
class Car(object):
def __init__(self,name,speed,):
self.speed = speed
self.name = name
def run(self):
print('现在速度为:',self.speed)
return self.speed
#新增根据速度打印汽车型号的方法。
def car_xh(self):
if self.speed > 300:
print(self.name,':','超级跑车')
elif self.speed > 200:
print(self.name,':','豪华型轿车')
else:
print(self.name,':','经济型轿车')
#创建Car的实例,并传入数据
baoma = Car('baoma_X1',100)
#调用查询汽车型号的方法
baoma.car_xh()
5:访问限制
现在定义的类,外部可以访问到类的属性,这样很不安全,而且外部可以直接更改Car类的速度属性。
class Car(object):
def __init__(self,name,speed,):
self.speed = speed
self.name = name
def run(self):
print('现在速度为:',self.speed)
return self.speed
#创建Car的实例,并传入数据
baoma = Car('baoma_X1',100)
#外部访问baoma的型号和速度
print(baoma.name,baoma.speed)
#外部更改宝马X1的参数
baoma.name = 'new_baoma_X1'
baoma.speed = 120
#更改后,再访问baoma的型号和速度
print(baoma.name,baoma.speed)
运行结果:
baoma_X1 100
new_baoma_X1 120
进程已结束,退出代码0
如果要让类的属性不被外部访问,直接在类属性的名称前加“__”两个下划线,这样就变成了一个私有变量(private)
更改为私有变量之后
Traceback (most recent call last):
File "L:/python项目库/面向对象编程/面向对象.py", line 26, in
print(baoma.name,baoma.speed)
AttributeError: 'Car' object has no attribute '__name'
这样就不能直接访问了,但是又想让外部访问和更改怎么办?而且还要对更改的参数做检查。
6:改进版访问限制
外部访问方法:get_name,get_speed
class Car(object):
def __init__(self,name,speed,):
self.__speed = speed
self.__name = name
def get_name(self):
return self.__name
def get_speed(self):
return self.__speed
def run(self):
print('现在速度为:',self.__speed)
return self.__speed
#创建Car的实例,并传入数据
baoma = Car('baoma_X1',100)
#外部访问baoma的型号和速度
print(baoma.get_name(),baoma.get_speed())
运行结果:
baoma_X1 100
进程已结束,退出代码0
外部更改speed的方法:set_speed,并检查参数不能小于0
class Car(object):
def __init__(self,name,speed):
self.__speed = speed
self.__name = name
def get_name(self):
return self.__name
def get_speed(self):
return self.__speed
def set_speed(self,speed):
if speed > 0:
self.__speed = speed
else:
raise ValueError('speed Erro')
def run(self):
print('现在速度为:',self.__speed)
return self.__speed
#创建Car的实例,并传入数据
baoma = Car('baoma_X1',100)
#调用set_speed方法,并传入错误参数
baoma.set_speed(0)
#外部访问baoma的型号和速度
print(baoma.get_name(),baoma.get_speed())
运行结果:
Traceback (most recent call last):
File "L:/python项目库/面向对象编程/面向对象.py", line 34, in
baoma.set_speed(0)
File "L:/python项目库/面向对象编程/面向对象.py", line 18, in set_speed
raise ValueError('speed Erro')
ValueError: speed Erro
四、多态和继承
1:继承
##继承
class Animal(object):
def speak(self):
print('Animal is speaking:')
#定义Dog类,从父类继承
class Dog(Animal):
pass
class Cat(Animal):
pass
#定义dog对象并调用继承来的Animal类的speak方法
dog = Dog()
dog.speak()
dog对象什么都没有做就能拿到Animal的方法,因为他即是Dog的子类也是Animal的子类。
2:多态
# -*- coding: utf-8 -*-
###多态
class Animal(object):
def speak(self):
print('Animal is speaking:')
#定义Dog类,从父类继承
class Dog(Animal):
def speak(self):
print('汪汪')
class Cat(Animal):
def speak(self):
print('喵喵')
#定义一个外部函数speak_twice,传入的参数只要是带speak方法的对象就执行。
def speak_twice(animal):
animal.speak()
animal.speak()
speak_twice(Animal())
speak_twice(Dog())
1:在写一个函数speak_twice时,要调用Animal类,只需要保证函数中speak方法编写正确,不管你想调用子类Dog还是父类Animal还是新的子类,都可以拿到父类的speak方法。 2:在1中,如果子类的方法名和父类重复时,子类的优先执行,所以父类的方法即可继承有可以重写。
开闭原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。
Python的鸭子理论
在Python中,只要你长得像鸭子那你就是鸭子 如: 在上面的多态例子中,函数speak_twice,只要你有speak方法那么就会执行,不管你的父类是谁
class yazi(object):
def speak(self):
print('嘎嘎')
speak_twice(yazi())
五、多重继承
继承和多态不仅可以继承父类的功能和行为,也可以继承多个父类,这样的叫多重继承。
# -*- coding: utf-8 -*-
"""
@author:leelian
@time:2018/9/2515:40
"""
class Bird(object):
pass
class Mammal(object):
pass
class Flyable(object):
def say(self):
print('我会飞!')
class Swimmable(object):
def say(self):
print('我会游泳')
#定义一种会飞的哺乳动物
class Bat(Flyable,Mammal):
pass
#创建实例,并调用实例的方法
bat = Bat()
print(bat.say())
#如果多重继承中有多个父类,以第一个为主。
class Seagull(Mammal, Flyable, Swimmable):
pass
#创建实例,并调用实例的方法)
seagull = Seagull()
seagull.say()
###类的定制__iter__
#构造一个迭代类
class FactorialIterator(object):
def __init__(self):
self.value = 1
self.index = 1
def __next__(self):
self.value = self.value * self.index
self.index = self.index + 1
if self.index > 11:
raise StopIteration()
return self.value
class Factorial(object):
def __init__(self):
pass
def __iter__(self):
return FactorialIterator()
factorial = Factorial()
for n in factorial:
print(n)