Python再学习(五)面对对象编程

基本概念

  • OOP(Object Oriented Programming) 面对对象编程,对象可以是任何被识别的实体:学生、桌子、圆、按钮甚至贷款。
  • 一个对象的特性就好比人的身份证,Python 运行时会自动对每个对象赋予一个独特的 id
  • 一个对象的状态是用变量来表示的,称为数据域。
  • Python 使用方法来定义一个对象的行为,function 也被称为函数,通过对对对象上的方法,可以让对象完成某项操作。例如对圆进行 getArea() 和 getPerimeter() 的方法。圆就可以调用 getArea() 方法返回它的面积。调用 getPerimeter()的方法来返回它的周长。

一个 Python 类使用变量存储数据域,定义方法来完成动作,类就是一份契约或者模板或者蓝本,它定义对象的数据域和方法。

对象是类的一个实例,一个类可以创建多个对象,创建类的过程也被称为实例化,它定义对象的数据域和方法。

定义类的方法:

__init__ 这个方法称为初始化程序,它是在创建和初始化这个新对象时被调用的。初始化能够完成任何动作, 但是初始化程序被设计完成初始化动作,例如:初始值创建对象的数据域。
Python 定义类的语法:

class Classnames:
    initalizer
    methods

构造对象

一旦定义了一个类,就可以使用构造的方法来创建对象。构造对象完成两个任务:

  • 在内存中为类创建一个对象。
  • 调用类的__init__ 方法来初始化对象

包括初始化所有的方法,都有第一个参数 self,这个参数指向调用方法的对象。 __init__ 方法中的 self 参数常被自动设置位引用刚被创建类的对象,你可以为这个参数指定任何的名字,但是按照惯例,经常使用的是 self。

class Circle:
    # Construct a circle object
    def __init__(self,radius = 1):
        self.radius = radius

    def getPerimeter(self):
        return 2*self.radius*math.pi

    def setRadius(self,radius):
        self.radius = radius

这段程序创建了一个 Circle 的类,同时把自己的 r 默认设置为1,但是,可以通过后续的 setRadius 函数去设置它的半径,然后可以先定义一个对象设置为这种类,比如:

c = Circle(5)
print(c.radius) 
print(c.getPerimeter())
print(c.getArea())

self 的作用:

定义每个方法的第一个参数就是 self。self 是指向对象本身的参数,它的作用域就是整个类,self.x 是一个在 __init__ 方法中创建的实例变量。

一旦实例变量被创建。那么它的作用域就是整个类。self .x 是agiel在__init__方法中创建的实例变量,它可以在 m2中被访问。实例变量 self.y 在方法 。

事实上,想要创建一个新的类,只需要以一个变量名 = 类的初始函数,即可创建。例如下面的代码尝试,当然还需要有一定的定义函数的基础,变量定义的基础。

# * conding = UTF8
# class learn
# author:Neverland
# 生活就是一坨屎
import math

class Circle:
    # Construct a circle object
    def __init__(self,radius = 1):
        self.radius = radius

    def getPerimeter(self):
        return 2*self.radius*math.pi

    def setRadius(self,radius):
        self.radius = radius

CIrcle2 = Circle(25) 

程序使用 Circle 类创建 Circle对象,这种使用类的程序被称作类的客户端。

书中也提到,看似保存一个对象的变量实际上包含的是指向这个对象的引用。严格地讲变量和对象是不同的,但大多数情况下,这两者的区别是可以忽略的。所以,为了简单起见,最好说"circle1" 是一个 “Circle” 对象,而不会冗长地描述位 “circle1” 是一个变量,它包含一个指向 Circle 对象的引用。

UML 类图

Circle
类图 radius: float data 域

Circle(radius=1:float)

getArea():float 构造方法

getPerimeter():float

setRadius(radius,float): none

类中方法定义中总有 self 参数,但在 UML 图中并不包括它,因为客户端并不知道这个参数会不会使用参数调用方法。

方法__init__ 同样不需要罗列在 UML 图中,因为它被构造方法所调用,它的参数与构造方法的参数是一样的。

Plus:事实上,init 的构造函数就是self 加上一些常量定义,然后其他函数继续去调用它。

隐藏数据域

  如果直接使用构造函数的话,数据是可以直接修改的,很容易造成数据被篡改,比如修改 Circle 类,想要保证 radius 保持在一个非负值,此时不仅仅需要修改 Circle类,还得更改程序,因为客户端可以直接可以修改半径,导致其他 function 得出的值和预期不一致,所以需要私有数据域

  私有数据与和方法可以在类内部被访问,但是他们不能在类外被访问,可以定义一个 getfunction以达到返回值的效果,然后再设置一个 set 以修改的值。

  通过在属性名前加两个下划线,将 radius属性定义位私有的来修改,例如修改之前的 Circle 类。

import math

class Circle:
    # Construct a circle object
    def __init__(self,radius = 1):
        self.__radius = radius

    def getPerimeter(self):
        return 2*self.__radius*math.pi

    def getRadius(self):
        return self.__radius

    def setRadius(self,radius):
        self.__radius = radius

c = Circle(5)
print(c.__radius)           #错误的类外访问方法
print(c.getRadius())     #正确的使用 get 的方法访问

如果仅仅使用print(c.__radius)会报错,因为它是私有的

❗如果类是被设计给用来给其他程序使用的,为了防止数据被篡改并使类易于维护,就将数据定义为私有的。如果这个类仅仅在程序内部使用,就没有必要隐藏数据域。
❗使用两个下划线来命名私有数据域,但是不要以一个以上的下划线结尾。在 Python 中,以两个下划线开头同时以两个下划线结尾的名字有特殊的含义。例如 __radius是一个私有数据域,但是 __radius__ 并不是私有数据域

☑️关键点:类的抽象是将类的实现和类的使用分离的概念。类的实现和细节对用户而言是不可见的。这就是类的封装。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值