设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 92925|回复: 76
打印 上一主题 下一主题

【Python 第50课】 面向对象(4)

[复制链接]

174

主题

45

好友

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2013-8-12 17:54:22 |只看该作者 |倒序浏览
上一课举了一个面向对象和面向过程相比较的例子之后,有些同学表示,仍然没太看出面向对象的优势。没关系,那是因为我们现在接触的程序还不够复杂,等以后你写的程序越来越大,就能体会到这其中的差别了。

今天我们就来举一个稍稍再复杂一点的例子。

仍然是从A地到B地,这次除了有汽车,我们还有了一辆自行车!
自行车和汽车有着相同的属性:速度(speed)。还有一个相同的方法(drive),来输出行驶/骑行一段距离所花的时间。但这次我们要给汽车增加一个属性:每公里油耗(fuel)。而在汽车行驶一段距离的方法中,除了要输出所花的时间外,还要输出所需的油量。

面向过程的方法,你可能需要写两个函数,然后把数据作为参数传递进去,在调用的时候要搞清应该使用哪个函数和哪些数据。有了面向对象,你可以把相关的数据和方法封装在一起,并且可以把不同类中的相同功能整合起来。这就需要用到面向对象中的另一个重要概念:继承。

我们要使用的方法是,创建一个叫做Vehicle的类,表示某种车,它包含了汽车和自行车所共有的东西:速度,行驶的方法。然后让Car类和Bike类都继承这个Vehicle类,即作为它的子类。在每个子类中,可以分别添加各自独有的属性。

Vehicle类被称为基本类或超类,Car类和Bike类被成为导出类或子类。
  1. class Vehicle:
  2.     def __init__(self, speed):
  3.         self.speed = speed

  4.     def drive(self, distance):
  5.         print 'need %f hour(s)' % (distance / self.speed)

  6. class Bike(Vehicle):
  7.     pass

  8. class Car(Vehicle):
  9.     def __init__(self, speed, fuel):
  10.         Vehicle.__init__(self, speed)
  11.         self.fuel = fuel

  12.     def drive(self, distance):
  13.         Vehicle.drive(self, distance)
  14.         print 'need %f fuels' % (distance * self.fuel)

  15. b = Bike(15.0)
  16. c = Car(80.0, 0.012)
  17. b.drive(100.0)
  18. c.drive(100.0)
复制代码
解释一下代码:
__init__函数会在一个实例被创建的时候自动调用,用来初始化类。它的参数,要在创建实例的时候提供。于是我们通过提供一个数值来初始化speed的值。

class定义后面的括号里表示这个类继承于哪个类。Bike(Vehicle)就是说Bike是继承自Vehicle中的子类。Vehicle中的属性和方法,Bike都会有。因为Bike不需要有额外的功能,所以用pass在类中保留空块,什么都不用写。

Car类中,我们又重新定义了__init__和drive函数,这样会覆盖掉它继承自Vehicle的同名函数。但我们依然可以通过“Vehicle.函数名”来调用它的超类方法。以此来获得它作为Vehicle所具有的功能。注意,因为是通过类名调用方法,而不是像之前一样通过对象来调用,所以这里必须提供self的参数值。在调用超类的方法之后,我们又给Car增加了一个fuel属性,并且在drive中多输出一行信息。

最后,我们分别创建一个速度为15的自行车对象,和一个速度为80、耗油量为0.012的汽车,然后让它们去行驶100的距离。

50class.png

#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:312723402

面向零基础初学者的编程课
每天5分钟,轻松学编程


#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

沙发
发表于 2013-8-12 23:15:33 |只看该作者
多说一句,__init__函数是左右各两个下划线。这是python系统定义的名称。其他还有很多系统定义的方法和属性也是用双下划线包围的。
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

88

积分

注册会员

Rank: 2

板凳
发表于 2013-8-29 16:40:05 |只看该作者
最后一段代码中,b = Bike(15.0)  和 c = Car(80.0,0.012),类Bike和类Car都继承类Vehicle,但是Vehicle里有两个方法啊,怎么确定括号里的参数15.0 和 80.0   0.012 是哪个方法里的参数?
回复

使用道具 举报

174

主题

45

好友

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

地板
发表于 2013-8-29 16:59:04 |只看该作者
匠逍之岿 发表于 2013-8-29 16:40
最后一段代码中,b = Bike(15.0)  和 c = Car(80.0,0.012),类Bike和类Car都继承类Vehicle,但是Vehicle里 ...

Bike没有重写Vehicle的__init__函数,所以它会调用它基类的。Car重写了,所以会调用它自身的。假如Car里要调用Vehicle中的同名方法,要用Vehicle.__init__()
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

88

积分

注册会员

Rank: 2

5#
发表于 2013-8-29 17:08:32 |只看该作者
还有__init__是什么?为什么要用这个名字?  初始化类是什么意思?不太懂...
回复

使用道具 举报

174

主题

45

好友

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

6#
发表于 2013-8-29 17:14:18 |只看该作者
匠逍之岿 发表于 2013-8-29 17:08
还有__init__是什么?为什么要用这个名字?  初始化类是什么意思?不太懂...

当创建一个类的实例时,有很多工作要做,比如类中的一些变量要赋给初始值。__init__就是干这种事。它会在一个实例被创建的时候自动调用。前后两个双下划线是系统方法的命名方式,它是python命名的,不需要你手动去调用
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

24

积分

新手上路

Rank: 1

7#
发表于 2013-8-31 13:21:53 |只看该作者
为什么要用__init__,有什么好处,这个函数也可以比不用__init__,直接def drive(self,speed,distance)
回复

使用道具 举报

0

主题

0

好友

24

积分

新手上路

Rank: 1

8#
发表于 2013-8-31 13:33:16 |只看该作者
另外def drive的函数中间,为什么一定要distance/self.speed,而不是直接distance/speed,speed不是已经定义过了吗
回复

使用道具 举报

0

主题

0

好友

24

积分

新手上路

Rank: 1

9#
发表于 2013-8-31 13:35:27 |只看该作者
而且,distance又为何不建立一个def __init__()?
回复

使用道具 举报

174

主题

45

好友

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

10#
发表于 2013-9-1 00:33:25 |只看该作者
lsxx043 发表于 2013-8-31 13:21
为什么要用__init__,有什么好处,这个函数也可以比不用__init__,直接def drive(self,speed,distance) ...

init是去初始化类,我们假设speed是vehicle的属性,所以应该在建立的时候被创建。直接那样当然可以实现统一的效果,但你每次都需要指定speed,这就失去面向对象的意义了
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-12-27 06:33 , Processed in 0.018639 second(s), 24 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部