python面向对象下
封装
封装是面向对象的核心思想。它是指将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏细节,这就是封装的思想。
私有属性:我们在属性前加两个下划线表示的是私有属性
封装的方法
我们写如下的代码:
class Student():
def __init__(self,myName,myScore):
self.name,self.score=myName,myScore
def __str__(self):
return '姓名:'+str(self.name)+'\t成绩:'+str(self.score)
s1=Student('ohhh',100)
print(s1)
s1.score=-18
print(s1)
以上的结果如下:
我们在实际情况中,通常是不能将成绩改成负数的,所以这里为了防止用户的自我修改,就用到了封装
下面是封装后的代码:
class Student():
def __init__(self,myName,myScore):
self.name,self.__score=myName,myScore
def __str__(self):
return '姓名:'+str(self.name)+'\t成绩:'+str(self.__score)
s1=Student('ohhh',100)
print(s1)
s1.__score=-18
print(s1)
下面是程序的执行图:
我们发现将__score这个变量不能够被函数外面的引用修改我们可以想一下在游戏中,我们可以自己修改自己的用户名,但是自己不能修改自己的等级,和这个封装很类似
获取私有属性
我们通常应该提供设置或获取属性值的两个方法供外界使用,如下面的代码:
class Student():
def __init__(self,myName,myScore):
self.name=myName
self.setScore(myScore)
def setScore(self,myScore):
if(myScore>=0 and myScore<=100):
self.__score=myScore
else:
self.__score=0
print("输入的成绩有误!")
def getScore(self):
return self.__score
def __str__(self):
return '姓名:'+str(self.name)+'\t成绩:'+str(self.__score)
s1=Student('ohhh',-100)
print(s1)
s2=Student('ojjj',89)
print(s2)
下面是代码结果:
继承
用于描述类的所属关系,多个类通过继承形成一个关系体系
单一继承
语法格式
单一继承只有一个基类,继承关系比较简单,操作比较容易,因此使用相对较多
语法格式如下代码:
class People(object): #object通常省略
print('人们有不同的职业')
class Student(People):
print('我们都一样')
派生类继承于基类,派生类可以使用基类的所有公有成员,也可以定义新的属性和方法,从而完成对基类的扩展,python中所有的类继承于object,但是其通常省略
同名的情况
如果派生类中的属性和方法同名,那么派生类实例对象调用派生类中的定义的属性和方法,如下例所示:
class Person(object):
def __init__(self,name):
self.name='wan' #实例对象
def show(self):
print("姓名",self.name)
class Student(Person):
def __init__(self,name,score):
self.name,self.__score=name,score
def __str__(self):
return "姓名:"+self.name+' '+'分数:'+str(self.__score)
s1=Student('qian',100)
print(s1)
下面是代码运行结果:
派生类中方法重写调用原方法的方式
如果派生类的构造函数中需要添加参数,则可以再派生类中调用基类,如下例所示:(也有很多其他的方法,如直接给继承的变量赋新值就可以)
class Person(object):
name='ccc'
def __init__(self,name):
self.name='wan'
def show(self):
print("姓名",self.name)
class Student(Person):
def __init__(self,name,score):
super(Student,self).__init__(name)
# Person.__init__(self,name) # 这两种形式都可以
self.__score=100
def __str__(self):
return "姓名:"+self.name+' '+'分数:'+str(self.__score)
s1=Student('qian',100)
print(s1)
下面是运行结果:
我们发现,这个虽然传入了自己的参数,但是输出的name是基类中的名字
私有属性的调用方法
这里要注意的是基类的私有属性和方法是不会被派生类继承的,因此,派生类不能反问基类的私有成员,但是可以通过相应的方法间接调用,如下例所示:
class Person(object):
def __init__(self,name):
self.__name=name
def __show(self):
print("姓名:",self.__name)
def get_name(self):
print(self.__name)
def get_method(self):
self.__show()
class Student(Person):
def test(self):
print(self.__name)
def test1(self):
self.get_name()
self.get_method()
s1=Student('1111')
# s1.test()# 我们会发现调用这个的话会报错
s1.test1()
下面是输出结果:
我们发现对于基类中的私有变量,我们只能通过一定的方法去访问,不能直接访问
多重继承
语法格式
多重继承就是指派生类同时继承多个基类,其语法格式如下:
class 基类1(object):
类体
class 基类2(object):
类体
class 派生类(基类1,基类2):
类体
格式很简单,就是再派生类里面依次写上要继承的类名即可。
小例子
下面是一个样例代码:
class Student(object):
def __init__(self,name,score):
self.name,self.score=name,score
def showStd(self):
print('姓名:',self.name,'分数:',self.score)
class Staff(object):
def __init__(self,id,salary):
self.id,self.salary=id,salary
def showStf(self):
print('ID:',self.id,'薪资:',self.salary)
class jobGraduate(Student,Staff):
def __init__(self,name,score,id,salary):
Student.__init__(self,name,score)
Staff.__init__(self,id,salary)
g1=jobGraduate('qian',100,'001',1000000)
g1.showStd()
g1.showStf()
下面是输出结果:
同名的情况
在多重继承中,如果基类存在同名的方法,python按照继承顺序从左到右在基类中搜索方法
如下例:
class Student(object):
def __init__(self,name,score):
self.name,self.score=name,score
def showStf(self):
print('姓名:',self.name,'分数:',self.score)
class Staff(object):
def __init__(self,id,salary):
self.id,self.salary=id,salary
def showStf(self):
print('ID:',self.id,'薪资:',self.salary)
class jobGraduate(Student,Staff):
def __init__(self,name,score,id,salary):
Student.__init__(self,name,score)
Staff.__init__(self,id,salary)
g1=jobGraduate('qian',100,'001',1000000)
g1.showStf()
我们将两个方法改成同名,发现是执行的继承的第一个对象:
总的来说,多重继承和单一继承是一样的,只是有一个在继承的类中依次查询变量的过程
多态
多态是指基类的同一个方法在不同的派生类对象中具有不同的表现和行为,当调用该方法时,程序会根据对象选择合适的方法
下面是一个例子:
class animal(object):
def __init__(self,name,call):
self.name=name
self.call=call
def say(self):
print(self.call)
def get(self):
print(self.name)
class dog(animal):
def __init__(self):
self.name='dog'
self.call='汪汪'
class cat(animal):
def __init__(self):
self.name='cat'
self.call='喵喵'
an1=dog()
an1.say()
an1.get()
an2=cat()
an2.say()
an2.get()
设计模式
工厂模式
工厂模式主要用来实例化有共同方法的类,他可以动态化决定应该实例化哪个类,不必事先知道每次要实例化哪个类。例如:在编写一个应用程序时,用户可能会连接各种各样的数据库,但开发者不能预知用户会使用哪个数据库,于是提供一个通用方法,里面包含了各个数据库的连接方案,用户在使用过程中,只需要传入数据库的名字并给出连接所需要的信息即可,如例所示:
class Operation():
def connect(self):
pass
class MySQL(Operation):
def connect(self):
print("连接MySQL成功")
class SQLite(Operation):
def connect(self):
print("连接SQLite成功")
class DB():
@staticmethod
def create(name):
name=name.lower()
if(name=='mysql'):
return MySQL()
elif(name=='sqlite'):
return SQLite()
else:
print("不支持其他数据库")
if(__name__=='__main__'):
db1=DB.create('MySQL')
db1.connect()
db2 = DB.create('SQLite')
db2.connect()
简单来说,就是用一个类将一些类包装起来,通过返回实例对象的方式来创建。
适配器模式
适配器是指一种接口适配技术,实现两个不兼容接口之间的兼容,例如原程序中存在类Instrument与Person,其中Instrument可以调用play()方法,Person实例对象可以调用act()方法新程序中增加类Computer,其实例对象可以调用execute()方法。现要求类Instrument与Person的实例对象execute()调用各自的方法,具体如例所示:
class Instument():
def __init__(self,name):
self.name=name
def play(self):
print(self.name,'演奏')
class Person():
def __init__(self,name):
self.name=name
def act(self):
print(self.name,'表演')
class Computer():
def __init__(self,name):
self.name=name
def execute(self):
print(self.name,'执行程序')
class Adapter():
def __init__(self,obj,adaptedeMthods):
self.obj=obj
self.__dict__.update(adaptedeMthods)
if(__name__=='__main__'):
obj1=Instument('guitar')
Adapter(obj1,dict(execute=obj1.play)).execute()
obj2=Person('xiao')
Adapter(obj2,dict(execute=obj2.act)).execute()
上面这个例子我不是很懂,就是按照自我感觉写了一个自己的例子:
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self,money):
pass
class Alipay(Payment):
def pay(self,money):
print("pay ",money," in alipay way...")
class WechatPay(Payment):
def pay(self,money):
print("pay ",money," in wechat way...")
class BankPay(object):
def cost(self,money):
print("pay ",money," in bankpay way...")
class PaymentAdapter(Payment):
def __init__(self,payment1,payment2):
self.payment1=payment1
self.payment2=payment2
def pay(self,money):
self.payment1.pay(money)
def cost(self,money):
self.payment2.cost(money)
if __name__=="__main__":
p=Alipay()
p.pay(100)
p2 = PaymentAdapter(WechatPay(),BankPay())
p2.pay(100)
p2.cost(100)
自我感觉就是将多个类的方法放到一个类中,然后通过这个类来调用其他类的方法。