面向对象三大特征
1.封装:根据职责将属性和方法封装到一个抽象的类中
2.继承:实现代码的重用,相同的代码不需要重复的编写设计类的技巧,子类针对自己特有的需求,编写特定的代码。
3.多态:不同的对象调用相同的方法,产生不同的结果,增加代码的灵活度
类的设计:
在程序开发中,要设计一个类,通常需要以下三个要求:
1.类名:这类事物的名字,满足大驼峰命名法
2.属性:这类事物具体有什么样的特征
3.方法:这类事物具有什么样的行为
1.面向对象-01
需求:
小明今年18岁,身高1.75,每天早上要跑步,会去吃东西
小美今年17岁,身高163,小妹不跑步,小妹喜欢吃东西
Person()
name
age
height
run()
eat()
一只黄颜色的狗叫大黄
看见生人汪汪叫
看见家人摇尾巴
Dog()
name
color
shout()
shake()
2.面向对象-02
面向对象的基础语法:
定义简单的类:
定义只包含方法的类:
class 类名:
def 方法1(self,参数列表):
pass
def 方法2(self,参数列表):
pass
当一个类定义完成之后,要使用这个类来创建对象,语法格式如下:
对象变量 = 类名()
需求
小猫爱吃鱼,小猫要喝水
初始化方法
我们现在已经知道了使用 类名() 就可以创建一个对象
当使用类名()创建对象时,python的解释器会自动执行以下操作:
1.为对象在内存中分配空间——创建对象
2.调用初始化方法为对象的属性设置初始值——初始化方法(__init__)
这个初始化方法就是__init__方法,__init__是对象的内置方法
__init__方法是专门用来定义一个类具有那些属性的方法
1.del方法
__del__方法:
在python中
当使用类名()创建对象时,为对象分配完空间后,自动调用__init__方法
当一个对象被从内存中销毁前,会自动调用__del__方法
在python中,使用python输出对象变量
默认情况下,会输出这个变量引用的对象是由哪一个类创建的对象
以及在内存中的地址(十六进制表示)
如果在开发中,希望使用print输出对象变量时,
能够打印自定义的内容,就可以利用__str__这个内置方法了
封装
1.封装是面向对象编程的一大特点
2.面向对象变成编程的第一步,将属性和方法封装到一个抽象的类中
3.外界使用类创建对象,然后让对象调用方法
4.对象方法的细节都被封装在类的内部
1.封装-01练习
xx爱跑步
1.xx体重75.0公斤
2.xx每次跑步会减肥0.5公斤
3.xx每次吃东西体重会增加1公斤
class Gun():
def __init__(self,model):
# 枪的型号
self.model = model
# 子弹的数量
self.bullet_count = 0
def add_bullet(self,count):
self.bullet_count += count
def shoot(self):
# 1.判断子弹数量
if self.bullet_count <=0:
print '没有子弹了'
# 2.发射子弹
self.bullet_count -= 1
# 3.提示发射信息
print '%s biubiubiu %d' % (self.model,self.bullet_count)
class Soldier():
def __init__(self,name):
self.name = name
#不确定有没有枪
self.gun = None
def fire(self):
# 1.判断士兵没有枪
if self.gun == None:
print '%s 还没枪。。'
return
#2.高喊口号
print 'go!!! %s' %self.name
#3.让枪装填子弹
self.gun.add_bullet(50)
#4.让枪发射子弹
self.gun.shoot()
#1.创建枪对象
ak47 = Gun('AK47')
#ak47.add_bullet(50)
#ak47.shoot()
#创建士兵
ryan = Soldier('Ryan')
ryan.gun = ak47
ryan.fire()
print ryan.gun
需求:
1.房子有户型,总面积和家具名称列表
新房子没有任何家具
2.家具有名字和占地面积,其中
床:4.6平米
衣柜:2平米
餐桌:3平米
3.将以上三件家具添加到房子中
4.打印房子时,要求输出:户型,面积,剩余面积,家具名称列表
class houseitem():
#初始化方法
def __init__(self,name,area):
self.name= name
self.area= area
def __str__(self):
return '[%s] 占地 %.2f' %(self.name,self.area)
class House():
def __init__(self,house_type,area):
self.house_type = house_type
self.area = area
#剩余面积
self.free_area = area
#家具名称列表
self.item_list = []
def __str__(self):
return '户型:%s\n总面积:%.2f[剩余面积:%.2f]\n家具:%s'\
% (self.house_type,self.area,self.free_area,self.item_list)
def add_item(self,item):
print '要添加 %s' % item
# 1.判断家具面积
if item.area > self.free_area:
print '%s的面积太大了,无法添加' %item.name
#如果不满足,下方代码就不执行
return
# 2.将家具名称添加到列表中
self.item_list.append(item.name)
# 3.计算剩余面积
self.free_area -= item.area
# 创建家具
bed = houseitem('bed', 10)
print bed
chest = houseitem('chest', 1.5)
print chest
table = houseitem('table', 2)
print table
#创建房子对象
my_home = House('两室一厅',100)
#添加家具
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print my_home
1.继承-01
单继承
1.继承的概念 语法和特点
继承的概念:子类拥有父类的所有方法和属性(子类只需封装自己特有的属性)
2.继承的语法
class 类名(父亲)
def 子类特有的方法
class Animal():
def eat(self):
print '吃'
def drink(self):
print '喝'
def run(self):
print '跑'
def sleep(self):
print '睡'
class Cat(Animal):
# 子类拥有父类的所有属性和方法
def call(self):
print '喵呜~'
fentiao = Cat()
fentiao.eat()
fentiao.drink()
fentiao.run()
fentiao.sleep()
fentiao.call()
# 子类继承自父类,可以直接享受父类中已经封装好的方法
# 子类中应该根据自己的职责,封装子类特有的属性和方法
继承的传递性:(爷爷 父亲 儿子)
1.C类从B类继承,B类又从A类继承
2.那么C类就具有B类和A类的所有属性和方法
子类拥有父亲以及父类的父类中封装的所有属性和方法
class Animal():
def eat(self):
print '吃'
def drink(self):
print '喝'
def run(self):
print '跑'
def sleep(self):
print '睡'
class Cat(Animal):
def call(self):
print '喵呜~'
class HelloKitty(Cat):
def speak(self):
print '我可以说日语'
# 创建一个HelloKitty对象
kt = HelloKitty()
kt.speak()
kt.eat()
kt.drink()
kt.run()
kt.sleep()
kt.call()
class Animal():
def eat(self):
print '吃'
def drink(self):
print '喝'
def run(self):
print '跑'
def sleep(self):
print '睡'
class Cat(Animal):
def call(self):
print '喵呜~'
class HelloKitty(Cat):
def speak(self):
print '我可以说日语'
class Dog(Animal):
def bark(self):
print '旺旺~'
# 创建一个HelloKitty对象
kt = HelloKitty()
#继承的传递性,子类拥有父类和父类的父类的属性和方法
kt.speak()
kt.eat()
kt.drink()
kt.run()
kt.sleep()
kt.call()
dog =Dog()
dog.sleep()
dog.bark()
重写父类方法有两种情况:
1.覆盖父类的方法
2.对父类方法进行扩展
1.覆盖父类的方法
如果在开发中,父类的方法的实现和子类方法的实现完全不同
就可以使用覆盖的方法,在子类中重新编写父类的方法
具体实现方式,就相当于在子类中定义了
一个和父类同名的方法并且实现
重写之后,在运行时,只会调用子类的重写方法
而不会调用父类封装的方法
class Animal():
def eat(self):
print '吃'
def drink(self):
print '喝'
def run(self):
print '跑'
def sleep(self):
print '睡'
class Cat(Animal):
def call(self):
print '喵呜~'
class HelloKitty(Cat):
def speak(self):
print '我可以说日语'
def call(self):
print 'ouhayaogaozayimasi'
kt = HelloKitty()
kt.speak()
kt.call()
对父类的方法进行扩展
如果在开发中,子类的方法实现包含有父类的方法实现
(父类原本封装的方法实现时子类方法的一部分
就可以使用扩展的方法)
1.在子类中重写父类的方法
2.在需要的位置使用 父类名.方法(self) 来调用父类方法的执行
(使用父类名称调用父类方法)
3.代码其他位置针对子类的需求,编写子类特有的代码实现
class Animal():
def eat(self):
print '吃'
def drink(self):
print '喝'
def run(self):
print '跑'
def sleep(self):
print '睡'
class Cat(Animal):
def call(self):
print '喵呜~'
class HelloKitty(Cat):
def speak(self):
print '我可以说日语'
def call(self):
print 'ouhayaogaozayimasi'
# 调用本来在父类中封装的方法
Cat.call(self)
print '@#$#$%$&^^*&'
kt = HelloKitty()
kt.speak()
kt.call()
class Dog(object):
def __init__(self,name):
self.name = name
def game(self):
print '%s 奔跑,使劲奔跑' % self.name
class xiaotianquan(Dog):
def game(self):
print '%s 会说话' % self.name
class Person(object):
def __init__(self,name):
self.name = name
def game_with_dog(self,dog):
print '%s 和 %s 快乐的玩耍' % (self.name,dog.name)
dog.game()
#1.创建一个狗对象
#mao = Dog('猫')
mao = xiaotianquan('大猫')
#2.创建一个对象
xiaolei = Person('小雷')
#让小雷和狗玩
xiaolei.game_with_dog(mao)