python面向对象编程基础
目录
属性与方法
继承机制
抽象类
多重继承
@property装饰器
多态
运算符重载
面向对象程序设计(Object Oriented Programming,OOP)主要针对大型软件设计而提出,是得软件设计更加灵活,能够很好地支持代码复用和设计复用,并且是的代码具有更好的可读性和可扩展性。
Python中对象的概念很广泛,Python中的一切内容都可以称为对象。
Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现
定义了类之后。可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法。
在Python中,可以使用内置方法isinstance()来测试一个对象是否为某个类的实例。
Python提供了一个关键字“pass”,类似于空语句,可以用再类和函数的定义中或者选择结构中。当咱叔没有确定如何实现功能,或者为以后的软件升级预留空间,或者其他类型功能时,可以使用改关键字来“占位”
类的所有实例方法都必须至少有一个名为sel的参数,并且必须是方法的第一形参(如果多个形参的话),self参数代表当前对象(当前正在调用方法的对象)
在类的实例方法中访问实例属性时需要以self为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数。
一、属性
Python的属性分为实例属性和类属性
实例属性是在类内部定义的属性,可以被类中的所有实例共享
注意:如果属性的名字以两个下划线开始,就表示私有属性(方法也一样)不可以调用,一个下划线,也表示私有属性,外部可以调用
class Businessman: def __init__(self,name,age,money): self.name = name self.age = age self.__money = money # __money为私有属性,只能在当前类中访问该私有属性 def getMoney(self): return self.__money # 可以通过类的内部访问私有属性 bs = Businessman("马云",55,200) print("实例化对象的名字:",bs.name) print("实例化对象的年龄:",bs.age) #print("实例化对象的财产:",bs.__money) #报错 print(bs._Businessman__money) # 可以通过 " _类名__实例化属性名"的方式访问私有属性 print("该商人的财产是:",bs.getMoney())
class Person: count = 0 # 类属性 def __init__(self,name,age,sex): self.name = name # name实例属性 self.age = age # age实例属性 self.sex = sex # sex实例属性 def say(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)
class Worker: # 初始化方法 def __init__(self,name,age): print("一个对象实例化了...") self.name = name # 给name属性赋值,self.name说明name为该对象的一个实例属性 self.age = age # 给age属性赋值,self.age说明age为该对象的一个实例属性 def repair(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)的执行
class Person: 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接收,静态方法没有参数)
class Animal: def __init__(self,name,color): self.name = name self.color = color @classmethod # 相当于 run = classmethod(run) def run(cls): # 能被转化为类方法的方法,第一个参数必须接收一个对象,该对象(cls)代表类本身 print("动物在跑...") def drink(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)
class Person(object): @staticmethod # 相当于 play = staticmethod(play) def play(): print("人在玩耍...") def work(): print("working...") person_work = staticmethod(work) # 使用staticmethod()函数将work()方法转换为静态方法 per = Person() per.play() # 使用实例化对象调用“静态方法” Person.play() # 使用类调用“静态方法” print("*************************************************************") per.person_work() Person.person_work()
四、继承
继承是为代码复用 和设计复用而设计的,是面向对象程序设计的重要特性之一。设计一个新类时,如果可以及继承一个已有的设计良好的类然后进行二次开发,无疑会大幅度减少开发工作量。
在继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或者派生类。派生类可以继承父类的共有成员,但是不能继承其私有成员。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式来实现这一目的。
class Person: def __init__(self,name,age,sex): self.__name = name self.__age = age self.__sex = sex def play(self): print("人在玩耍...") def setName(self,name): self.__name = name def getName(self): return self.__name def setAge(self,age): if age<=0 or age >= 120: print("年龄不合法!") else: self.__age = age def getAge(self): return self.__age class Worker(Person): def __init__(self,name,age,sex,skill): Person.__init__(self,name,age,sex) self.skill = skill def play(self): # Worker类中重写了父类的play()方法 print("工人在娱乐...") # Person.play(self) w = Worker("汤姆",25,"男","修车") w.play() w.setAge(35) print("年龄是:",w.getAge())
多重继承
python支持多重继承,即一个类可以继承多个父类。注意:子类根据父类的顺序继承构造方法。
class Fruit: def __init__(self,name,price): print("fruit init...") self.name = name self.price = price def grow(self): print("水果生长...") class Vegetable: def __init__(self): print("vegetable init...") def plant(self): print("种植蔬菜...") class Watermelon(Vegetable,Fruit): pass w = 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 @abstractmethod def eat(self): pass def sleep(self): print("动物睡觉...") class Dog(Animal): def eat(self): # 重写继承而来的抽象方法 print("小狗啃骨头...") dog = Dog("旺财","黄色") dog.eat() dog.sleep()
六、@property装饰器的应用
@property使方法像属性一样调用,就像是一种特殊的属性
@property装饰器使属性的访问更加方便,而且可以对属性的赋值加入检查机制
class Person: def __init__(self,name,age): self.__name = name self.__age = age @property # @property 将age()方法转变为age属性 def age(self): return self.__age @age.setter def age(self,age): if age <= 0 or age >= 120: raise ValueError("年龄不符合要求,必须是0~120之间") # 引发异常 self.__age = age def __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)
七、多态
多态:多态值得是一类事物有多钟形态
鸭子类型是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由“当前方法和属性的集合”决定。“当看到一只鸟走起来想鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
结论:Python 崇尚鸭子类型,即“如果看起来像、叫声而且走起路来像鸭子,那么它就是鸭子”
八、运算符重载
Python把运算符和类的内置方法关联起来,每个运算符都对应1个函数
__add__(self,other)表示加法运算符"+"
__sub__(self,other)表示减法运算符“-”
__gt__(self,other)表示减法运算符“>”
__lt__(self,other)表示减法运算符“=”
__eq__(self,other)表示减法运算符“==”
class Student: def __init__(self,name,age,sex,score): self.name = name self.age = age self.sex = sex self.score = score def __add__(self, other): return self.score + other.score def __sub__(self, other): return self.score - other.score # 小于 def __lt__(self, other): return self.score < other.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) print(stu1 >= stu2)

浙公网安备 33010602011771号