面向对象入门

Posted superwuchaofan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象入门相关的知识,希望对你有一定的参考价值。

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

  那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官方文档。 

                                                                                                                                                                                              

 

 

 

 

 

 

 

  


以上是关于面向对象入门的主要内容,如果未能解决你的问题,请参考以下文章

面向对象入门(封装)

Python3快速入门Python3面向对象

Python3快速入门——Python3面向对象

面向对象入门2--继承

python入门到放弃之 面向对象vs面向过程

java入门12--面向对象(上)