首页 > 技术文章 > python(8):面向对象编程

xuying-fall 2018-01-20 12:45 原文

有三种程序类型:

(1)面向过程:按照一定的逻辑顺序,一步步垒代码

(2)面向函数:对用常用的计算,建立函数避免重复

(3)面向对象: 函数的集合,对函数进行分类和封装

(一) 抽象

抽象: 哈巴狗, 宾利犬... 都是狗, 狗就是抽象

对象: 哈巴狗, 宾利犬, 藏獒

类的具体化叫对象, 对象的抽象叫做类

类是一个模板, 

class(类):包含了很多函数的一个模块: 如何定义类?

class class_name(object):
    'define classname class'
    class_suite

(object) 为父类!,,, 之后会介绍, 如果你的类没有继承任何父类, 那么默认就是object作为父类, 

object是万类之源.

定义一个什么也不做的空类

class mydate(object):
    'this is a very simple example class'
    pass  # 表示什么也不做
    # 这里的类仅作为名称空间

类的方法

class dog(obect):
    def greet(self): # python 类的定义中需要每个方法的声明中第一个参数是self
        print('hello')

第一个参数是self, 说明调用这个方法的对象自身在调用时不需要实参跟它对应.

# 定义类dog, 有一个方法是greet 
class dog(object):
    def greet(self): # python 类的定义中需要每个方法的声明中第一个参数是self
        print('hello')
                
#实例创建
dog1=dog() # dog1就是实例名
dog1.greet()  # 调用方法, hello

实例属性 instance attributes

class dog(object):
    def setname(self,name):
        self.name=name  # 相当于dog.name='paul'
    def greet(self):
        print('Hi, my name is %s'%self.name)
if __name__=='__main__': # 可以理解为一个程序的入口, 类似C中的main函数
    dog1=dog()
    dog1.setname('paul')
    dog1.greet()

dog.name 就是实例属性

重要的__init__方法:  对象的初始化方法 __int__()

当类被调用后, python会创建实例对象,
创建完对象之后, python自动调用的第一个方法是__int__(). 

实例对象作为方法的第一个参数(self)被传递进去,  调用类创建实例对象时的参数都传给__int__()

class dog(object):
    def __init__(self, name):
        self.name=name
    def greet(self):
        print('Hi, my name is %s.'%self.name)
if __name__=='__main__': # 可以理解为一个程序的入口, 类似C中的main函数
    dog1=dog('mike')
    dog1.greet() 

狗这个类是实例化之后都会自动创建名字, 每一个实例都要完成的事, 所以可以把它放到__init__方法中去. 

类属性 : cnt实现统计这个类被创建的实例对象个数 , cnt 与具体的对象无关, 只跟类有关, 成为类属性, 也叫静态属性. 

class dog(object):
    cnt=0
    def __init__(self, name):
        self.name=name
        dog.cnt+=1  # 修改类属性必要要用类名
    def greet(self):
        print('Hi, I am %s, my number id %d'%(self.name,dog.cnt))

if __name__=='__main__': # 可以理解为一个程序的入口, 类似C中的main函数
    dog1=dog('sara')
    dog1.greet()
    dog2=dog('jason')           
    dog2.greet()    
#Hi, I am sara, my number id 1
#Hi, I am jason, my number id 2  

 实例: roster 花名册

(1)__init__()方法对数据进行初始化,以班主任的姓名初始化;

(2)add():加入一个学生姓名;

(3)remove():按照姓名移除学生;

(4)print_all():输出班主任姓名和所有学生名单。

class roster(object):
    "students and teacher class"
    teacher = ""
    students = [ ]
    def __init__(self, tn = 'XY'):
        self.teacher = tn
    def add(self, sn):
        self.students.append(sn)
    def remove(self, sn):
        self.students.remove(sn)
    def print_all(self):
        print("Teacher:",self.teacher)
        print("Students:", self.students)        

r1=roster('scarlett')
r1.add('mike')
r1.add('jim')
r1.add('alice')
r1.add('kelly')
r1.remove('jim')
r1.print_all()
#Teacher: scarlett
#Students: ['mike', 'alice', 'kelly']

(二) 继承

在原有抽象的基础上进行修改, 生成新的抽象, 称作 继承

继承可以修改一个已经定义好的类, 将其修改生成一个新的类, 而不需要将原来的类再次实现一遍!

车--轿车, 救护车, 公共汽车...

 子类的定义: 

class subclassname(parentclass1):        
# 多个父类 class subclassname([parentclass1,parentclass2]):
    class_suite

单个父类叫做 单继承, 多个父类叫做 多继承

并不是所有的语言都支持多继承, java就不支持多继承

class dog(object):
    cnt=0
    def __init__(self, name):
        self.name=name
        dog.cnt+=1  # 修改类属性必要要用类名
    def greet(self):
        print('Hi, I am %s, my number id %d'%(self.name,dog.cnt))

# 定义一个子类, barkingdog, 父类是dog 
# 这里, 子类重写了父类的greet() 方法
class barkingdog(dog):
    def greet(self):
        print('woof!I am %s, my number is %d'%(self.name,dog.cnt))
if __name__=='__main__':
    dog=barkingdog('zoe')
    dog.greet()
#woof!I am zoe, my number is 1

注意: 如果父类的__init__ 初始化方法被子类修改, 那么父类的初始化方法就不会被自动调用, 

必须显式的写出来才会被执行. 

实例: 

class people:
    def __init__(self,n,a,w):
        self.name=n
        self.age=a
        self.weight=w  
    def speak(self):
        print('%s is speaking: I am %d years old'%(self.name,self.age))
        
p=people('mike',10,20)
p.speak()   #不用加print 
print p.name
print p.age

ans:
mike is speaking: I am 10 years old
mike
10

具体: 

class funset: 定义类的名称
    def fun1(self): self是特殊的参数,必须要有!:
        #类中函数的第一个参数必须是self,类中定义的函数称为 方法, fun1就是一个方法
        #do something
x=funset()#根据类funset 创建对象

为什么要用类 ,明明函数可以解决的事情?
函数与函数之间是独立的,没有共用的数据!!!
面向对象的三大特征:封装\继承\多态

1.封装

#封装:先把东西封装在某个地方,以后在拿出来调用

class funset:
    def __init__(self,name,age):
        self.name=name
        self.age=age
x=funset('xx',19) #将'xx'与19分别封装到x self的name与 age 属性中
y=funset('yy',20)
#self是一个形式参数,执行x=funset('xx',19) 时,self等于x;执行y=funset('yy',20),self=y
#内容被封装到了x, y 中,每个对象x,y都有name age 属性,

#调用封装: 通过对象直接调用被封装的内容
print x.name
print y.age

#调用封装: 通过self间接调用被封装的内容
class funset:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def detail(self):
        print self.name
        print self.age
x = funset('xx', 18)
print x.name    # 直接调用x对象的name属性
print x.age   
y=funset('alex', 73)
y.detail()    #间接调用, 默认将y传递给self参数,即x.detail(x)

 

解释__init__:init 创建完对象之后,pyhton会自动调用的方法,通过两个例子可以秒懂:

例1:

class dog(object):
    'define dog class'
    def setname(self,name):
        self.name=name #传递形参的效果:dog.name='wangcai'
    def greet(self):
        print('hi, my name is %s'%self.name)
if __name__=='__main__':#程序的入口,类似c语言中的main函数
    dog1=dog()
    dog1.setname('wangcai') #将参数传递给形参,
    #传递形参的效果:dog.name='wangcai'
    dog1.greet()

ans:hi, my name is wangcai

例2:

class dog(object):
    'define dog class'
    def __init__(self,name): #实例化之后会自动取名字
    #定义init,
        self.name=name 
    def greet(self):
        print('hi, my name is %s'%self.name)
if __name__=='__main__':
    dog1=dog('haha')#要是没有init那么 只能用dog1=dog(),dog1=dog('haha')中的haha传递不进去的
    dog1.greet()

 

练习1;

请输出:

小明,10岁,男,上山去砍柴
小明,10岁,男,开车去东北
小明,10岁,男,下山采蘑菇
老李,90岁,男,上山去砍柴
老李,90岁,男,开车去东北
老李,90岁,男,下山采蘑菇

方法一:面向函数

编写三个函数即可:

def kanchai(name, age, gender):
    print "%s,%s岁,%s,上山去砍柴" %(name, age, gender)
 
def qudongbei(name, age, gender):
    print "%s,%s岁,%s,开车去东北" %(name, age, gender)
 
def mogu(name, age, gender):
    print "%s,%s岁,%s,下山采蘑菇" %(name, age, gender)
 
kanchai('小明', 10, '')
qudongbei('小明', 10, '')
mogu('小明', 10, '')
kanchai('老李', 90, '')
qudongbei('老李', 90, '')
mogu('老李', 90, '')

方法二:面向对象

class funset:
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
    def kanchai(self):
        print '%s,%s岁,%s,上山砍柴'%(self.name,self.age,self.gender)
    def qudongbei(self):
        print '%s,%s岁,%s,开车去东北'%(self.name,self.age,self.gender)
    def mogu(self):
        print '%s,%s岁,%s,下山采蘑菇'%(self.name,self.age,self.gender)
xm=funset('小明',10,'')
xm.kanchai()
xm.qudongbei()
xm.mogu()

练习二:
创建三个游戏人物:
水,女,18,初始战斗力1000
木,男,20,初始战斗力1800
山,女,19,初始战斗力2500
游戏场景,分别是:
草丛战斗,消耗200战斗力
自我修炼,增长100战斗力
多人游戏,消耗500战斗力

class person:
    def __init__(self,name,gender,age,fight):
        self.name=name
        self.age=age
        self.gender=gender
        self.fight=fight
    def grassland(self):
        self.fight-=200
    def practice(self):
        self.fight+=200
    def incest(self):
        self.fight-=500
    def detail(self):
        temp='姓名:%s;性别:%s;年龄:%s;战斗力:%s'%(self.name,self.age,self.gender,self.fight)
        print temp
x=person('haha','',18,2400)
x.detail()
x.incest()
x.detail()
x.grassland()
x.detail()

ans:
姓名:haha;性别:18;年龄:女;战斗力:2400
姓名:haha;性别:18;年龄:女;战斗力:1900
姓名:haha;性别:18;年龄:女;战斗力:1700

应用实例:

从给出的数据文件中,找到成绩最好的学生:

class student:
    def __init__(self,name,hours,points):
        self.name=name
        self.hours=float(hours)
        self.points=float(points)
    def getname(self):
        return self.name
    def gethours(self):
        return self.hours
    def getpoints():
        return self.points
    def gpa(self):
        return self.points/self.hours
#
#s=student('xxx',100,10)
#print s.name
#print s.getname()#两者一样
     
def makestudent(info):
    name,hours,points=info.split('\t')
    return student(name,hours,points)
def main():
    f=open(r'C:\Users\xuyin\Desktop\test\info_student.txt')
    best=makestudent(f.readline())
    for line in f:
        if makestudent(line).gpa()>best.gpa():
            best=makestudent(line)
    f.close()
#    print('the best student is %s'%best.getname())
#    print('the hours are %.2f'%best.gethours())
#    print('the gpa is %.2f'%best.gpa())
    print('the best student is %s'%best.name) #不需要用getname
    print('the hours are %.2f'%best.hours)
    print('the gpa is %.2f'%best.gpa())
#if __name__=='__main__':#这一行不需要也可以的
main()

源数据:

ans:

the best student is ccc
the hours are 120.00
the gpa is 2.51

 

推荐阅读