zoukankan      html  css  js  c++  java
  • Python之面向对象

    Python

     

      面向对象:    

        面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

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

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

    一. 如何定义一个类

      在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。

      类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义:

    class className:
        block

      注意类名后面有个冒号,在block块里面就可以定义属性和方法了。当一个类定义完之后,就产生了一个类对象。类对象支持两种操作:引用和实例化。引用操作是通过类对象去调用类中的属性或者方法,而实例化是产生出一个类对象的实例,称作实例对象。比如定义了一个people类:

    class people:
        name = 'jack'       #定义了一个属性
        #定义了一个方法
        def printName(self):
            print self.name

      people类定义完成之后就产生了一个全局的类对象,可以通过类对象来访问类中的属性和方法了。当通过people.name(至于为什么可以直接这样访问属性后面再解释,这里只要理解类对象这个概念就行了)来访问时,people.name中的people称为类对象,这点和C++中的有所不同。当然还可以进行实例化操作,p=people( ),这样就产生了一个people的实例对象,此时也可以通过实例对象p来访问属性或者方法了(p.name).

      理解了类、类对象和实例对象的区别之后,我们来了解一下Python中属性、方法和函数的区别。

      在上面代码中注释的很清楚了,name是一个属性,printName( )是一个方法,与某个对象进行绑定的函数称作为方法。一般在类里面定义的函数与类对象或者实例对象绑定了,所以称作为方法;而在类外定义的函数一般没有同对象进行绑定,就称为函数。

    二.属性

      在类中我们可以定义一些属性,比如:

    class people:
        name = 'jack'
        age = 12
    
    p = people()
    print p.name,p.age

      定义了一个people类,里面定义了name和age属性,默认值分别为'jack'和12。在定义了类之后,就可以用来产生实例化对象了,这句p = people( )实例化了一个对象p,然后就可以通过p来读取属性了。

    三.方法

      在类中可以根据需要定义一些方法,定义方法采用def关键字,在类中定义的方法至少会有一个参数,,一般以名为'self'的变量作为该参数(用其他名称也可以),而且需要作为第一个参数。下面看个例子:

    class people:
        __name = 'jack'
        __age = 12
    
        def getName(self):
            return self.__name
        def getAge(self):
            return self.__age
    
    p = people()
    print(p.getName(),p.getAge())

    注意:    

      self是一个Python自动会给传值得参数

    obj1.fetch('selec...') self = obj1
    obj2.fetch('selec...') self = obj1

    四.类中内置的方法

      在Python中有一些内置的方法,这些方法命名都有比较特殊的地方(其方法名以2个下划线开始然后以2个下划线结束)。类中最常用的就是构造方法和析构方法。

      构造方法__init__(self,....)在生成对象时调用,可以用来进行一些初始化操作,不需要显示去调用,系统会默认去执行。构造方法支持重载,如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。

      析构方法__del__(self)在释放对象时调用,支持重载,可以在里面进行一些释放资源的操作,不需要显示调用。

     1 class Person:
     2     population=0
     3 
     4     def __init__(self,name):
     5         print("Person类正在实例化")
     6         self.name=name
     7         print("类名为",self.name)
     8         self.population += 1
     9 
    10     def __del__(self):#析构函数
    11         print("Person类正在析构",self.name)
    12         self.population -= 1
    13 
    14         if self.population == 0:
    15             print("I am the last One")
    16         else:
    17             print("There are still",self.population,"left")
    18 
    19     def sayHi(self):
    20         print("Hello World",self.name)
    21 
    22     def howMany(self):
    23         print("We have,",self.population,"Person Now")
    24 
    25 swaroop = Person("swaroop")
    26 swaroop.sayHi()
    27 swaroop.howMany()
    28 
    29 kalam = Person("kalam")
    30 kalam.sayHi()
    31 kalam.howMany()
    32 
    33 swaroop.sayHi()
    34 #输出:
    35 
    36 Person类正在实例化
    37 类名为 swaroop
    38 Hello World swaroop
    39 We have, 1 Person Now
    40 Person类正在实例化
    41 类名为 kalam
    42 Hello World kalam
    43 We have, 1 Person Now
    44 Hello World swaroop
    45 Person类正在析构 swaroop
    46 I am the last One
    47 Person类正在析构 kalam
    48 I am the last One

    面向对象三大特性(引用)

    面向对象的三大特性是指:封装、继承和多态。

    1 . 封装

    封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。

    所以,在使用面向对象的封装特性时,需要:

    • 将内容封装到某处
    • 从某处调用被封装的内容

    第一步:将内容封装到某处

     self 是一个形式参数,当执行 obj1 = Foo('wupeiqi', 18 ) 时,self 等于 obj1

                                  当执行 obj2 = Foo('alex', 78 ) 时,self 等于 obj2

    所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有 name 和 age 属性,在内存里类似于下图来保存。

    第二步:从某处调用被封装的内容

    调用被封装的内容时,有两种情况:

    • 通过对象直接调用
    • 通过self间接调用

    1、通过对象直接调用被封装的内容

    上图展示了对象 obj1 和 obj2 在内存中保存的方式,根据保存格式可以如此调用被封装的内容:对象.属性名 1 class Foo:

     1 class Foo:
     2 
     3     def __init__(self, name, age):
     4         self.name = name
     5         self.age = age
     6 
     7 obj1 = Foo('wupeiqi', 18)
     8 print(obj1.name)    # 直接调用obj1对象的name属性
     9 print(obj1.age)    # 直接调用obj1对象的age属性
    10 
    11 obj2 = Foo('alex', 73)
    12 print(obj2.name)    # 直接调用obj2对象的name属性
    13 print(obj2.age)     # 直接调用obj2对象的age属性
    14 
    15 wupeiqi
    16 18
    17 alex
    18 73

    2、通过self间接调用被封装的内容

    执行类中的方法时,需要通过self间接调用被封装的内容

     1 class Foo:
     2 
     3     def __init__(self, name, age):
     4         self.name = name
     5         self.age = age
     6 
     7     def detail(self):
     8         print(self.name)
     9         print(self.age)
    10 
    11 obj1 = Foo('wupeiqi', 18)
    12 obj1.detail()  # Python默认会将obj1传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18
    13 
    14 obj2 = Foo('alex', 73)
    15 obj2.detail()  # Python默认会将obj2传给self参数,即:obj1.detail(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 alex ; self.age 是 78
    16 
    17 wupeiqi
    18 18
    19 alex
    20 73

    练习一:在终端输出如下信息

    • 小明,10岁,男,上山去砍柴
    • 小明,10岁,男,开车去东北
    • 小明,10岁,男,最爱大保健
    • 老李,90岁,男,上山去砍柴
    • 老李,90岁,男,开车去东北
    • 老李,90岁,男,最爱大保健
     1 class Foo:
     2     
     3     def __init__(self, name, age ,gender):
     4         self.name = name
     5         self.age = age
     6         self.gender = gender
     7 
     8     def kanchai(self):
     9         print "%s,%s岁,%s,上山去砍柴" %(self.name, self.age, self.gender)
    10 
    11     def qudongbei(self):
    12         print "%s,%s岁,%s,开车去东北" %(self.name, self.age, self.gender)
    13 
    14     def dabaojian(self):
    15         print "%s,%s岁,%s,最爱大保健" %(self.name, self.age, self.gender)
    16 
    17 
    18 xiaoming = Foo('小明', 10, '')
    19 xiaoming.kanchai()
    20 xiaoming.qudongbei()
    21 xiaoming.dabaojian()
    22 
    23 laoli = Foo('老李', 90, '')
    24 laoli.kanchai()
    25 laoli.qudongbei()
    26 laoli.dabaojian()
    27 
    28 面向对象

    2 . 继承

             面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

      

     在python中继承中的一些特点:

       (1):在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。有别于C#

       (2):在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

       (3):Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

     1 class F1:#父类,基类
     2 
     3     def show(self):
     4         print("show")
     5 
     6     def foo(self):
     7         print(self.name)
     8 
     9 class F2(F1): #子类,派生类
    10     def __init__(self, name):
    11         self.name = name
    12 
    13     def bar(self):
    14         print("bar")
    15     def show(self):
    16         print("F2,show")
    17 
    18 obj = F2("hong")
    19 obj.foo()
    20 
    21 hong
     1 class SchoolMember:  
     2     def __init__(self,name,age):  
     3         self.name=name  
     4         self.age=age  
     5         print(self.name,"正在实例化")  
     6           
     7     def tell(self):  
     8         print("Name is",self.name,"and Age is",self.age)  
     9           
    10 class Teacher(SchoolMember):  
    11     def __init__(self,name,age,salary):  
    12         SchoolMember.__init__(self, name, age)  
    13         self.salary=salary  
    14         print("教师类正在实例化")  
    15           
    16     def tell(self):  
    17         SchoolMember.tell(self)  
    18         print("工资为",self.salary)  
    19 t = Teacher("A",12,300)  
    20 t.tell()  
    21 #输出:
    22 
    23 A 正在实例化
    24 教师类正在实例化
    25 Name is A and Age is 12
    26 工资为 300
  • 相关阅读:
    java 小数点取2位并且四舍五入
    批处理(.bat脚本)基本命令语法
    vue-webpack项目本地开发环境设置代理解决跨域问题
    vue项目引入FastClick组件解决IOS系统下h5页面中的按钮点击延迟,连续点击无反应的问题
    用vue构建多页面应用
    单页面应用和多页面应用对比分析
    html5文件读取+按钮样式重置+文件内容预览
    FileReader读取文件详解
    vue的双向数据绑定实现原理
    译:9.使用Redis进行消息传递
  • 原文地址:https://www.cnblogs.com/python-nameless/p/5615453.html
Copyright © 2011-2022 走看看