初始面向对象

 

一.函数式编程和面向对象编程区别

  - 函数: 是将某些功能代码封装到函数中,不用重复编写,直接调用函数即可

  - 面向对象: 是对函数分类和封装

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

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

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

# 编写功能:用户购买商品,然后给商家发送提醒
if 1 ==1:
    msg('13522289159','xxx购买了某个商品')
    email('592888935@qq.com','xxx购买了某个商品')
    wechat('xxxxxxx','xxx购买了某个商品')
函数式编程
class Message:
    def email(self,em,text):
        """
        发送邮件
        :param em:
        :param text:
        :return:
        """
        print(em, text)

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

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

 # 编写功能:用户购买商品,然后给商家发送提醒
obj= Message()
obj.msg('13522289159', 'xxx购买了某个商品')
obj.email('592888935@qq.com', 'xxx购买了某个商品')
obj.wechat('xxxxxxx', 'xxx购买了某个商品')
面向对象编程
对比:
函数: 定义简单/调用简单
面向对象: 定义复杂/调用复杂 好处:归类/将某些类似的方法(函数)写在一起
总结:
  函数式编程可以会比面向对象编程好
  python支持两种编程方式

二.类与对象


  面向对象编程核心二字即:'对象'
  可以把类看做是一个包,包里可以包含多个函数,每个函数实现一个功能
  对象则是根据包创建的一个实例,通过实例可以调用包里的函数
定义:
class Foo:        # 定义了一个类,Foo为类名

    def func():   # 在类中编写了一个方法(单独称为函数,放到类中一般都被称为方法)
        pass

调用:
obj = Foo()      # 创建了一个对象/实例化一个对象
obj.func()       # 通过对象调用类中的方法

  class 是关键字,表示你将要创建一个类

  创建对象即类名称加括号

  提示: 类名定义的时候第一个字母大写,或每个单词的首字母大写(潜规则,可以看出你是不是个老司机)

 练习题:

  

class Account:
    def login(self):
        user = input('请输入用户名:')
        pwd = input('请输入密码:')
        if user == 'alex' and pwd == 'SB':    # SB即:烧饼
            print('登录成功')
        else:
            print('登录失败')


obj = Account()
obj.login()
用户登录

三.三大特性

三大特性:封装/继承/多态
  - 封装(顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容)
    将相关功能封装到一个类中
class Message:
     def email(self):pass
     def msg(self):pass
     def wechat(self):pass
    将数据封装到一个对象中
class Person:
     def __init__(self,name,age,gender):
         self.name = name
         self.age = age
         self.gender = gender

 obj1 = Person('侯明巍',18,'')
obj2 = Person('房文磊',16,'女')

self 是一个形式参数,当执行 obj1 = Person('侯明巍',18,'男' ) 时,self 等于 obj1

                  当执行 obj2 = Person('房文磊',16,'女' ) 时,self 等于 obj2

所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和 age 及 gender 属性,在内存分别开辟两个空间来保存。

"""
完成以下功能:
    老狗/20岁/男/上山去砍柴
    老狗/20岁/男/开车去东北
    老狗/20岁/男/喜欢大宝剑
"""


class LaoLi:
    def __init__(self,name,age,gender):              # 特殊的方法,如果 类名(),则该方法会被自动执行  (构造方法)
        self.name = name
        self.age = age
        self.gender = gender

    def kc(self):
        data = "%s,%s,今年%s,喜欢上山去砍材" % (self.name, self.gender, self.age)
        print(data)

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

    def bj(self):
        data = "%s,%s,今年%s,喜欢去做大保健" % (self.name, self.gender, self.age)
        print(data)

obj = LaoLi('老狗',20,'')
obj.kc()
obj.db()
obj.bj()
练习题

  - 继承(面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容)
    - 单继承
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()

原则: 先在自己的类中找,找不到去父类找
站的角度不同,对待父类和子类的定义也不同,子类也有可能是别的类的父类


    - 多继承
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()

# 左边比右边更亲

总结:
  1. 继承编写
  2. python支持多继承
  3.为什么要有继承: 提高代码的重用性

  - 多态(多种形态和多种状态)
    python原生支持多态,所有没有特殊性
    其Python崇尚“鸭子类型”
class F1:
    pass

class S1(F1):

    def show(self):
        print 'S1.show'

class S2(F1):

    def show(self):
        print 'S2.show'

def Func(args):
    print args.show()

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj)
由于python函数在传参时没无需指定类型,args可以是多种类型,只要其中有seed方法即可


总结:
  以上对面向对象知识总结
    - 面相对象是一种编程方式,此编程方式的实现是基于对'类'和'对象'的使用
    - 类是一个包,包中包装了多个'函数'供使用
    - 对象,根据类创建的实例(即:对象),实例用于调用被包装的类中的函数
    - 面向对象的三大特性: 封装/继承/多态
      - 封装
        归类,将函数放置到一个类中
        打包,将数据打包放到一个对象中
      - 继承
        提高代码的重用性
      

四.类的成员

  成员共分为三类:
    1.变量
    2.方法
    3.属性
  1.变量
    实例变量(字段)
      - 公有实例变量(公有字段)
      - 私有实例变量(私有字段)
    类变量(静态字段)
      - 公有类变量(公有静态字段)
      - 私有类变量(私有静态字段)
class Foo:
    # 类变量(静态字段)
    country = '中国'
   # 私有类变量
  
__secret = '贪污受贿'
    def __init__(self,name,age):
        # 实例变量(字段)
        self.name = name
     # 私有实例变量      __self.age = age def func(self): pass
  什么时候用类变量?
    当所有对象中有共同的字段时且要改都改要删都删的时候,可以将实例变量(字段)提取到类变量(静态字段)
  私有变量在函数外部是无法访问的
class Foo:

    def __init__(self,name):
        # 私有实例变量(私有字段)
        self.__name = name       # 在变量前边加 '__'
        self.age = 26

    def func(self):
        print(self.__name)


obj = Foo('侯明巍')
# print(obj.__name)   # 无法访问
print(obj.age)
obj.func()  # 可以让内部的func函数帮助执行内部私有的__name
私有变量如何调用
class Foo:
    __country = '中国'

    def __init__(self):
        pass

    def func(self):
        # 内部调用
        print(self.__country)
        print(Foo.__country)   # 推荐使用类调用

obj = Foo()
obj.func()
# 外部无法调用内部私有类变量
# print(Foo.__country)   # 外部无法调用
私有变量如何调用
############ 无法访问

class Baer(object):
    __secret = '贪污受贿'


class Foo(Baer):

    def func(self):
        print(self.__secret)
        print(Foo.__secret)

obj = Foo()
obj.func()


############ 可以访问
class Baer(object):
    __secret = '贪污受贿'

    def func1(self):
        print(Baer.__secret)

class Foo(Baer):
    def func2(self):
        print(self.__secret)
        print(Foo.__secret)

obj = Foo()
obj.func1()
验证子类也无法调用父类的私有变量
  2.方法
    1.实例方法
      公有实例方法
      私有实例方法
    2.静态方法
      公有静态方法
      私有静态方法
    3.类方法
      公有类方法
      私有类方法
class Foo(object):
    def __init__(self,name):
        self.name = name


    # 实例方法   
    def func1(self):
        print('实例方法')
    # 私有实例方法 
    def __display1(self)
        print('私有方法')       


    # 静态方法 
    @staticmethod
    def func2():
        print('静态方法')
    # 私有静态方法
    def __display2():
        print('私有静态方法')


    # 类的方法. cls是类
    @classmethod
    def func3(cls):
        print(类方法)
    # 私有类方法
    @ classmethod
    def __display(cls)
        print('私有类方法')
静态方法总结:
1.编写时:
- 方法上方写 @staticmethod
- 方法参数(self)可有可无
2.调用时:
- 类.方法名() # 推荐
- 对象.方法名()
3.什么时候写静态方法
- 无需使用对象中封装的值的时候
类方法总结:
1.定义时:
- 方法上方写 @classmethod
- 方法的参数:至少有一个cls的参数
2.执行时:
- 类名.方法名() # 默认会把当前类传到参数中
3.什么时候用类方法
- 如果在方法中会使用到当前类,那么久可以使用类方
静态方法/类方法和实例方法的区别?
  1.定义:
  1.实例方法上方什么也不加
  2.静态方法上方加 @staticmethod
  3.类方法上方加 @classmethod
  2.执行:
  1.实例方法是先实例化,再通过对象.方法名
  2.静态方法是通过类.方法名
  3.类方法是通过类.方法名

  3.属性(通过方法改造出来的)
    公有属性
    私有属性

class Foo(object):

    def __init__(self):
        pass
    # 属性
    @property
    def start(self):
        return "hell word,I's'赛利亚"

    # 私有属性
    @property
    def __end(self):
        return '你好啊,我是赛利亚'
属性总结:
1.编写时
- 方法上方写 @property
- 方法参数: 只有一个self
2.调用时: 无需加括号,直接 对象.方法
3.应用场景: 对于简单的方法,当无需传参且有返回值时,可以使用 @property

  

原文地址:https://www.cnblogs.com/hmw112626/p/9601279.html