python _ 面向对象

一、面向对象和面向过程是什么?

    面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,
使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,
建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

二、面向对象和面向过程的区别在哪里?

可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,
面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,
2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,
6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。
把上面每个步骤用不同的方法来实现。

如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思
路来解决问题。整个五子棋可以分为1、黑白双方,这两方的行为是一模
一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、
输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象
(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕
上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

可以明显地看出,面向对象是以功能来划分问题,而不是步骤。
同样是绘制棋局,这样的行为在面向过程的设计中分散在了多个步骤中,
很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行
各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。

三、简单的类设计

1、概念

类的设计:
在程序开发中,要设计一个类,通常需要满足以下三个要求:
1.类名 这类事物的名字,满足大驼峰命名法
2.属性 这类事物具有什么样的特征
3.方法 这类事物具有什么样的行为

2、案例

第一个:

需求:
小明今年18岁,身高1.75,每天早上要跑步,会去吃东西
小美今年17岁,身高1.65,不跑步,小美喜欢吃东西
Person()
name    #  属性
age
height
run()   # 方法
eat()

第二个

一只黄颜色的狗狗叫大黄
看见生人旺旺叫
看见主人摇尾巴
Dog()
color   #  属性
name
shout() #   方法
shake()

四、面向对象的基础语法

1、概念

面向对象的基础语法:
定义简单的类:
定义只包括方法的类:
class 类名:
    def 方法1(self,参数列表):  
    self的意思就是哪一个对象调用的方法就是哪个对象的引用
        pass
    def 方法2(self,参数列表):
        pass
当一个类定义完成之后,要使用这个类来创建对象,语法格式如下:
类和对象的关系就是:
类----->对象相当于图纸------>建筑

2、简单的动物特性的面向对象编程

需求
    小狗爱吃肉,小狗爱玩耍
"""
# 定义一个类,但是只有一个类是无法输出的
class Dog():
    def eat(self):
        print '小狗爱吃肉'
    def play(self):
        print '小狗爱玩耍'
# 将类转换到对象
dou = Dog()
dou.eat()
dou.play()

这里写图片描述

3、一个类可以创建多个对象

class Dog():
    def eat(self):
        print '小狗爱吃肉'
    def play(self):
        print '小狗爱玩耍'
# 创建狗对象
doudou = Dog()
doudou.name = 'doudou'   # 单独的赋值属性
doudou.eat()
doudou.play()
print doudou    # 会输出doudou的引用
addr = id(doudou)
# %x:大印格式为16进制
print '%x' % addr
# %d:大印格式为10进制
print '%d' % addr

# 再创建一个狗对象,一个类可以创建多个对象
lazy_dog = Dog()
lazy_dog.name = 'huhu'
lazy_dog.eat()
lazy_dog.play()
print lazy_dog

lazy_dog2 = lazy_dog   # 这个命令表示两个对象是相同的
print lazy_dog2

这里写图片描述
这里写图片描述

4、在类的外部给对象增加属性会报错:(对刚才的脚本做了点修改)

这里写图片描述

五、初始化方法

1、概念

初始化方法
我们已经知道了使用类名()就可以创建一个对象
当使用类名()创建对象时,python的解释器会自动执行以下操作:
    1.为对象在内存中分配空间--创建对象
    2.调用初始化方法为对象的属性设置初始值--初始化方法(__init__)
这个初始化方法就是__init__方法,__init__是对象的内置方法
__init__方法是专门用来定义一个类具有哪些属性的方法

2、案例

# 调用初始化方法可以直接打印hello
class Cat():
    def __init__(self):
        print 'hello'
tom = Cat()
class Cat():
    def __init__(self):
        print '这是一个初始化方法'
        # self.属性名 = 属性的初始值
        self.name = 'Tom'
# 使用类名()创建对象的时候,会自动调用初始化方法__init__
tom = Cat()
print tom.name

这里写图片描述

3、直接调用初始化不加入形参在有两个类的时候程序会出现BUG

class Cat():
    def __init__(self):
        self.name = 'Tom'
        # 在类中,任何方法都可以使用self.name
    def eat(self):
        print '%s 爱吃鱼' % self.name
tom = Cat()
print tom.name
tom.eat()
# 重新定义一个猫输出还是Tom,显然不合理
lazy_cat = Cat()
lazy_cat.eat()

这里写图片描述

4、调用初始化加入形参

class Cat():
    def __init__(self,new_name):  # new_name为形参
        # 在类中,任何方法都可以使用self.name
        self.name = new_name
    def eat(self):
        print '%s 爱吃鱼' % self.name
tom = Cat('tom')    # 必须给传递实际的参数不然会报错
print tom.name
tom.eat()
lazy_cat = Cat('lazy_cat')   # 必须给传递实际的参数不然会报错
lazy_cat.eat()

这里写图片描述

六、面向对象编程的三大特点

1.封装:根据职责将属性和方法封装到一个抽象的类中
    定义类的准则
2.继承:实现代码的重用,相同的代码不需要重复的编写
    设计类的技巧
    子类针对自己特有的需求,编写特定的代码
3.多态:
    不同的子类对象调用相同的方法,产生不同的执行结果

1、封装

封装是面向对象编程的一大特点
面向对象编程的第一步就是将属性和方法封装到一个类中
外界使用类创建对象,然后让对象调用方法
对象方法的细节都被封装到类的内部

2、简单的封装案例

示例一、跑步

需求:
xx爱跑步,xx体重是55公斤
跑一次步减肥0.5公斤,吃一次东西增肥1公斤
"""
class Person():
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
    def __str__(self):
        return '%s爱跑步\n%s体重是%.2f公斤' % (self.name,self.name, self.weight)
    def run(self):
        self.weight -= 0.5
    def eat(self):
        self.weight += 1
jane = Person('jane',55.0)
jane.run()
jane.eat()
print jane

这里写图片描述

需求:
xx和xxx爱跑步
xx体重是55公斤,xxx的体重是52公斤
跑一次步减肥0.5公斤,吃一次东西增肥1公斤
"""
nancy = Person('nancy',52.0)
nancy.run()
nancy.eat()
print nancy

这里写图片描述

示例二、士兵开枪

desc:
1.士兵瑞恩有一把AK47
2.士兵可以开火
3.枪能够发射子弹
4.枪能够装填子弹
"""
class Gun():
    def __init__(self,model):
        # 枪的型号
        self.model = model
        # 子弹的数量
        self.buttet_count = 0
    def add_buttet(self,count):
        self.buttet_count += count
    def shoot(self):
        # 1.判断子弹的数量
        if self.buttet_count <= 0:
            print '%s没有子弹了'%self.model
            return
        # 2.发射子弹
        self.buttet_count -= 1
        # 3.提示发射信息
        print '%s突突突%d' %(self.model,self.buttet_count)
class Soldier():
        def __init__(self,name):
                self.name = name
                self.gun = None
        def fire(self):
            # 1.判断士兵有没有枪
            if self.gun == None:
                print '%s没有枪!!!'%self.name
            # 2.高喊口号
            print 'go!!!!%s' %self.name
            # 3.让枪装填子弹
            self.gun.add_buttet(50)
            # 4.发射子弹
            self.gun.shoot()
# 1.创建枪对象
ak47 = Gun('Ak47')
# 2.创建士兵
ryan = Soldier('Ryan')
ryan.gun = ak47
ryan.fire()
print ryan.gun   #返回的是内存地址

这里写图片描述
这里写图片描述
这里写图片描述

示例三、摆放家具案例:(没有完成添加家具)

desc:
需求:
1.房子有户型,总面积和家具名称列表
    新房子没有任何家具
2.家具有名字和占地面积,其中
    床:占4平方米
    衣柜:占2平方米
    餐桌:占1.5平方米
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)
# 创建家具(对象)
bed = HouseItem('bed',4)
print bed
chest = HouseItem('chest',2)
print chest
table = HouseItem('table',1.5)
print table

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
# 创建房子对象
my_home = House('两室一厅',100)
# 添加家具
my_home.add_Item(bed)
my_home.add_Item(chest)
my_home.add_Item(table)
print my_home

这里写图片描述
这里写图片描述
这里写图片描述

摆放家具进阶版

desc:
小结:
1.创建一个房子类,使用到__init__和__str__两个内置的方法
2.准备一个add_item方法准备添加家具
3.使用房子类,创建一个房子对象
4.让房子对象调用三次add_item方法,将三件家具以实参的形式进行传递到add_item
"""
# 定义家具类
class HouseItem():
    # 初始化方法
    def __init__(self, name, area):   # 属性
        self.name = name
        self.area = area
    def __str__(self):     # 方法
        return '%s占地面积是%.2f平方米'%(self.name, self.area)
# 创建家具(对象)
bed = HouseItem('bed',40)
print bed
chest = HouseItem('chest',69)
print chest
table = HouseItem('table',61)
print table
# 创建房子类
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
        else:
            # 将家具添加到列表中
            self.Item_list.append(item.name)
            # 计算剩余面积
            self.free_area -= item.area
# 创建房子对象
my_home = House('两室一厅',100)
# 添加家具
my_home.add_Item(bed)
my_home.add_Item(chest)
my_home.add_Item(table)
print my_home

这里写图片描述
这里写图片描述
这里写图片描述

七、继承就是子类拥有父类的所有方法和属性也可以保留自己特性

面向对象的三大特性:
1.封装:根据职责将属性和方法封装到一个抽象的类中
2.继承:实现代码的重用,相同的代码不需要重复的写
3.多态:不同的对象调用相同的方法,产生不同的结果,增加代码的灵活性
单继承:
1.继承的概念语法和特点:
继承的概念:子类拥有父类的所有方法和属性
只需要封装自己特有的属性和方法
2.继承的语法:
class 类名(父类)
    def 子类特有的方法和属性

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 '喵喵~'
    # 子类中根据自己特有的属性,封装自己特有的属性和方法
huhu = Cat()
huhu.call()
huhu.eat()
huhu.run()
huhu.drink()
huhu.sleep()

这里写图片描述
这里写图片描述

2、继承的传递性:(爷爷,父亲,儿子)

C类从B类继承,B类从A类继承
那么C类具有A类和B类的所有方法和属性

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 '你好!!!'
huhu = HelloKitty()
huhu.speak()
# 子类可以继承父类的所有属性和方法
huhu.call()
# 继承的传递性,子类拥有父类和父父类的所有属性和方法
huhu.eat()
huhu.run()
huhu.drink()
huhu.sleep()

这里写图片描述
这里写图片描述

4、子类重写父类有两种情况

覆盖父类的方法
对父类方法进行扩展

5、覆盖父类的方法

如果在开发中,父类的方法的实现和子类的方法的实现完全不同
就可以使用覆盖的方法在子类中重写父类的方法
具体实现方式:
就相当于在子类中定义了一个和父类同名的方法并且
实现重写之后,在运行时,只会调用子类的重写方法
而不会调用父类的重写方法

6、覆盖父类案例

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 '哈哈哈'
huhu = HelloKitty()
huhu.call()

这里写图片描述
这里写图片描述

7、对父类的方法进行扩展

如果在开发中,子类的方法实现含有父类的方法是先
(父类原本封装的方法实现是子类方法的一部分,就可以使用扩展方法)
在子类中重写父类的方法
在需要的位置使用父类名.方法(self)来调用父类
方法的执行(使用父类名称调用父类方法)
代码其他的位置针对子类的需求,编写子类特有的属性和方法

8、扩展父类案例01

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 'ouhayou'
        Cat.call(self)
        print '#@!#@!#@!'
huhu = HelloKitty()
huhu.call()

这里写图片描述
这里写图片描述

9、扩展父类案例02

class Bird():
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print 'Aaaaa...'
            self.hungry = False
        else:
            print 'no Thanks!!!'
class SongBird(Bird):
    def __init__(self):
        self.sound = 'Squawk'
        # 如果不加的话就会hungry就会被覆盖访问eat的时候找不到就会报错,所以我们要使用扩展的方法
        Bird.__init__(self)
    def sing(self):
        print self.sound
bird = Bird()
bird.eat()

littlebird = SongBird()
littlebird.eat()
littlebird.sing()

这里写图片描述
这里写图片描述

10、多继承

子类拥有一个父类叫单继承
子类可以拥有多个父类,并且具有所有父类的属性和方法
例如:孩子会继承自己父亲和母亲的特性
语法:
class 子类名(父类名1,父类名2...)
    pass  进行占位

11、简单的A,B,C多继承

class A(object):
    def test(self):
        print 'test 方法'
class B(object):
    def demo(self):
        print 'demo 方法'
class C(A,B):
    """多继承可以让子类对象同时具有多个父类的属性和方法"""
    pass
c = C()
c.demo()
c.test()

这里写图片描述

12、按照继承顺序继承

class A(object):   # 加入object为新式类
    def test(self):
        print 'A---->test 方法'
    def demo(self):
        print 'A---->demo 方法'
class B(object):
    def test(self):
        print 'B---->test 方法'
    def demo(self):
        print 'B---->demo 方法'
class C(B,A):
    # 有相同的类方法名字按照继承顺序进行继承
    pass
c = C()
c.demo()
c.test()

这里写图片描述

八、多态

多态即不同的子类对象调用相同的方法,产生不同的执行结果

1、子类对象1调用

class Dog(object):
    def __init__(self, name):
        self.name = name
    def game(self):
        print '%s蹦蹦跳跳地玩耍'%self.name
class Huskie(Dog):
    def game(self):
        print '%s爱吃好吃的' %self.name
class Person(object):
    def __init__(self,name):
        self.name = name
    def game_with_dog(self,cat):   #cat是形参,可以随意指定
        print '%s和%s快乐的玩耍'%(self.name,cat.name)
        cat.game()

# 1.创建一个狗对象
wangcai = Dog('旺财')
# 2.创建一个人对象
jane = Person('囡囡')
# 3.让囡囡和狗狗玩耍
jane.game_with_dog(wangcai)

这里写图片描述
这里写图片描述

2、子类对象1调用

class Dog(object):
    def __init__(self, name):
        self.name = name
    def game(self):
        print '%s蹦蹦跳跳地玩耍'%self.name
class Huskie(Dog):
    def game(self):
        print '%s爱吃好吃的' %self.name
class Person(object):
    def __init__(self,name):
        self.name = name
    def game_with_dog(self,cat):   #cat是形参,可以随意指定
        print '%s和%s快乐的玩耍'%(self.name,cat.name)
        cat.game()

# 1.创建一个狗对象
# 用二哈来调用
wangcai = Huskie('旺财')
# 2.创建一个人对象
jane = Person('囡囡')
# 3.让囡囡和狗狗玩耍
jane.game_with_dog(wangcai)

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/janenancy/article/details/81171728