目录
属性与方法
继承机制
抽象类
多重继承
@property装饰器
多态
运算符重载
面向对象程序设计(Object Oriented Programming,OOP)主要针对大型软件设计而提出,是得软件设计更加灵活,能够很好地支持代码复用和设计复用,并且是的代码具有更好的可读性和可扩展性。
Python中对象的概念很广泛,Python中的一切内容都可以称为对象。
Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现
定义了类之后。可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法。
在Python中,可以使用内置方法isinstance()来测试一个对象是否为某个类的实例。
Python提供了一个关键字“pass”,类似于空语句,可以用再类和函数的定义中或者选择结构中。当咱叔没有确定如何实现功能,或者为以后的软件升级预留空间,或者其他类型功能时,可以使用改关键字来“占位”
类的所有实例方法都必须至少有一个名为sel的参数,并且必须是方法的第一形参(如果多个形参的话),self参数代表当前对象(当前正在调用方法的对象)
在类的实例方法中访问实例属性时需要以self为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数。
一、属性
Python的属性分为实例属性和类属性
实例属性是在类内部定义的属性,可以被类中的所有实例共享
注意:如果属性的名字以两个下划线开始,就表示私有属性(方法也一样)不可以调用,一个下划线,也表示私有属性,外部可以调用
classBusinessman:def __init__(self,name,age,money):
self.name=name
self.age=age
self.__money = money #__money为私有属性,只能在当前类中访问该私有属性
defgetMoney(self):return self.__money #可以通过类的内部访问私有属性
bs = Businessman("马云",55,200)print("实例化对象的名字:",bs.name)print("实例化对象的年龄:",bs.age)#print("实例化对象的财产:",bs.__money) #报错
print(bs._Businessman__money) #可以通过 " _类名__实例化属性名"的方式访问私有属性
print("该商人的财产是:",bs.getMoney())
私有属性
classPerson:
count= 0 #类属性
def __init__(self,name,age,sex):
self.name= name #name实例属性
self.age = age #age实例属性
self.sex = sex #sex实例属性
defsay(self):print("我叫",self.name,",今年",self.age,"岁了,性别:",self.sex)
per1= Person("张三",20,"男") #实例化per1对象
per2 = Person("李红",22,"女") #实例化per2对象
per1.say()
per2.say()
Person.count= Person.count + 10 #给类属性加10
print("改变count类属性之后的值:",Person.count)print("通过实例化对象访问count类属性:",per1.count)
per1.count= per1.count + 10 #相当于对per1对象的count实例化属性赋值(动态添加了一个count实例化属性)
print("给per1实例化对象添加count实例属性之后的值:",per1.count)
类属性
classWorker:#初始化方法
def __init__(self,name,age):print("一个对象实例化了...")
self.name= name #给name属性赋值,self.name说明name为该对象的一个实例属性
self.age = age #给age属性赋值,self.age说明age为该对象的一个实例属性
defrepair(self):print("名字叫",self.name,"的电工,年龄为:",self.age,"正在修电灯...")
w= Worker("tom",20) #实例化对象,完成实例化对象之后会自动去调用__init__(self,name,age)方法
w.repair()
二、方法
__init__()方法:构造方法,用来初始化新创建的对象
__str__(self)方法:返回一个字符串,实现了__str(self)方法后,可以直接使用print语句输出对象,也可以通过str()触发__str__(self)的执行
classPerson:def __init__(self,name,age):
self.name=name
self.age=age#实现了__str__(self)方法后,直接打印对象或使用str( )函数转换对象为字符串,都会触发该__str__(self)方法
def __str__(self):return "我叫" + self.name + ";今年" + str(self.age) +"岁了"per= Person("tom",20)print(per)print(str(per))
三、静态方法与类方法
Python使用函数staticmethod()或@staticmethod修饰器把普通的函数转化为静态方法
类方法是将类本身作为操作对象的方法。类方法可以使用函数classmethod()或@classmethod修饰器定义,把类作为第一个参数传递
区别:类方法咦类本身作为第一个参数(习惯用cls接收,静态方法没有参数)
classAnimal:def __init__(self,name,color):
self.name=name
self.color=color
@classmethod#相当于 run = classmethod(run)
def run(cls): #能被转化为类方法的方法,第一个参数必须接收一个对象,该对象(cls)代表类本身
print("动物在跑...")defdrink(cls,a,b,c):print("动物在喝水...")
animal_drink= classmethod(drink) #通过classmethod()方法将drink方法转换为类方法
animal= Animal("小狗","棕色")
animal.run()
animal.animal_drink(1,2,3)
Animal.animal_drink(4,5,6)
classmethod
classPerson(object):
@staticmethod#相当于 play = staticmethod(play)
defplay():print("人在玩耍...")defwork():print("working...")
person_work= staticmethod(work) #使用staticmethod()函数将work()方法转换为静态方法
per =Person()
per.play()#使用实例化对象调用“静态方法”
Person.play() #使用类调用“静态方法”
print("*************************************************************")
per.person_work()
Person.person_work()
staticmethod
四、继承
继承是为代码复用 和设计复用而设计的,是面向对象程序设计的重要特性之一。设计一个新类时,如果可以及继承一个已有的设计良好的类然后进行二次开发,无疑会大幅度减少开发工作量。
在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或者派生类。派生类可以继承父类的共有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式来实现这一目的。
classPerson:def __init__(self,name,age,sex):
self.__name =name
self.__age =age
self.__sex =sexdefplay(self):print("人在玩耍...")defsetName(self,name):
self.__name =namedefgetName(self):return self.__name
defsetAge(self,age):if age<=0 or age >= 120:print("年龄不合法!")else:
self.__age =agedefgetAge(self):return self.__age
classWorker(Person):def __init__(self,name,age,sex,skill):
Person.__init__(self,name,age,sex)
self.skill=skilldef play(self): #Worker类中重写了父类的play()方法
print("工人在娱乐...")#Person.play(self)
w= Worker("汤姆",25,"男","修车")
w.play()
w.setAge(35)print("年龄是:",w.getAge())
继承
多重继承
python支持多重继承,即一个类可以继承多个父类。注意:子类根据父类的顺序继承构造方法。
classFruit:def __init__(self,name,price):print("fruit init...")
self.name=name
self.price=pricedefgrow(self):print("水果生长...")classVegetable:def __init__(self):print("vegetable init...")defplant(self):print("种植蔬菜...")classWatermelon(Vegetable,Fruit):passw=Watermelon()
w.grow()
w.plant()
多继承
五、抽象类
抽象类是对一类事物特征行为的抽象,可以包含抽象方法
在python3中可以使用abc模块,该模块中一个元素ABCMeta和修饰器@abstractmethod。
1.抽象类不能被直接实例化
2.抽象类中的抽象方法在子类中必须重写,否则无法实例化该抽象类的子类对象
class Animal(metaclass=ABCMeta):def __init__(self,name,color):
self.name=name
self.color=color
@abstractmethoddefeat(self):pass
defsleep(self):print("动物睡觉...")classDog(Animal):def eat(self): #重写继承而来的抽象方法
print("小狗啃骨头...")
dog= Dog("旺财","黄色")
dog.eat()
dog.sleep()
abstractmethod
六、@property装饰器的应用
@property使方法像属性一样调用,就像是一种特殊的属性
@property装饰器使属性的访问更加方便,而且可以对属性的赋值加入检查机制
classPerson:def __init__(self,name,age):
self.__name =name
self.__age =age
@property#@property 将age()方法转变为age属性
defage(self):return self.__age@age.setterdefage(self,age):if age <= 0 or age >= 120:raise ValueError("年龄不符合要求,必须是0~120之间") #引发异常
self.__age =agedef __str__(self):return "我叫" + self.__name + ",今年" + str(self.__age) + "岁了"per= Person("令狐冲",20)
per.age= 50 #设置age属性,会自动触发由@age.setter修饰的方法
print(per.age) #访问age属性,该age属性是由@property装饰的方法得来的,属性名就是@property修饰的方法名,属性值是装饰的方法返回值
print(per)
property
七、多态
多态:多态值得是一类事物有多钟形态
鸭子类型是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由“当前方法和属性的集合”决定。“当看到一只鸟走起来想鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
结论:Python 崇尚鸭子类型,即“如果看起来像、叫声而且走起路来像鸭子,那么它就是鸭子”
八、运算符重载
Python把运算符和类的内置方法关联起来,每个运算符都对应1个函数
__add__(self,other)表示加法运算符"+"
__sub__(self,other)表示减法运算符“-”
__gt__(self,other)表示减法运算符“>”
__lt__(self,other)表示减法运算符“=”
__eq__(self,other)表示减法运算符“==”
classStudent:def __init__(self,name,age,sex,score):
self.name=name
self.age=age
self.sex=sex
self.score=scoredef __add__(self, other):return self.score +other.scoredef __sub__(self, other):return self.score -other.score#小于
def __lt__(self, other):return self.score
def __gt__(self, other):return self.score >other.score#等于
def __eq__(self, other):return self.age ==other.age#大于等于
def __ge__(self, other):return self.score >=other.score
stu1= Student("张三",25,"男",85)
stu2= Student("李四",25,"男",70)print(stu1 + stu2) #stu1 + stu2相当于: stu1.__add__(stu2)
print(stu1 == stu2) #默认比较的是内存地址是否相同,但可以通过在类中实现__eq__(self,other)改变默认的比较规则
print(stu1 -stu2)print(stu1 >stu2)print(stu1 = stu2)
View Code