python面向对象解决哪些问题_python面向对象知识整理

说几个生活中常见的车?你能想到:小汽车,火车,救护车,消防车,QQ飞车……它们有一些共同的特点,比如说,能开……

面向对象

面向对象是一种思想,是一种解决问题的方向性引导。通常来说,我们的思维总是面向过程的。比如说房屋的修建:第一步先做好地基,第二步搭建框架,第三步垒墙封顶,第四步安装门窗。假设我们要用程序来实现,可能会有四个分步的函数,然后再在一个整体的函数里去依次调用他们。

面向对象则和面向过程不同,对于房屋修建这个问题,它重点分析的对象不是修建,而是房屋。房屋由哪些部分组成?如门、窗、墙、屋顶、房梁等,更细粒度的,如砖、木头、水、沙子等。在程序里,选择合适的对象,去描述它们的特征和行为。再把它们结合起来,使它们根据自身的特性去发生反应,最终得到结果。

在使用面向对象的方法分析问题时,有两个关键主体:类和对象。一般会有以下一些方法或特点,体现在面向对象的问题分析过程中。

抽象:一系列事物,可以根据其共有的特点,归结为一类。它们拥有一系列共同的属性。比如说,图形A和图形B都是三角形。它们都有三条边,三个角。但是,它们每个边的边长或每个角的角度是不相同的。在程序里,我们可能会有一个类叫Triangle,然后,我们可能会创建两个对象,分别是triangle_a和triangle_b,然后,分别去描述它们的边长和角度。

三角形

封装:某类事物,可能会具备若干个通用的方法,对于该类的使用者来说,方法内部的实现细节,我们其实是没有必要去深入考究的。我们只需要知道,该类有哪些方法可以使用,并分别能达到什么效果,然后直接去使用就好。如三角形类Triangle,它可能有一个方法叫get_area,这个方法用来计算并返回三角形的面积。我们直接去调用这个方法就好,并没有必要去关注这个方法内部是如何计算的。

继承:有时候,我们会发现,我们抽象出来的某几个类,还是拥有一些共同的特性。比如说三角形和正方形,它们都有一个方法,叫get_area。那么,此时,我们可以定义一个类,比如叫Shape,形状。然后,把get_area方法写在Shape,再让三角形和正方形都继承Shape类,这样,三角形和正方形类就会自动拥有get_area方法。

多态:上面我们提到,三角形和正方形可以从Shape类继承得到get_area方法。但事实上,在实际应用中,我们发现可能会重在一些困难,这种困难源自于三角形和正方形面积计算公式的差异性。这意味着,我们可能需要在三角形中对get_area方法进行重写,以适合三角形的面积计算。这在面向对象中,称之为多态。

python中面向对象的一些基本概念

python在设计之初,就是面向对象的。我们先来了解一些基本的概念,以提高后面学习面向对象的效率。

类:一系列事物,经过抽象后,归纳出来一个用于描述它们的框架,包含了它们共有的属性和方法,该框架称之为类。

对象:类经过实例化后,可以创建出一系列对象。对象就是类的实例化。可以把类想象成模具,对象则是通过模具创建出来的具体事物。

方法:在Python中,可能使用def关键字来定义一个函数,然后在其它位置调用。假如一个函数被定义在类中,则可以称之为方法,它通常用来描述该类事物的某个动作或行为。

类变量:在Python中,定义在某个类内部的变量,称之为类变量。注意,类变量的外层就是类,如果一个变量是在类的某个方法内部被定义,那么,它并不是一个类变量。

python中类的定义和使用

python中,通过class关键字来定义一个类。假设有一个类“人”,它有姓名,年龄,可以打招呼,则可以定义如下:

类定义

如上,Person类的定义中,包含了name和age两个类变量,基于python语法的基本要求,它们都必须有一个默认值。有一个类方法,hello。类方法和普通函数的区别是,类方法必须有一个参数,这个参数用于操作对象本身。如hello中,通过self,可以获取到当前变量的name和age。self是我们自己定义在的一个标识符,并不是规定的。可以根据自己的喜好更换。当然,没有什么特殊场景是必须更换的。

在第9行,创建了一个Person类的对象,person_a。第10行,在类外,通过对象调用了对象的hello方法。得到了如下结果:

类方法调用结果

输出结果表明,hello方法被成功调用了。但是,在实际使用中,name和age通常是每个对象个性化的。那么,如何在创建对象时,个性化name和age呢?一种方法是我们可以定义一个方法,如update_name,用于修改name,并在对象创建好后调用。另一种方法是,提供一个__init__方法,如下:

带参数的构造方法

如上,从第5行起,我们自定义了一个__init__方法,该方法除self外,添加了两个额外的参数,即name和age,方法体中,对方法内变量进行了赋值操作。

第13行和15行,分别实例化了两个对象。根据代码执行的结果,可以发现,这两个对象是个性化的。

python中,当实例化一个对象时,会默认调用__init__方法,所以,__init__方法也被称之为构造方法。 当未提供自定义__init__方法时,python会给类默认添加一个无参的构造函数。当提供了自定义的__init__方法后,将会覆盖掉原来的__init__方法。

有过其它语言的基础的同学可能会想到,我是不是可以同时提供两个__init__方法,一个带有name和age,另一个不带,这样,我是否就可以既使用无参方式实例化对象,又可以用带参数的方式实例化对象,就像Java中的方法重载一样?

答案是:不行。

python是不支持方法重载的。在python,万物皆对象,类的方法,也是一个对象。方法名就是标识符。所以,当定义了多个__init__方法时,其效果就等同于对一个变量多次赋值,最终结果是:只有最后一次赋值后的结果是最终有效的。甚至,可以通过__init__方法定义后,对__init__直接赋值成一个类变量,来导致__init__方法失效。如下:

方法不能重载

如上,尝试运行,会得到一个TypeError,类型错误。这说明,__init__方法确实被覆盖成了一个整数0。

python中,方法重载是行不通的,但是,我们可以通过另一种方式,达到在调用时,好像重载的效果。如下:

类似重载的构造方法

如上,尝试运行会发现,是可以正确运行的。这其实是我们之前学过的,python中,在定义函数时,默认参数,关键字参数等的综合应用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值