• 面向对象编程


    面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)

    一、编程类型

    面向过程编程:根据业务逻辑从上到下写垒代码,分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

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

    面向对象编程:对函数进行分类和封装,把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

    二、类和对象

    面向对象编程需要使用 “类” 和 “对象” 来实现

    类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

    对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

     1 class role(object):  #创建一个类,类名role,(object)新式类的写法
     2     ac = None
     3     def __init__(self,name,role,weapon,life_value=100):  #初始化函数,在生成一个角色时要初始化的一些属性就填写在这里
     4         self.name = name
     5         self.role = role
     6         self.weapon = weapon
     7         self.life_value = life_value
     8     def buy_weapon(self,weapon):
     9         print("%s is buying [%s]" %(self.name,weapon))
    10         self.weapon = weapon
    11 
    12 p1 = role("nima",'police',"B11",90)  #创建对象,自动把参数传给Role下面的__init__(...)方法
    13 t1 = role("nimei",'terrorist',"B10",100)  #生成一个角色,相当于 t1, role(t1,'nimei','terrorist','B10',100)
    14 p1.buy_weapon("AK47")  #python 会自动帮你转成 role.buy_weapon(p1,”B21")
    15 t1.buy_weapon("B51")
    16 
    17 p1.ac = "china brand"
    18 role.ac = "us brand"
    19 print("p1:",p1.life_value,p1.ac)
    20 print("t1:",t1.weapon,t1.ac)

    __init__()叫做初始化方法(或构造方法), 在类被调用时,这个方法(虽然它是函数形式,但在类中就不叫函数了,叫方法)会自动执行,进行一些初始化的动作,所以我们这里写的__init__(self,name,role,weapon,life_value=100)就是要在创建一个角色时给它设置这些属性

    三、面向对象三大特性

    1.封装

    封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

    将内容封装到某处

    1 class foo:
    2     def __init__(self,name,age):
    3         self.name = name
    4         self.age = age
    5 
    6 obj = foo('haha',22)  #将haha和22分别封装到obj的name和age属性中

    调用被封装的内容

    1 class foo:
    2     def __init__(self,name,age):
    3         self.name = name
    4         self.age = age
    5 
    6 obj = foo('haha',22) 
    7 print(obj.name)  #通过“对象.属性名”调用被封装的内容
     1 class foo:
     2     def __init__(self,name,age):
     3         self.name = name
     4         self.age = age
     5 
     6     def detail(self):
     7         print(self.name)   #通过“self.name”调用被封装的内容
     8         print(self.age)
     9 
    10 obj = foo('haha',22) 
    11 obj.detail()

    2.继承

    继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

    对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

    通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。

    一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

     1 class SchoolMember(object):  #父类
     2     member_nums = 0
     3     def __init__(self,name,age,sex):
     4         self.name = name
     5         self.age = age
     6         self.sex = sex
     7         self.enroll()
     8 
     9     def enroll(self):
    10         SchoolMember.member_nums +=1
    11         print("the [%s] SchoolMember [%s] is enrolled!" %(self.member_nums,self.name))
    12 
    13     def tell(self):
    14         print("hello my name is %s" %self.name)
    15 
    16 class Teacher(SchoolMember):  #子类,继承父类
    17     def __init__(self,name,age,sex,course,salary):
    18         super(Teacher,self).__init__(name,age,sex)
    19         self.course = course
    20         self.salary = salary
    21         #SchoolMember.__init__(self,name,age,sex)  旧的写法
    22     def teaching(self):
    23         print("Teacher [%s] is teaching [%s]" %(self.name,self.course))
    24 
    25 class Student(SchoolMember):
    26     def __init__(self,name,age,sex,course,tuition):
    27         super(Student,self).__init__(name,age,sex)  #继承
    28         self.course = course
    29         self.tuition = tuition
    30     def pay_tution(self):
    31         print("cao,student [%s] paying tution [%s]" %(self.name,self.tuition))
    32 
    33 t1 = Teacher("haha",50,"","PY",250)
    34 t2 = Teacher("hehe",60,"","PY",741)
    35 
    36 s1 = Student("nima",24,"","python",1000)
    37 s2 = Student("nimei",23,"","python",1200)
    38 t1.tell()
    39 t2.teaching()
    40 s1.tell()
    41 s2.pay_tution()
    42 
    43 #输出结果
    44 #the [1] SchoolMember [haha] is enrolled!
    45 #the [2] SchoolMember [hehe] is enrolled!
    46 #the [3] SchoolMember [nima] is enrolled!
    47 #the [4] SchoolMember [nimei] is enrolled!
    48 #hello my name is haha
    49 #Teacher [hehe] is teaching [PY]
    50 #hello my name is nima
    51 #cao,student [nimei] paying tution [1200]
    继承实例

    继承多个类

    继承多个类,寻找方法的方式,深度优先和广度优先,Python3.0不管新式类还是经典类都是广度优先

    深度优先:当类是经典类时,多继承情况下,会按照深度优先方式查找

    广度优先:当类是新式类时,多继承情况下,会按照广度优先方式查找

     1 class A:
     2     n = 'A'
     3     def f2(self):
     4         print("f2 from A")
     5 class B(A): #继承A
     6     n = 'B'
     7     def f1(self):
     8         print("from B")
     9     def f2(self):
    10         print("f2 from B")
    11 class C(A):
    12     n = 'C'
    13     def f2(self):
    14         print("from C")
    15 
    16 class D(B,C):  #多继承,先找B,C,A 广度优先
    17     '''test class'''
    18     def __del__(self):
    19         print("deleteing the...")
    20 
    21 #经典类,深度优先,Python3.0不管新式类还是经典类都是广度优先
    22 
    23 d = D()
    24 d.f1()
    25 d.f2()
    26 print(d.__doc__) #打印类的介绍
    1 from multi_inheritance import D
    2 
    3 a = D()
    4 print(a.__module__)  #打印从哪个文件导入

    3.多态

    多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

    Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中

     1 class Animal:
     2     def __init__(self, name):    # Constructor of the class
     3         self.name = name
     4     def talk(self):              # Abstract method, defined by convention only
     5         raise NotImplementedError("Subclass must implement abstract method")
     6 
     7 class Cat(Animal):
     8     def talk(self):
     9         return 'Meow!'
    10 
    11 class Dog(Animal):
    12     def talk(self):
    13         return 'Woof! Woof!'
    14 
    15 def animal_talk(obj):  #python不需要指定类型,所以没有多态
    16     print(obj.talk())  
    17 #==========================================
    18 c = Cat("nima")
    19 d = Dog("nimei")
    20 animal_talk(c)
    21 animal_talk(d)

    其他类型的语言

    1 def animal_talk(万能类型,obj): #必须指定类型Dog或者Cat,使用万能类型为多态,接口重用
    2     print(obj.talk())
    3 #==========================================
    4 c = Cat("nima")
    5 d = Dog("nimei")
    6 animal_talk(c)
    7 animal_talk(d)

    四、类的方法与属性

    1.类方法

     1 class Animal:
     2     def __init__(self,name):
     3         self.name = name
     4     hobbie = "meat"
     5 
     6     @classmethod #类方法,不能访问实例变量
     7     def talk(self):
     8         print("%s is talking..." % self.name)  #不能访问实例变量name
     9         print("%s is talking..." % self.hobbie)  #类变量可以访问
    10 
    11 d = Animal("yoyo")
    12 d.talk() 

    2.静态方法

     1 class Animal:
     2     def __init__(self,name):
     3         self.name = name
     4     hobbie = "meat"
     5 
     6     @staticmethod  #静态方法,不能访问类变量及实例变量
     7     def walk(self):
     8         print(" %s is talking..." % self.hobbie)  #不可以
     9 
    10     def walk():
    11         print(" is talking..." )  #正确方法
    12 
    13 d = Animal("yoyo")
    14 d.walk()

     

    3.属性

    1     @property  #把方法变成属性
    2     def habit(self):
    3         print("%s habit is football" %self.name)
    4 d.habit  #调用

    私有属性,属性的修改和删除

     1 class Animal:
     2     def __init__(self,name):
     3         self.name = name
     4         self.__num = None  #私有属性    
     5 
     6     @property
     7     def total_players(self):
     8         return self.__num  #私有属性,只能在里面自己用,对外面隐藏
     9 
    10     @total_players.setter  #修改属性
    11     def total_players(self,num):
    12         self.__num = num
    13         print("total players:",self.__num)
    14     @total_players.deleter  #删除属性
    15     def total_players(self):
    16         print("total players got deleted.")
    17         del self.__num
    18 
    19 d = Animal("yoyo")
    20 print(d.total_players)  #None
    21 d.total_players = 3  #赋值
    22 print(d.__num) #无法访问私有属性
    23 d.__num = 9  #外部修改为9,内部还是3
    24 print(d.__num)
    25 print("OUT:",d._Animal__num) #特例访问私有变量
    26 print(d.total_players) #结果为3
    27 del d.total_players  #删除属性

    4.类的特殊成员

     

     (1)__doc__:显示类的描述信息

    1 class Foo:
    2     """ test class """  #类的介绍
    3     def func(self):
    4         pass
    5 print(d.__doc__) #打印类的介绍

    (2)__module__:表示当前操作的对象在那个模块

    1 from multi_inheritance import D
    2 
    3 a = D()
    4 print(a.__module__)  #打印从哪个文件导入

    (3)__init__:构造方法,通过类创建对象时,自动触发执行

    1 class Foo:
    2 
    3     def __init__(self, name,age):
    4         self.name = name
    5         self.age = age
    6 
    7 a = Foo("wu",22)

    (4)__del__:析构方法,当对象在内存中被释放时,自动触发执行

    1     def __del__(self): 
    2         print("deleteing the...") 

    (5)__call__:对象后面加括号,触发执行

     1 class Foo:
     2 
     3     def __init__(self):
     4         pass
     5     
     6     def __call__(self, *args, **kwargs):
     7 
     8         print '__call__'
     9 
    10 
    11 obj = Foo() # 执行 __init__
    12 obj()       # 执行 __call__

    (6)__dict__:获取类或对象中的所有成员

    1  class Foo:
    2      def __init__(self):
    3          print('__init__')
    4          self.n =4
    5 print(obj.__dict__)  #以字典的形式显示,可以查看所有变量

    6 MyShinyClass = type('MyShinyClass',(),{"test":123}) #一句话定义一个类 7 print(type(MyShinyClass)) #类是由type创建 8 a = MyShinyClass() 9 print(MyShinyClass.test)

    五、反射

    #反射.py
    import sys
    class WebServer(object):
        def __init__(self,host,port):
            self.host = host
            self.port = port
    
        def start(self):
            print("Server is starting...")
        def stop(self):
            print("Server is stopping...")
        def restart(self):
            self.stop()
            self.start()
    
    if __name__ == "__main__":
        server = WebServer('localhost',333)
    
    #传统解决方法
        cmd_dic = {
            'start':server.start,
            'stop':server.stop
        }
    
        if sys.argv[1] in cmd_dic:
            cmd_dic[sys.argv[1]]()
    
    #输入python 反射.py restart
    #输出Server is stopping...
    #      Server is starting...

    利用反射

    import sys
    class WebServer(object):
        def __init__(self,host,port):
            self.host = host
            self.port = port
    
        def start(self):
            print("Server is starting...")
        def stop(self):
            print("Server is stopping...")
        def restart(self):
            self.stop()
            self.start()
    
    def test_run(name):
        print("running...",name)
    
    if __name__ == "__main__":
        server = WebServer('localhost',333)
        #print(sys.argv[1])
        if hasattr(server,sys.argv[1]):  #判断
            func = getattr(server,sys.argv[1])  #获取server.start 内存地址
            func()  #server.start()
    
        setattr(server,'run',test_run)  #设置,把test_run添加到实例
        server.run("alex")
    
        delattr(server,'host')  #删除host
        delattr(WebServer,'start')  #删除start
        print(server.host)
        print(server.restart())
  • 相关阅读:
    数学函数,字符串函数,聚合函数
    javascript大神修炼记(7)——OOP思想(多态)
    Join的表顺序
    java web 基础
    LVS入门
    Eclipse 一直提示 loading descriptor for 的解决方法
    nginx的配置总结
    nginx入门(安装,启动,关闭,信号量控制)
    如何正大光明的使用 google 进行搜索
    npm报错Error: ENOENT, stat 'D:NodeLearn ode-global'
  • 原文地址:https://www.cnblogs.com/yoyovip/p/5702870.html
Copyright © 2020-2023  润新知