一、面向对象和面向过程

面向过程:核心过程二字,过程即解决问题的步骤,就是先干什么后干什么,基于该思想写程序就好比这是一条流水线,是一种机械式的思维方式。

  • 优点:复杂的过程流程化
  • 缺点:扩展性差

面向对象:核心是对象二字,对象特征与技能的结合体,基于该思想编写程序就好比在创造一个世界,世界是由一 个个对象组成,是一种上帝的思维方式。

  • 优点:可扩展性强
  • 缺点:编程复杂度高,极容易出现过度设计的问题

二、类

对象是特征与技能的结合体,类就是一系列对象相似的特征与技能的结合体
在现实生活中:一定是先有一个个具体的对象,后总结出类
在程序中L一定是先定义类,后产生对象

例:定义一个学生类,特征是都属于学校,技能是都会跑

class Students:
    school = '学校'
    #初始化
    def __init__(self,name,phone):
        self.name = name
        self.phone = phone

    def run(self):
        print('running......')

stu1 = Students('bob', 110)
print(stu1.name)
print(stu1.phone)
stu1.run()
stu2 = Students('mike', 120)
print(stu2.name)
print(stu2.phone)
stu2.run()
输出:
bob
110
running......
mike
120
running......

三、面向对象有三大特性

1.封装
  1. 封装是面向对象的一大特点
  2. 面向对象编程的第一步——将属性和方法封装到一个抽象的类当中
  3. 外界使用类创建对象,然后让对象调用方法
  4. 对象方法的细节都封装在类的内部

例:小明爱跑步
  需求:

- 小明体重75公斤
	 - 小明每次跑步都会减肥0.5公斤
	 - 小明每次吃东西体重会增加1公斤
class Person: #定义一类人
    def __init__(self,name,weight): #初始化
        self.name = name
        self.weight = weight
    def run(self):              #技能跑
        self.weight -= 0.5      #减肥0.5公斤
    def eat(self):              #技能吃
        self.weight += 1        #增肥1公斤
    def __str__(self):         
        return '%s的体重是:%s' % (self.name, self.weight)  #返回的内容就是需要打印输出对象

xiaoming = Person('小明',75)
xiaoming.eat()    #引用的方法
xiaoming.eat()
xiaoming.run()
print(xiaoming)
输出:
小明的体重是:76.5

封装案例
需求:
    1、房子有户型、总面积、家具名称列表
      房子没有任何家具
    2、家具有名字和占地面积,其中
      席梦思(bed):4平米
      衣柜(chest): 2平米
      餐桌(table): 1.5平米
    3、将以上3个家具添加到房子中
    4、打印房子中,要求输出:户型、总面积、剩余面积、家具名称列表
首先分析出:
1.房子是一类,它的特征是户型,总面积,技能是添加家具
2.家具是一类,它的特征是名字和占地面积
3.一般定义先定义小的,再定义大的

class Items():
    def __init__(self,name,area):
        self.name = name
        self.area = area

class House():
    def __init__(self,house_type,total_area):
        self.house_type = house_type
        self.total_area = total_area
        self.free_area = total_area
        self.items = []
    def add_item(self,item):
        if self.free_area >= item.area:
            self.free_area -= item.area
            self.items.append(item.name)
        else:
            print('面积太大,放不进去')
    def __str__(self):
        return '户型:%s|总面积:%s|剩余面积:%s|家具名称列表:%s' % (self.house_type, self.total_area,self.free_area,self.items)

#实例化家具
bed = Items('席梦思',4)
chest = Items('衣柜',2)
table = Items('餐桌',1.5)
#实例化房子
house = House('地下室',20)
#添加家具
house.add_item(bed)
house.add_item(chest)
house.add_item(table)
print(house)
输出:
户型:地下室|总面积:20|剩余面积:12.5|家具名称列表:['席梦思', '衣柜', '餐桌']
2.继承

继承实现代码的重用,相同的代码不需要重复的编写

单继承:就是一个类只继承一个父类
多继承:就是一个类继承多个父类

例:单继承

class Anamal(object):#新式类   不写object为旧式类
    def eat(self):
        print('吃')
    def drink(self):
        print('喝')
    def run(self):
        print('跑')
    def sleep(self):
        print('睡')
class Dog(Anamal):
    def bark(self):
        print('汪汪叫')
class WangCai(Dog):
    def jump(self):
        print('跳')

dog = WangCai()
dog.eat()
dog.drink()
dog.run()
dog.sleep()
dog.bark()
dog.jump()
输出:
吃
喝
跑
睡
汪汪叫
跳

例:多继承

class Anamal(object):
    def eat(self):
        print('吃')
    def drink(self):
        print('喝')
    def run(self):
        print('跑')
    def sleep(self):
        print('睡')
class Dog(object):
    def bark(self):
        print('汪汪叫')
class WangCai(Dog,Anamal):
    def jump(self):
        print('跳')

dog = WangCai()
dog.eat()
dog.drink()
dog.run()
dog.sleep()
dog.bark()
dog.jump()
输出:
吃
喝
跑
睡
汪汪叫
跳

例:多继承中继承相同技能存在先后。子类调用参数谁在前继承谁

class Anamal(object):
    def eat(self):
        print('吃')
    def drink(self):
        print('喝')
    def run(self):
        print('跑')
    def sleep(self):
        print('睡')
    def bark(self):
        print('哼哼叫')
class Dog(object):
    def bark(self):
        print('汪汪叫')
class WangCai(Dog,Anamal): #Dog类在前继承Dog的
    def jump(self):
        print('跳')
dog = WangCai()
dog.bark()
输出:汪汪叫

继承方法的重写

class Anamal(object):
    def eat(self):
        print('吃')
    def drink(self):
        print('喝')
    def run(self):
        print('跑')
    def sleep(self):
        print('睡')
class Dog(object):
    def bark(self):
        print('汪汪叫')
class WangCai(Dog):
    def jump(self):
        print('跳')
    def bark(self):
        print('乱叫......')

dog = WangCai()
dog.bark()
输出:
乱叫......

对父类方法的扩展

class Anamal(object):
    def eat(self):
        print('吃')
    def drink(self):
        print('喝')
    def run(self):
        print('跑')
    def sleep(self):
        print('睡')
class Dog(object):
    def bark(self):
        print('汪汪叫')
class WangCai(Dog):
    def jump(self):
        print('跳!')
    def bark(self):
        super().bark()
        print('乱叫......')

dog = WangCai()
dog.bark()
输出:
汪汪叫
乱叫......
3.多态

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

  1. 多态可以增加代码的灵活度
  2. 以继承和重写父类方法为前提,才能实现多态
  3. 是调用方法的技巧,不会影响到类的内部设计
    多态的特性:让不同的子类对象调用相同的代码产生不同的结果

例:

class Dog(object):
    def __init__(self, name):
        self.name = name
    def game(self):
        print('%s 开开心心去玩耍.....' % self.name)
class WangCai(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()
#创建人对象
xiaoming = Person('小明')
#创建狗对象
dog = Dog('阿黄')
#让小明跟狗玩耍
xiaoming.game_with_dog(dog)
输出:
小明 和 阿黄 正在开开心心的玩耍......
阿黄 开开心心去玩耍.....
class Dog(object):
    def __init__(self, name):
        self.name = name
    def game(self):
        print('%s 开开心心去玩耍.....' % self.name)
class WangCai(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()
#创建人对象
xiaoming = Person('小明')
#创建狗对象
dog = WangCai('旺财')
#让小明跟狗玩耍
xiaoming.game_with_dog(dog)
输出:
小明 和 旺财 正在开开心心的玩耍......
旺财 开开心心去玩耍.....