Top

面向对象初识

一、函数式编程和面向对象的对比

  面向过程:根据业务逻辑从上到下垒代码;

  函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可;

  面向对象:对函数进行分类和封装,让开发“更快更好更强...”;

  面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。

  round 1 请开发一个消息提醒的功能(邮件/短信/微信)

    def email(em,text):
        """
        发送邮件
        """
        print(em,text)

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

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

    # 编写功能:假设用户购买课程,然后给管理员发送提醒;
    if 1==1:
        msg('188888888','xx购买了一个学位课')
        email('alex@sb.com','xx购买了一个学位课')
        wechat('微信号','xx购买了一个学位课')
函数式
    class Message:
        def email(self, em, text):
            """
            发送邮件
            """
            print(em,text)

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

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

    # 编写功能:假设用户购买课程,然后给管理员发送提醒;
    if 1==1:
        obj = Message()
        obj.email('alex@sb.com', 'xx购买了一个学位课')
        obj.msg('188888888','xx购买了一个学位课')
        obj.wechat('微信号','xx购买了一个学位课')
面向对象

  通过第一轮对比,我们发现:

    函数式的特点是:定义简单,调用简单;

    面向对象的特点是:定义复杂,调用复杂,其好处是进行了归类,将某些类似的函数写在了一起。

总结: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()

  round 2 打印:完成以下功能:

              老狗/20岁/男/上山去砍柴

              老狗/20岁/男/开车去东北

              老狗/20岁/男/喜欢大宝剑

    def kc(name,age,gender):
        data = "%s,性别%s,今年%s岁,喜欢上山砍柴" %(name,gender,age)
        print(data)

    def db(name,age,gender):
        data = "%s,性别%s,今年%s岁,喜欢开车去东北" %(name,gender,age)
        print(data)

    def bj(name,age,gender):
        data = "%s,性别%s,今年%s岁,喜欢大宝剑" %(name,gender,age)
        print(data)

    kc('老狗',20,'')
    db('老狗',20,'')
    bj('老狗',20,'')
函数版本
    class LaoGou:
    
        def __init__(self,name,age,gender): 
        # 特殊的方法,如果 类名() ,则该方法会被自动执行 (构造方法)
            self.n1 = name
            self.n2 = age
            self.n3 = gender
    
        def kc(self):
            data = "%s,性别%s,今年%s岁,喜欢上山砍柴" %(self.n1,self.n3,self.n2)
            print(data)
    
        def db(self):
            data = "%s,性别%s,今年%s岁,喜欢开车去东北" %(self.n1,self.n3,self.n2)
            print(data)
    
        def bj(self):
            data = "%s,性别%s,今年%s岁,喜欢大宝剑" %(self.n1,self.n3,self.n2)
            print(data)
    
    obj = LaoGou('老狗',20,'')
    obj.kc()
    obj.db()
    obj.bj()
    
面向对象版本

总结:1、构造方法

  # 示例一:
  class Foo:

      def __init__(self,name):     # 构造方法,目的是进行数据初始化.
          self.name = name
          self.age = 18    # 也可以指定值,不一定非要传参

  obj = Foo("alex")  
  # 通过构造方法,可以将数据进行打包,以后使用时,去其中获取即可.

    # 示例二:
  class Bar:
      pass 
  obj = Bar()

    2、面向对象编程应用:

              2.1 将数据封装到对象中,以供自己在方法中调用,如下示例:

  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()
          # ...
       
      def read_last(self):
          # self.f.read()
          # ...
        
      def read_second(self):
          # self.f...
          # ...

  obj = FileHandler('C:/xx/xx.log')
  obj.read_first()
  obj.read_last()
  obj.read_second()
  obj.f.close()

    2.2 将数据封装到对象中,以供其他函数调用,如下示例:

  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(11,22,66)
  new_func(obj)

  注:JavaC#只支持面向对象编程,而python比较灵活既支持面向对象编程也支持函数式编程。

二、面向对象代码如何编写

1、面向对象代码语法规则,如下示例:
  class Foo:

      def __init__(self, name):
          self.name = name

      def detail(self, msg):
          print(self.name, msg)

  obj = Foo("alex")
  obj.detail("hello world")
2、什么时候写面向对象代码?如何写?

  2.1 反向:归类 + 提取公共值;

  2.2 正向:在指定类中编写和当前类相关的所有代码 + 提取公共值;如下示例:

  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 = self.fight - 10

      def practice(self):
          self.fight = self.fight + 90

      def incest(self):
          self.fight = self.fight - 666

  cang = Person('苍井井', '', 18, 1000)  # 创建苍井井角色
  dong = Person('东尼木木', '', 20, 1800)  # 创建东尼木木角色
  bo = Person('波多多', '', 19, 2500)  # 创建波多多角色

  dong.grassland()

二、面向对象三大特征:封装、继承、多态

1、封装

              1.1 将相关方法封装到一个类中,如下示例:

  class Message:
      def email(self):pass
      def msg(self):pass
      def wechat(self):pass

    1.2 将数据封装到一个对象中,如下示例:

  class Person:
      def __init__(self, name, age, gender):
          self.name = name
          self.age = age
          self.gender = gender

  obj = Person('alex', 18, '')
2、继承(原则:先在自己类中找,没有就去父类中找)

  如下示例:

  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()
  # 父类和子类都是相对的,此例中Base是SupperBase的子类,是Foo的父类

总结:1)继承编写规则,如下:

             class Foo(父类名):

        pass

     2)支持多继承,即一个子类可以有多个父类(先找左边父类,再找右边)

          3)为什么要有继承和多继承?提高代码的可重用性

继承的相关练习题:

  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()   # 实例化Foo类的一个obj对象
  obj.f0()
  # 结果为:
  # foo.f0
  # base2.f3
  # base1.f1

总结:1)多继承先找左边

        2)明确self到底是谁,self是哪个类的对象,那么就从该类开始找(自己没有就找父类)

3、多态

              鸭子模型,只要可以嘎嘎叫就是鸭子。由于Python函数传参时,无需指定类型。

    def func(arg): # arg可以是多种类型,只要其中有send方法即可.
        arg.send()

              多态就是多种形态或多种状态,由于python原生支持多态,所以没有特殊性,如下是体现python原生多态的示例:

    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)  
    # func的参数可以是Foo1的实例化对象,也可以是Foo2或者Foo3的实例化对象
python原生多态示例

 

posted @ 2018-08-27 17:25  勇敢的巨蟹座  阅读(170)  评论(0编辑  收藏  举报