面向对象编程的学习

一、定义

首先跟大家介绍一位资深的程序员前辈说过的编程心得:

1、写重复代码是非常不好且低级的行为

2、完成的代码需要经常变更

所以根据以上两个心得,我们可以知道写的代码一定要遵循易读、易改的原则(可读性好、易扩展),这样的话面向对象编程是一个非常好的选择。

面向对象编程是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。编写类时,你定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。使用面向对象编程可模拟现实情境,其可达到非常高的逼真程度。

根据类来创建对象被称为实例化,这让你能够使用类的示例。在今天的学习中,我将介绍如何编写类并创建其示例。你将指定可在实例中存储什么信息,定义可对这些实例执行哪些操作。

下面简单介绍一下面向过程编程与面向对象编程的区别:

面向过程编程即程序从上到下一步步执行,一步步从上到下,从头到尾解决问题。适合做一些一次性任务,通常是一些简单的脚本。

面向对象编程,即object-oriented programming(OOP),利用‘类’和‘对象’来创建各种模型来实现对真实世界的描述,易于维护和扩展,并可大大提高程序开发效率,更易理解。只要是对象,就肯定属于某种品类,就肯定有属性。

面向对象编程的有两个核心特征:

1、class类

  一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性和共同的方法。

2、object对象

  一个对象即是一个类的实例化后的实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性。就像‘人类’指的是所有人,每个人是指具体的对象,人与人之间有共性,亦有不同。

面向对象编程的有三个特性:

1、封装(Encapsulation)

  在类中对数据的赋值、内部调用对外部用户是透明的,这种类变成了一个胶囊或容器,里面包含着类的数据和方法。

2、继承(Inheritance)

  一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承。

3、多态(Polymorphism)

  ‘一个接口,多种实现’,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一事物表现出的多种形态。  

二、面向对象示例

1、接下来我们创建一个简单的类来描述一种动物——狗,并创建一个类的方法——叫。文件名为dog.py,具体代码如下:

class Dog():
def __init__(self,name): #构造函数
'''初始化属性name'''
self.name = name def bulk(self):
'''模拟小狗叫'''
print('%s: wang!wang!wang!'%self.name) #创建两个实例d1,d2
d1 = Dog('Ali')
d2 = Dog('Bob') #访问实例的属性
print(d1.name)
print(d2.name) d1.bulk()
d2.bulk()

代码执行结果如下:

2、接下来,我们利用类方法来写一个简单的‘警察与小偷’程序,即创建一个警察角色和小偷角色,两人都有拥有购买和使用武器的功能。具体代码实现如下:

class Role(object):
def __init__(self,name,role,weapon,life_value=100,money=15000):
#构造函数
#在实例化时,做一些类的初始化的工作
self.name = name #实例变量(静态属性),作用域就是实例本身
self.role = role
self.weapon = weapon
self.life_value = life_value
self.money = money #开枪功能
def shot(self):
print("shooting...") #被击中
def got_shot(self):
self.life_value -= 50
print("%s:ah...,I got shot..."%(self.name)) #买枪功能
def buy_gun(self,gun_name):
print("%s just bought %s" %(self.name,gun_name)) #显示角色状态
def show_status(self):
print('name:%s,weapon:%s,life_value:%s'%(self.name,self.weapon,self.__life_value)) def __del__(self):
#析构函数
#在实例释放、销毁的时候执行的,通常用于做一些收尾工作,如关闭一些数据库链接,打开临时文件等。
print('%s 彻底死了。。。'%self.name) r1 = Role('Alex','police','AK47') #把一个类变成具体对象的过程称作实例化(初始化一个类,造了一个对象)
r1.buy_gun('ak47')
r1.got_shot()
r1.shot()
r1.show_status() r2 = Role('Jack','terrorist','B22') #生成一个角色
r2.got_shot()

代码执行结果如下:

在这里我们看到类Role最后的析构函数的作用就是在每次实例化完一个角色后,自动执行析构函数的内容 。

3、私有方法

通过私有方法我们可以把‘类’下的方法设为私有,即外部不可调用,我们还以类Dog为例,具体如下:

class Dog():
def __init__(self,name): #构造函数
'''初始化属性name'''
self.name = name def __bulk(self): #方法前加'__'即可把原方法设为私有化方法
'''模拟小狗叫'''
print('%s: wang!wang!wang!'%self.name) #创建两个实例d1,d2
d1 = Dog('Ali')
d2 = Dog('Bob') #访问实例的属性
print(d1.name)
print(d2.name) d1.__bulk()
d2.__bulk()

代码执行结果如下:

可以看到到后面并没有调用__bulk方法。

三、继承

编写类时,并非总要从空白开始。如果你要编写的类时另一个现成的特殊版本,可使用继承。一个类继承一个类时,它将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

接下来我们以男人和女人同属人类为例编写一个简单的继承小程序,具体代码如下:

class People():
#创建‘人类’类
def __init__(self,name,age):
self.name = name
self.age = age
#‘吃’方法
def eat(self):
print('%s is eating'%self.name)
#‘睡’方法
def sleep(self):
print('%s is sleeping'%self.name) class Relation(object):
#创建‘交朋友’类
def make_friends(self,obj):
print('%s is making friends with %s'%(self.name,obj.name)) class Man(People,Relation):
#类‘Man’继承类‘People’和‘Relation’
def __init__(self,name,age,money):
super().__init__(name,age) #新式类
self.money=money #'money'为类‘Man’独有的属性
print('%s have %s money'%(self.name,self.money))
def smoke(self):
#'smoke'为类‘Man’独有的方法
print('%s is smoking'%self.name) def sleep(self):
People.sleep(self)
#在继承类‘People’的sleep方法基础上添加了新功能
print('man is sleeping') class Women(People,Relation):
#类‘Women’继承类‘People’和‘Relation’
def get_birth(self):
#'get_birth'为类‘Women’独有的方法
print('%s is borning a baby'%self.name) m1 = Man('kobe',36,26)
m1.eat()
m1.sleep()
m1.smoke() w1 = Women('alice',45)
w1.get_birth() m1.make_friends(w1)

代码执行结果如下:

另外,若我们让实例w1去使用类Man中的‘smoke’方法,则会出现问题。如下所示:

class People():
#创建‘人类’类
def __init__(self,name,age):
self.name = name
self.age = age
#‘吃’方法
def eat(self):
print('%s is eating'%self.name)
#‘睡’方法
def sleep(self):
print('%s is sleeping'%self.name) class Relation(object):
#创建‘交朋友’类
def make_friends(self,obj):
print('%s is making friends with %s'%(self.name,obj.name)) class Man(People,Relation):
#类‘Man’继承类‘People’和‘Relation’
def __init__(self,name,age,money):
super().__init__(name,age) #新式类
self.money=money #'money'为类‘Man’独有的属性
print('%s have %s money'%(self.name,self.money))
def smoke(self):
#'smoke'为类‘Man’独有的方法
print('%s is smoking'%self.name) def sleep(self):
People.sleep(self)
#在继承类‘People’的sleep方法基础上添加了新功能
print('man is sleeping') class Women(People,Relation):
#类‘Women’继承类‘People’和‘Relation’
def get_birth(self):
#'get_birth'为类‘Women’独有的方法
print('%s is borning a baby'%self.name)
w1 = Women('alice',45)
w1.smoke()

结果如下图:

我们可以看到w1只能使用继承的类(People,Relation)和自己类(Women)下包含的方法。

最后,我们用学到的类来编写一个描述学校-老师-学生之间关系的小程序。其中老师有教课的方法,学生有交学费的方法。

具体如下:

class School():
def __init__(self,name,addr):
self.name = name
self.addr = addr
self.students = []
self.staffs = [] #为学生办理注册手续
def enroll(self,stu_obj):
print('为学员%s办理注册手续'%stu_obj.name)
self.students.append(stu_obj) #记录招募的员工情况
def hire(self,staff_obj):
self.staffs.append(staff_obj)
print('雇佣新员工%s'%staff_obj.name) #描述‘学校成员’的类
class SchoolMember():
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex class Teacher(SchoolMember):
def __init__(self,name,age,sex,salary,course):
super().__init__(name,age,sex)
self.salary = salary
self.course = course def tell(self):
print('''
---info of Teacher: %s---
Name: %s
Age: %s
Sex: %s
Salary: %s
Course: %s
'''%(self.name,self.name,self.age,self.sex,self.salary,self.course)) def teach(self):
print('%s is teaching course [%s]'%(self.name,self.course)) class Student(SchoolMember):
def __init__(self,name,age,sex,stu_id,grade):
super().__init__(name,age,sex)
self.stu_id = stu_id
self.grade = grade def tell(self):
print('''
---info of Student: %s---
Name: %s
Age: %s
Sex: %s
Stu_id: %s
Grade: %s
'''%(self.name,self.name,self.age,self.sex,self.stu_id,self.grade)) def pay_tuition(self,amount):
print('%s has paid tuition for $%s'%(self.name,amount)) #实例化
school=School('南京邮电大学','南京') t1=Teacher('Kobe',56,'M',200000,'Sport')
t2=Teacher('Justin',22,'M',3000,'Music') s1=Student('Chen',36,'F',1001,'Sport')
s2=Student('Xu',19,'M',1002,'Music') t1.tell()
s1.tell()
school.hire(t1)
school.enroll(s1)
school.enroll(s2) print(school.students)
print(school.staffs)
school.staffs[0].teach() for stu in school.students:
stu.pay_tuition(5000)

代码执行结果如下:

四、导入类

随着你不断给类添加新功能,文件可能变得很长,即使你妥善地使用了继承亦如此。为遵循Python的总体理念,应让文件尽可能简洁。为这方面提供帮助,Python允许你将类存储在模块中,然后在主程序中导入所需模块中,然后在主程序中导入所需的模块。

以上述dog.py中的Dog为例,我们新建一个文件——导入.py来实现导入类的功能。

导入.py的具体代码如下:

from dog import Dog
d3=Dog('bai')
d3.bulk()

代码执行结果如下:

通过上面的例子我们可以看到导入类是一种有效的编程方式。通过将这个类移到一个模块中,并导入该模块,你依然可以使用其所有功能,但主程序变得简洁而易于阅读了。这还能让你将大部分逻辑存储在独立的文件中。确定类像你希望的那样工作后,你就可以不管这些文件,而专注于主程序的高级逻辑了。

Python3.5学习之旅——day6的更多相关文章

  1. Python3.5学习之旅——day2

    本节内容: 1.模块初识 2..pyc是什么? 3.Python的数据类型 4.三元运算 5.进制 6.byte类型 7.数据运算 8.列表 9.元组 10.课后练习 一.模块初识 由day1的学习我 ...

  2. Python3.5学习之旅——day5

    模块初识 一.定义 在python中,模块是用来实现某一特定功能的代码集合.其本质上就是以‘.py’结尾的python文件.例如某文件名为test.py,则模块名为test. 二.导入方法 我们在这一 ...

  3. Python3.5学习之旅——day4

    本节内容 1.装饰器 2.迭代器与生成器 3.内置方法 4.软件目录结构规范 一.装饰器 装饰器是一个用来装饰其他函数的工具,即为其他函数添加附加功能,其本质就是函数. 装饰器需要遵循的以下两个原则: ...

  4. Python3.5学习之旅——day3

    本节内容: 1.字符串操作 2.字典操作 3.集合 4.文件操作 5.字符编码与转码 6.函数与函数式编程 一.字符串操作 name='kobe' name.capitalize() 首字母大写 na ...

  5. Python3.5学习之旅——day1

    本节内容: 1.Python介绍 2.Hello World程序 3.变量\字符编码 4.用户输入 5.if-else语句 6.循环语句 一.Python介绍 Python是一种动态解释性的强类型定义 ...

  6. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  7. Hadoop学习之旅二:HDFS

    本文基于Hadoop1.X 概述 分布式文件系统主要用来解决如下几个问题: 读写大文件 加速运算 对于某些体积巨大的文件,比如其大小超过了计算机文件系统所能存放的最大限制或者是其大小甚至超过了计算机整 ...

  8. WCF学习之旅—第三个示例之二(二十八)

    上接WCF学习之旅—第三个示例之一(二十七) 五.在项目BookMgr.Model创建实体类数据 第一步,安装Entity Framework 1)  使用NuGet下载最新版的Entity Fram ...

  9. WCF学习之旅—第三个示例之三(二十九)

    上接WCF学习之旅—第三个示例之一(二十七) WCF学习之旅—第三个示例之二(二十八) 在上一篇文章中我们创建了实体对象与接口协定,在这一篇文章中我们来学习如何创建WCF的服务端代码.具体步骤见下面. ...

随机推荐

  1. IntelliJ IDEA 2017.3尚硅谷-----省电模式

  2. leetcode 64. 最小路径和 动态规划系列

    目录 1. leetcode 64. 最小路径和 1.1. 暴力 1.2. 二维动态规划 2. 完整代码及执行结果 2.1. 执行结果 1. leetcode 64. 最小路径和 给定一个包含非负整数 ...

  3. 故障解决 | win10没声音及找不到Realtek高清音频管理器

    重装 win10 系统后,电脑没声音,更新驱动以及万不得已下载驱动精灵都没有解决. 后来发现在“硬件和声音”中没有Realtek高清音频管理器,之后找到解决办法如下: 1. 找到Realtek高清音频 ...

  4. testng的prioriy

    todo: 同一个class中的priority: 1.不标priority的case和标注priority的case,谁先谁后? 2.标注相同priority的case,谁先谁后?是不是并发? 3. ...

  5. java中一个类中的 this. 是什么作用

    2)this代表的是本类的实例对象,不是什么调用本类的方法的对象.当你用new创建一个对象的时候,对象就已经在内存了.(具体的你的血jvm和反射).构造方法只是为了给对象里的属性赋值.在类里任何地方出 ...

  6. Makefile的编写及四个特殊符号的意义@、$@、$^、$

    https://www.cnblogs.com/sky-heaven/p/9450435.html Makefile一般的格式是: target:components rule 一.@ 这个符串通常用 ...

  7. Flask 教程 第十六章:全文搜索

    本文翻译自The Flask Mega-Tutorial Part XVI: Full-Text Search 这是Flask Mega-Tutorial系列的第十六部分,我将在其中为Microblo ...

  8. sql注入基础知识

    信息安全概论课堂作业 SQL注入之万能密码漏洞 第一道题是牵扯到了万能密码漏洞 用户名先输入个’ 返回了sql报错语句,猜测存在sql注入漏洞 使用万能密码测试 登陆成功 原理 假设登录框处的判断代码 ...

  9. node 连接数据库异常

    1 找不到mysql模块 报错:Cannot find module 'mysql' 处理:npm install mysql 2 建立了多次连接 报错:Cannot enqueue Handshak ...

  10. Homebrew安装和Mac使用

    软件安装 1.Homebrew安装   ruby环境: curl -sSL https://get.rvm.io | bash -s stable   官网方式: /usr/bin/ruby -e & ...