day22 python面向对象 封装/继承/多态

day22 python面向对象 封装/继承/多态
 
一.面向对象
1.函数式编程和面向对象的对比
    1.1.对比一: 请开发一个消息提醒的功能(邮件/短信/微信)
        1.1.1.函数式编程: 实现
def email(em,text):
    '''
    send email
    :return:
    '''
    print('send email')
def msg(tel,text):
    '''
    send msg
    :return:
    '''
    print('send msg')
def wechat(num,text):
    '''
    send wechat
    :return:
    '''
    print('send wechat')
#编写功能:假设用户购买课程, 然后给bajie发送提醒, 三个都发
buy = 1
if buy:
    msg('10086','bajie buy a class')
    email('[email protected]','bajie buy a class')
    wechat('3456654','bajie buy a class')
        1.1.2.面向对象: 来实现上面的功能
class Message:
    def email(self,em, text):
        '''
        send email
        :return:
        '''
        print('send email')
    def msg(self,tel, text):
        '''
        send msg
        :return:
        '''
        print('send msg')
    def wechat(self,num, text):
        '''
        send wechat
        :return:
        '''
        print('send wechat')
buy = 1
if buy:
    obj = Message()
    obj.msg('10086', 'bajie buy a class')               #少传了一个参数? 面向对象内部会把obj传给self
    obj.email('[email protected]', 'bajie buy a class')
    obj.wechat('3456654', 'bajie buy a class')
        1.1.3.对比:
            函数时:定义简单/调用简单
            面向对象:定义复杂/调用复杂, 有一个好处是做了一个归类
        1.1.4.总结:
            1.函数式编程可能会比面向对象好
            2.python中支持两种编程方式
            3.面向对象方式的格式:
    定义:
        class 类名:                #定义了一个类
            def 函数名(self):      #至少一个参数, self这个名字就是这个,比较专业   #在类中编写了一个方法
                pass
    调用:
        obj = 类名()               #创建了一个对象或者叫实例化了一个对象
        obj.函数名()               #传参否: 要看定义的时候是否写了参数            #通过对象调用其中的方法
    示例:
class Account:
    def login(self):
        user = input('user: ')
        password = input('password: ')
        if user == 'bajie' and password == 'bajie123':
            print('successful')
        else:
            print('incorrect')
obj = Account()
obj.login()
 
    1.2.对比二: 请帮我打印
        bajie/20/男/上山去砍柴
        bajie/20/男/开车去东北
        bajie/20/男/喜欢大宝剑
        1.2.1.函数式编程
def kc(name,age,gender):
    data = "%s,gender%s,is%syears old,love kc" %  (name,gender,age)
    print(data)
def db(name,age,gender):
    data = "%s,gender%s,is%syears old,love db" %  (name,gender,age)
    print(data)
def bj(name,age,gender):
    data = "%s,gender%s,is%syears old,love bj" %  (name,gender,age)
    print(data)
kc('bajie','20','man')                                                                      #参数反复传递
db('bajie','20','man')
bj('bajie','20','man')
        1.2.2.面向对象编程
class Bajie():
    def __init__(self,name,age,gender):      #类中的一种特殊方法, 当类名()加了个括号, 则该方法会被自动执行
        self.name = name                     # __init__的作用: 把参数封装起来(叫做构造方法)
        self.age = age
        self.gender = gender
    def kc(self):
        data = "%s,gender%s,is%syears old,love kc" %  (self.name, self.gender, self.age)     #参数就是被封装到了self里面
        print(data)
    def db(self):
        data = "%s,gender%s,is%syears old,love db" %  (self.name, self.gender, self.age)
        print(data)
    def bj(self):
        data = "%s,gender%s,is%syears old,love bj" %  (self.name, self.gender, self.age)
        print(data)
 
obj = Bajie('bajie','20','man')               #self 就是obj, 执行完__init__后, 参数就被封装到了self里,就是封装到了obj里
print(obj.name)                               #参数就是被封装到了obj里面
print(obj.age)
print(obj.gender)
obj.kc()
obj.db()
obj.bj()
        1.2.3.总结
                1).构造方法
class Foo:
    def __init__(self,name):                  #构造方法, 目的是进行数据初始化
        self.name = name
        self.age = 18
obj = Foo('bajie')
print(obj.age)
                                              #通过构造方法, 可以将数据进行打包,以后使用时, 去其中获取即可
class Bar:
    pass
obj = Bar()
                2).构造方法的应用: 当多个方法有共同参数的时候可以用
class File_Handler:
    def __init__(self, file_path):
        self.file_path = file_path
        self.f = open(file_path, 'rb')      #文件句柄经常打开,  就可以先打开,然后放到构造方法中,以供在方法中调用
    def read_first(self):
        self.f.readline()
        pass
    def read_last(self):
        self.f.readline()
        pass
    def read_second(self):
        self.f.readline()
        pass
obj =  File_Handler(r'C:\Users\THINKPAD\PycharmProjects\s15\day02\while.py')
obj.read_first()
obj.read_last()
obj.read_second()
obj.f.close()
                2).构造方法的应用: 对数据进行封装给其他函数使用时
#函数参数的封装*arg **kwargs
def func(*args):
    args[2]
    args[5]
def func(**kwargs):
    kwargs['k1']
    kwargs['k2']
 
#面向对象__init__()的封装
def func(obj):
    print(obj.k1)
    print(obj.k2)
    print(obj.k6)
 
class Foo:
    def __init__(self,k1,k2,k6):
        self.k1 = k1
        self.k2 = k2
        self.k6 = k6
obj = Foo(111,222,666)
func(obj)
 
    1.3.对比三: 信息管理系统
        #1.用户登录
        #2.显示当前用户信息
        #3.查看当前用户所有的账单
        #4.购买抱枕
class User_info:
    def __init__(self):
        self.name = None
    def shopping(self):
        print('%s buy a baozhen' % (self.name,))
    def info(self):
        print('current user is: %s' % (self.name,))
    def account(self):
        print('%s s account is ... ...' % (self.name,))
    def login(self):
        user = input('user: ')
        password = input('password: ')
        if password == 'bajie123':
            self.name = user
            print('successful')
            prompt = '''
            1.显示当前用户信息
            2.查看当前用户所有的账单
            3.购买抱枕
            please enter your choice(1/2/3):
            '''
            while True:
                choice = input(prompt)
                if choice == '1':
                    self.info()
                elif choice == '2':
                    self.account()
                elif choice == '3':
                    self.shopping()
                else:
                    print('choice is out of range, please choice again!')
        else:
            print('incorrect')
obj = User_info()
obj.login()
        1.3.1.总结: 类中的方法可以被类的方法调用
class Foo:
    def func2(self):
        print('func2')      
    def func1(self):
        self.func2()
        print('func1')
obj = Foo()
obj.func1()
 
2.面向对象代码如何编写
    2.1.规则
class Foo:
    def __init__(self,name):
        self.name = name
    def detail(self,msg):
        print(self.name, msg)
obj = Foo('bajie')
obj.detail('detail message')
    2.2.什么时候写? 如何写?
        方式一: 归类+提取公共值(反向推导)
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,name,age,gen,flg):
        self.name = name
        self.age = age
        self.gen = gen
        self.flg = flg
    def dajia(self):
        self.flg -= 10
    def practice(self):
        self.flg += 60
 
bajie = Person('bajie',22,'man',1000)
wukong = Person('wukong',66,'man',666)
 
bajie.dajia()
bajie.practice()
wukong.practice()
print(bajie.flg)
print(wukong.flg)
 
3.面向对象三大特性:封装/继承/多态
    3.1.封装:体现了两点
        1)将相关功能封装到一个类中
class Message:
    def email(self):pass
    def msg(self):pass
    def wechart(self):pass
        2)将数据封装到一个对象中
class Person:
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
obj = Person('bajie',33,'man')
print(obj.name)
    
    3.2.继承
        3.2.1.基本使用: 为了复用
class Super_base:
    def f3(self):
        print('in f3')
class Base(Super_base):          #父类,基类
    def f2(self):
        print('in f2')
class Foo(Base):                 #子类,派生类  #父类写到括号里
    def f1(self):
        print('in f1')
obj = Foo()
obj.f1()                         #先在自己类中找
obj.f2()                         #没有再去父类找
obj.f3()
        3.2.2.为何要有继承: 为了复用, 提高代码的重用性
class Base:
    def f1(self):               #如果Foo和Bar都有f1的功能, 那么就可以写到父类里面, 子类可继承f1方法
        pass
class Foo(Base):
    def f2(self):
        pass
class Bar(Base):
    def f3(self):
        pass
        3.2.3.多继承
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()                      #当父层有相同方法的时候, 自己没有时, 先找左边的父层中的方法执行
        3.2.4.继承练习1
class Base:
    def f1(self):
        print('base.f1')
class Foo(Base):
    def f2(self):
        print('foo.f2')
obj = Foo()
obj.f2()                        #都可执行
obj.f1()
obj = Base()
obj.f1()
#obj.f2()                       #找不到f2, 子类会去父类找,但是父类不会去子类找
        3.2.4.继承练习2
class Base:
    def f1(self):
        print('base.f1')
class Foo(Base):
    def f3(self):
        print('foo.f3')
    def f2(self):
        print('foo.f2')
        self.f3()                #self 就是obj. obj是哪个类的对象,就从哪个类开始找
obj = Foo()
obj.f2()
        3.2.4.继承练习3
class Base:
    def f1(self):
        print('base.f1')
    def f3(self):
        print('foo.f3')
class Foo(Base):
    def f2(self):
        print('foo.f2')
        self.f3()
obj = Foo()
obj.f2()
        3.2.4.继承练习4
class Base:
    def f1(self):
        print('base.f1')
    def f3(self):
        self.f1()                 #self 一直是obj, 不论在哪个类中
        print('foo.f3')
class Foo(Base):
    def f2(self):
        print('foo.f2')
        self.f3()
obj = Foo()
obj.f2()
        3.2.4.继承练习5
class Base:
    def f1(self):
        print('base.f1')
    def f3(self):
        self.f1()                   #要先去Foo里面找, 因为self 是Foo类的对象
        print('base.f3')
class Foo(Base):
    def f1(self):
        print('foo.f1')
    def f2(self):
        print('foo.f2')
        self.f3()
obj = Foo()
obj.f2()
obj2 = Base()
obj2.f3()
        3.2.4.总结:
            self 是哪个类的对象, 那么他一直是哪个类的对象, 那么就从自己开始找,没有再去找父类
        3.2.4.继承练习6
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()
obj = Foo()
obj.f0()
        3.2.5.总结:
                1).继承的编写
                    class Foo(父类):pass
                2).支持多继承(先找左)(c3算法找顺序)
                3).为什么要有多继承: 提高代码的重用性
                4).练习部分: 找self到底是谁的对象, 就先从哪开始找
 
 
    3.3.多态:
        在python中不用多说, python原生就支持
        多种状态(形态): args的多态性
        鸭子模型, 只要可以嘎嘎叫就是鸭子
def func(arg):
    arg.send()                  #从这还不知道arg是什么类型
    arg[0]                      #只知道有arg有这个属性和方法: 他可以是列表也可以是元组和字符串,这个参数可以是多个类型, 只要他支持这些功能就足够了
func([1,2,3])                   #这里的参数就是对象: 是列表的对象
func('bajieaishuishui')         #这里的参数就是对象: 是字符串的对象
func((1,))                      #这里的参数就是对象: 是元组的对象
class Foo1:
    def f1(self):pass
class Foo2:
    def f1(self):pass
class Foo3:
    def f1(self):pass
def func(arg):
    arg.f1()
obj = Foo1() #obj = Foo2() #obj = Foo3()
func(obj)
            3.3.1.总结: 由于python原生就是支持多态, 所以没有特殊性; 但是在java里面: 他只能传一种形态, 这时候多态就变得有意义了
 
 
 
 
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/aiaii/p/12191365.html