day22

1.概要

# 面向过程:根据业务逻辑从上到下写垒代码
# 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
# 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

2. 函数式编程和面向对象对比

# 需求:请开发一个消息提醒的功能(邮件 / 短信 / 微信)

(1)函数实现:
def email(em, text):
    """
    发送邮件
    :return:
    """
    print(em, text)

def msg(tel, text):
    """
    发送短信
    :return:
    """
    print(tel, text)

def wechat(num, text):
    """
    发送微信
    :return:
    """
    print(num, text)

# 编写功能:假设用户购买课程,然后给alex发送提醒;
if 1 == 1:
    msg('188888888', '张进购买了一个学位课')
    email('alex@sb.com', '张进购买了一个学位课')
    wechat('xxxx', '张进购买了一个学位课')

(2)面向对象实现:
class Message:
    def email(self, em, text):
        """
        发送邮件
        :return:
        """
        print(em, text)

    def msg(self, tel, text):
        """
        发送短信
        :return:
        """
        print(tel, text)

    def wechat(self, num, text):
        """
        发送微信
        :return:
        """
        print(num, text)

# 编写功能:假设用户购买课程,然后给alex发送提醒;
if 1 == 1:
    obj = Message()
    obj.email('alex@sb.com', '张进购买了一个学位课')
    obj.msg('188888888', '张进购买了一个学位课')
    obj.wechat('xxxx', '张进购买了一个学位课')

    对比:
        函数: 定义简单 / 调用简单
        面向对象: 定义复杂 / 调用复杂
        好处: 归类, 将某些类似的函数写在一起

    总结:
        1.函数式编程可能会比面向对象好.
        2.Python中支持两种编程方式.
        3.面向对象方式格式:
            定义:
                class 类名:  # - 定义了一个类
                    def 函数名(self):  # -> 在类中编写了一个"方法"
                        pass
        
            调用:
                x1 = 类名()  # -> 创建了一个对象 / 实例化一个对象
                x1.函数名()  # -> 通过对象调用其中一个方法.

        4.示例:
        class Account:
            def login(self):
                user = input('请输入用户名:')
                pwd = input('请输入密码:')
                if user == 'alex' and pwd == 'sb':
                    print('登录成功')
                else:
                    print('登录失败')
        
        obj = Account()
        obj.login()

3. 面向对象代码如何编写

3.1 创建类和对象
    (1)类和对象
        面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用
    
        类: 类就是一个模板,模板里可以包含多个函数,函数里实现一些功能
        对象: 对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

    (2) 创建类和对象如下图
        class是关键字,表示类
        创建对象,类名称后加括号即可

        ps:类中的函数第一个参数必须是self(详细见:类的三大特性之封装)
    类中定义的函数叫做 “方法”
3.2 构造方法(函数)
    (1)什么是构造方法?
        示例1
        class Foo:
            def __init__(self,name):  # 特殊的方法(构造方法),如果 类名(),则该方法会被自动执行,目的进行数据初始化。
                 self.name = name
                 self.age = 18
                            
        obj = Foo('闫康琪')
     类名+括号 -> 实例化(创建对象),会自动触发__init__(构造函数)
   总结: (1)通过构造方法可以将数据进行打包,以后使用时,去其中获取即可
        (2)__init__(构造方法)是一个特殊的方法,在对象实例化时会被调用,它的作用是初始化 示例2
class Bar: pass obj = Bar() # 类后面写了个空的,表示类里面没有构造方法 (2)应用 a.将数据封装到对象中, 以供自己在方法中调用 class FileHandler: def __init__(self, file_path): self.file_path = file_path self.f = open(self.file_path, 'rb') def read_first(self): # self.f.read() # ... pass def read_last(self): # self.f.read() # ... pass def read_second(self): # self.f.read() # ... pass obj = FileHandler('C:/xx/xx.log') obj.read_first() obj.read_last() obj.read_second() obj.f.close() b.将数据封装到对象中, 以供其它数据调用 def new_func(arg): arg.k1 arg.k2 arg.k6 class Foo: def __init__(self, k1, k2, k6): self.k1 = k1 self.k2 = k2 self.k6 = k6 obj = Foo(111, 222, 333) new_func(obj) c.在类的方法内部调用类中的其他方法 class UserInfo: def __init__(self): self.name = None def info(self): print("当前用户名称:%s" % (self.name)) def account(self): print("当前用户%s的账单是:..." % (self.name)) def shopping(self): print("当前用户%s购买了一个人形抱枕" % (self.name)) def login(self): user = input("请输入用户名:") pwd = input("请输入密码:") if pwd == 'sb': self.name = user while 1: print(""" 1. 查看用户信息 2. 查看用户账单 3. 购买抱枕 """) num = int(input("请输入选择的序号:")) if num == 1: self.info() elif num == 2: self.account() elif num == 3: self.shopping() else: print("序号不存在,请重新输入") else: print("登陆失败") obj = UserInfo() obj.login()
3.3 规则
    class Foo:  # 创建类
            def __init__(self):  # 构造函数
                self.name = name
                
            def detail(self,msg):  # 其他函数
                print(self,name,msg)
        
    obj = Foo()  #创建对象/实例化
    obj.detail()  # 通过对象执行内部的方法
    
    实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

    实例化的过程就是: 类——>对象的过程
3.4 什么时候写?如何写?
    方式一: 归类 + 提取公共值
        归类:
            class File:
                def file_read(self, file_path):
                    pass
    
                def file_update(self, file_path):
                    pass
    
                def file_delete(self, file_path):
                    pass
    
                def file_add(self, file_path):
                    pass
    
    
            class Excel:
                def excel_read(self):
                    pass
    
                def excel_update(self):
                    pass
    
                def excel_delete(self):
                    pass
    
                def excel_add(self):
                    pass
    
        提取公共值:
            class File:
                def __init__(self, file_path):
                    self.file_path = file_path
    
                def file_read(self):
                    pass
    
                def file_update(self):
                    pass
    
                def file_delete(self):
                    pass
    
                def file_add(self):
                    pass
    
    
            class Excel:
                def __init__(self, file_path):
                    self.file_path = file_path
    
                def excel_read(self):
                    pass
    
                def excel_update(self):
                    pass
    
                def excel_delete(self):
                    pass
    
                def excel_add(self):
                    pass
    
    方式二: 在指定类中编写和当前类相关的所有代码 + 提取公共值
        class Message:
            def email(self):
                pass
    
        class Person:
            def __init__(self, na, gen, age, fig)
                self.name = na
                self.gender = gen
                self.age = age
                self.fight = fig
    
            def grassland(self):  # 草丛战斗
                self.fight = fig - 10
    
            def practice(self):  # 自我修炼
                self.fight = fig + 90
    
            def incest(self):  # 多人游戏
                self.fight = fig - 666
    
        cang = Person('苍井井', '', 18, 1000)  # 创建苍井井角色
        dong = Person('东尼木木', '', 20, 1800)  # 创建东尼木木角色
        bo = Person('波多多', '', 19, 2500)  # 创建波多多角色
    
        dong.grassland()  # 东尼木木草丛战斗
4. 面向对象的三大特性: 封装/继承/多态
4.1 封装
    (1) 将相关功能封装到一个类中
        class Message:
            def email():pass
            def msg():pass
            def wechar():pass
                
    (2) 将数据封装到一个对象中            
        class Person:
            def __init__(self,name,age,gender):
                self.name = name
                self.age = age
                self.gender = gender
                    
        obj = Person('闫子哲',26,'男')

   封装的用法: (1)将相关功能封装到一个类中
         (2)将数据封装到一个对象中
4.2 继承
    (1)单继承:
        class SuperBase:
            def f3(self):
                print('f3')

        class Base(SuperBase):     # 父类,基类
            def f2(self):
                print('f2')

        class Foo(Base):    # 子类,派生类
            def f1(self):
                print('f1')

        obj = Foo()
        obj.f1()
        obj.f2()
        obj.f3()
        # 原则:先在自己类中找,没有就去父类中找
    
    (2)多继承
        class Base1:
            def show(self):
                print('Base1.show')
        
        class Base2:
            def show(self):
                print('Base2.show')
        
        class Foo(Base1,Base2):
            pass
        
        obj = Foo()
        obj.show()  # Base1.show
        # 原则左边父类的更亲,先去找左边的父类
        
        总结:
            1. 继承编写
                class Foo(父类):
                    pass
            
            2. 支持多继承(先找左/再找右)   # java不支持多继承
            
            3. 为什么要有多继承? 提高代码重用性
            
        练习: 找到self到底是谁的对象? 从谁开始找
            class Base1:
                def f1(self):
                    print('base1.f1')
                def f2(self):
                    print('base1.f2')
            
            class Base2:
                def f1(self):
                    print('base2.f1')
            
                def f2(self):
                    print('base2.f2')
            
                def f3(self):
                    print('base2.f3')
                    self.f1()
            
            class Foo(Base1,Base2):
                def f0(self):
                    print('foo.f0')
                    self.f3()
            # 1. 多继承先找左边的
            # 2. self到底是谁,self是哪个类的对象,那么就从该类开始找(自己没有就找父类)
            
            obj = Foo()
            obj.f0()    
            结果:
                foo.f0
                base2.f3
                base1.f1
4.3 多态
    多种形态或多种状态
    鸭子模型,只要可以嘎嘎叫就是鸭子.
        
        python
        # 由于python原生支持多态,所以没有什么特殊性
            class Foo1:
                def f1(self):
                    pass
            
            class Foo2:
                def f1(self):
                    pass
            
            class Foo3:
                def f1(self):
                    pass
                    
            def func(arg):  # 这里的传进来的arg可以是多种形态的
                arg.f1()
                
            obj = Foo1()  # obj = Foo2()    obj = Foo3()
            func(obj)  # 这里obj可以是Foo2(), 也可以是 Foo3()
        
        # java
            class Son(list):
                pass 
            
            class Son1(list):
                pass 
            
            # 以后传参时,arg可以是:list类的对象/list任何子类的对象
            public void func(list arg){
                print(arg)
            }
            
            # obj = list()
            # obj = Son()
            obj = Son1()
            func(obj)

5. 本节重点

1. 编写方式+执行流程

2. 如何归类?
 反向:归类+提取公共值 反向->把函数写出来了再归类,写出来了再改面向对象,耗时间
 正向:类相关的功能+提取公共值 正向->写好类,直接在类下面写方法,在脑子里提前设计好

3. 三大特性
 封装/继承/多态

 

posted @ 2019-09-20 11:16  magickang  阅读(138)  评论(0编辑  收藏  举报