基于python下的面向对象以及其三大特点

先来了解面向对象和面向过程是什么?

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

面向对象和面向过程有啥区别?

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

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

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

简单的类设计:

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

需求:
小明今年18岁,身高1.75,每天早上要跑步,会去吃东西
小美今年17岁,身高1.65,不跑步,小美喜欢吃东西
Person()
name    #  属性
age
height
run()   # 方法
eat()
一只黄颜色的狗狗叫大黄
看见生人旺旺叫
看见主人摇尾巴
Dog()
color   #  属性
name
shout() #   方法
shake()
"""

这里写图片描述

面向对象的基础语法:

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

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

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

这里写图片描述

一个类可以创建多个对象:

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

这里写图片描述
输出结果:
这里写图片描述

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

# 创建狗对象
doudou = Dog()
#doudou.name = 'doudou'   # 单独的赋值属性
doudou.eat()
doudou.play()
doudou.name = 'doudou'
#  如果在运行中没有找到属性,程序会报错

这里写图片描述

初始化方法:

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

这里写图片描述

直接调用初始化不加入形参在有两个类的时候程序会出现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()

这里写图片描述

调用初始化加入形参:

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.多态:
    不同的子类对象调用相同的方法,产生不同的执行结果

封装:

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

简单的封装案例:

需求:
xx爱跑步,xx体重是75公斤
跑一次步减肥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
xfl = Person('XFL',75.0)
xfl.run()
xfl.eat()
print xfl
"""
需求:
xx和xxx爱跑步
xx体重是75公斤,xxx的体重是52公斤
跑一次步减肥0.5公斤,吃一次东西增肥1公斤
"""
xyy = Person('XYY',52.0)
xyy.run()
xyy.eat()
print xyy

这里写图片描述
程序输出:
这里写图片描述

士兵开枪案例:

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   #返回的是内存地址

这里写图片描述

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

# _*_ coding:utf-8 _*_
"""
file: 摆放家具.py
date:2018-07-21 1:44 PM
author: xfl
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

这里写图片描述

摆放家具进阶版:

# _*_ coding:utf-8 _*_
"""
file: 摆放家具2.0.py
date:2018-07-21 2:32 PM
author: xfl
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 子类特有的方法和属性

简单的动物特性继承:

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()

这里写图片描述

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

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

动物特性继承:(三个类依次继承)

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()

这里写图片描述

子类重写父类有两种情况:

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

覆盖父类的方法:

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

覆盖父类案例:

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()

这里写图片描述

对父类的方法进行扩展:

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

扩展父类案例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()

这里写图片描述

扩展父类案例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()

这里写图片描述

多继承:

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

简单的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()

这里写图片描述

按照继承顺序继承:

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调用:

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.创建一个人对象
xfl = Person('薛飞龙')
# 3.让薛飞龙和狗狗玩耍
xfl.game_with_dog(wangcai)

这里写图片描述

子类对象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.创建一个人对象
xfl = Person('薛飞龙')
# 3.让薛飞龙和狗狗玩耍
xfl.game_with_dog(wangcai)

这里写图片描述

猜你喜欢

转载自blog.csdn.net/aaaaaab_/article/details/81162705