zoukankan      html  css  js  c++  java
  • 面向对象入门

      面向对象是软件开发方法。面向对象的概念和应用已经超越了程序设计和软件开发,电影《无间道》的拍摄就用了面向对象的思想。面向对象是一种对现实世界理解和抽象的方法。

      那python中的面向对象是什么样的呢?什么是封装,继承,和多态呢?很多同学都觉得面向对象很难以理解,总觉得面向对象非常神秘,今天我们不妨换个角度来学习面向对象。

      

      计算机通过数据来表达现实世界里的信息。因为信息是多种多样的有类型的,所以计算机里的数据也是有类型的。所有的编程语言都会有几个内置的基本数据类型,用来表达最常见的几种信息。但是现实世界里的信息类型是无穷无尽的,所以在实际的开发过程中我们为了更完美的表达信息,我们需要自定义新的数据类型。这就是类了。

      案例:要表示一个二维空间里的一个点

      在数学中用(0,0)表示原点,(x,y)表示一个在原点右侧x单位,上方y单位的点。

      在python中,有几种方法可以表达点

    •   我们可以用变量x和y分别表示点的两个坐标
    •        我们可以用列表或者元组来存储点的两个坐标
    •        我们可以新建一个类型来表达点

      用户自定的数据类型也称为类,类的定义如下所示:

    # 类的定义
    
    class Point:
        """表达一个2维空间里的点"""
    print(Point)

      结果:

    <class '__main__.Point'>

      class是关键字,Point是这个类的名称,文本内容是解释这个类的用途。我们定义好这个类之后,在后面的代码中,Point代表的就是这个数据类型,代表所有的点。那我们要表示具体的某一个点就需要通过类去创建一个具体的点,也叫新建一个对象,这个过程叫做实例化,对象是这个类的一个实例。创建一个类的对象的语法非常简单,可以把Point这个类名当做函数来调用,如下所示:

    p = Point()
    print(p)

      结果:

    <__main__.Point object at 0x03097690>

      属性

      p是类Point的一个实例,p代表一个具体的点,p应该有x,y坐标,我们可以通过赋值给对象的有命名的元素,这些元素就是属性。

    p.x = 0
    p.y = 0
    print('(%g, %g)' % (p.x, p.y))

      结果:

    (0, 0)

      方法

      我们先来看一个案例

      定义一个函数,计算一个点到原点的距离

      

    class Point:
        """表达一个2维空间里的点"""
    
    
    def distance(a):
        return (a.x**2 + a.y**2)**0.5
    
    
    p = Point()
    p.x = 3.0
    p.y = 4.0
    
    d = distance(p)
    print('点p到原点的距离是:%g' % d)

      结果

    点p到原点的距离是:5

      所有的对象就是一个具体的数据。从上例可以看出,对象可以作为函数的参数,那么也可以作为函数的返回值。在本例中,类定义和接着的函数定义没有明显的关联。但稍加观察,很明显distance函数接收一个Point对象作为参数。这种现象就是方法的由来。一个方法即是和某个特定的类相关联的函数。

      方法和函数在语义上是一样的,但在语法上有两个区别。

    •   方法定义写在类定义中,更明确的表示类和方法的关联
    •   调用方法和调用函数的语法形式不同

      上面的distance函数转换成方法非常容易,只需要将函数的定义,移入类定义中即可,注意缩进的改变:

    class Point:
        """表达一个2维空间里的点"""
    
        def distance(a):
            
            return (a.x ** 2 + a.y ** 2) ** 0.5

      现在有两种方式调用方法:第一种方式(更少见的)是函数调用语法:

    d = Point.distance(p)

      Point是类名,distance是方法名称,p作为参数传入

      另一种方式(更简洁,更常用)是使用方法调用语法:

    d = p.distance()

      在这里distance还是表示方法名称,而p是调用这个方法的对象,也称为主体。和一句话中主语用来表示这句话是关于什么东西的一样,方法调用的主体表示这个方法是关于哪个对象的。在方法中,主体会被赋值给第一个形参,所以本例中p被赋值给形参a。依照惯例来,方法的第一个形参通常叫做self,所以distance通常写成这种形式:

    class Point:
        """表达一个2维空间里的点"""
    
        def distance(self):
    
            return (self.x ** 2 + self.y ** 2) ** 0.5

      self代表的是调用这个方法的对象本身。

      接下来我们升级这个方法 ,让这个方法可以计算出任意两个点之间的距离

    class Point:
        """表达一个2维空间里的点"""
    
        def distance(self, other_point=None):
            if other_point:
                return ((self.x-other_point.x) ** 2 + (self.y-other_point.y) ** 2) ** 0.5
            else:
                return (self.x ** 2 + self.y ** 2) ** 0.5
    
    p = Point()
    p.x = 3.0
    p.y = 4.0
    
    p2 = Point()
    p2.x = 5.2
    p2.y = 7.8
    
    d = p.distance(p2)
    print('p和p2之间的距离是%g' % d)

      结果:

    p和p2之间的距离是4.3909

      init方法

      init方法(initialization的简写,意思是初始化)是一个特殊的方法,当对象初始化时会被调用。它的全名是__init__(两个下划线,接着是init,再接着两个下划线)。每个点在创建的时候就应该具备x,y坐标的属性,因此我们可以给Point类写一个init方法。

    class Point:
        """表达一个2维空间里的点"""
        
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y

      __init__的形参和属性名称常常是相同的。语句self.x = x 将形参x的值存储为self的一个属性。形参是可选的,所以你不使用任何实参调用Point时,会得到默认值:

    p = Point()
    print('(%g, %g)' % (p.x, p.y))

      运行结果:

    (0, 0)

      如果提供一个实参,它会覆盖x:

    p = Point(1)
    print('(%g, %g)' % (p.x, p.y))

      运行结果:

    (1, 0)

      如果提供二个实参,它会覆盖x和y:

    p = Point(1, 2)
    print('(%g, %g)' % (p.x, p.y))

      运行结果:

    (1, 2)

      __str__方法

      __str__方法和__init__类似,是一个特殊方法,它用来返回对象的字符串表达形式。

      上面的Point类的对象,我们想打印看看这个对象的x,y坐标的值时,总是要通过字符串拼接的形式,你可能会想,我们写个方法吧:

        def print_point(self):
            print('(%g, %g)' % (self.x, self.y))

      那么下次我直接调用方法就好了。这是一种解决办法。还有一种办法就是编写__str__方法,我们来给Point类写个str方法。

        def __str__(self):
            return '(%g, %g)' % (self.x, self.y)

      当你打印对象时,Python会调用str方法

    p = Point(1, 2)
    print(p)

      运行结果

    (1, 2)

      建议编写一个新类时,开始先写__init__,以便初始化对象,然后会写__str__,以便调试。

      操作符重载

      通过定义其他的特殊方法,可以为自 定义类型的各种操作符指定行为。例如:如果你为了Point类定义一个__add__方法,则可以在Point对象上使用+操作符。

        def __add__(self, other):
            new_point = Point()
            new_point.x = self.x + other.x
            new_point.y = self.y + other.y
            return new_point

      我们来使用它

    p = Point(1, 2)
    p2 = Point(3, 4)
    print(p+p2)

      运行结果:

    (4, 6)

      当你对Time对象应用+操作符时,Python会调用__add__。当你打印结果时,Python会调用__str__。幕后其实发生了很多事情。修改操作符的行为以便它能够作用于自定义类型,这个过程称为操作符重载。对每一个操作符,Python都提供了一个对应的特殊方法。更多相关,可以参阅Python官方文档。 

                                                                                                                                                                                                  

      

  • 相关阅读:
    placeholder 兼容处理
    扩展 jq 对象方法
    gulp 命令
    v-show、v-if、v-for的使用
    Vue中防抖和节流 --来自官方文档
    Python字符窜取值
    怎么安装redis桌面版?
    Python常用的基本数据类型
    MySQL常用语法
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/superwuchaofan/p/9593205.html
Copyright © 2011-2022 走看看