面向对象编程是一种解决软件复用的设计和编程方法。 这种方法把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。
类(class):就是对一类事物的描述,是抽象的,是概念上的定义.
对象(object):是该类事物存在的个体(对象),也叫实例(instance)
# 定义类 class 类名: ? ? ? ?方法列表 # 创建对象 对象名 = 类名()
类中的方法有普通方法、类方法、静态方法、魔术方法
普通方法永远依赖对象,因为每一个普通方法都有self参数;只有创建了对象才能调用普通方法,否则无法调用。
class student: ? ?def study(self): ? ? ? ?print('学习') ? ?def action(self): ? ? ? ?print('活动')
类方法的定义需要依赖装饰器@classmethod,此时,向该方法传递参数时,会将类(cls)作为参数传递过去;类方法中,只可以使用类属性;同理,类方法中也不能使用普通方法。
在对象创建之前,如果需要完成一些动作(或功能),就可以借助类方法来完成(类方法不依赖于对象,其可以单独调用,它只能对类的属性和方法进行操作,与对象无关)
class student: ? ?name = ' ' ? ?def study(self): ? ? ? ?print('学习') ? ?def action(self): ? ? ? ?print('活动') ? ?@classmethod ? ?def test1(cls): ? ? ? ?name = '李四' ? ? ? ?print(name)
需要装饰器@staticmethod,静态方法是无需传递参数(self、cls)的,也只能访问类的属性和方法,对象是无法访问的。
class student: ? ?name = ' ' ? ?def study(self): ? ? ? ?print('学习') ? ?def action(self): ? ? ? ?print('活动') ? ?@classmethod ? ?def test1(cls): ? ? ? ?name = '李四' ? ? ? ?print(name) ? ?@staticmethod ? ?def test2(): ? ? ? ?print('静态方法')
魔术方法就是一个类或对象中的方法,和普通方法唯一的区别是,普通方法需要调用,而魔术方法是在特定的时刻自动触发。
# __init__()是魔术方法之一,该方法在类实例化时会自动调用。可以用作初始化操作 class student: ? ?name = ' ' ? ?sno = 0 ? ?age = 0 ? ?def study(self): ? ? ? ?print('学习') ? ?def action(self): ? ? ? ?print('活动') ? ?def __init__(self, name, sno, age): ? ? ? ?self.name = name ? ? ? ?self.sno = sno ? ? ? ?self.age = age
在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的),私有化的属性和方法只能在本类(class )中使用。
若要修改和访问私有属性,需要通过set和get方法
class student: ? ?__name = ' ' ? ?def study(self): ? ? ? ?print('学习' ? ?def __init__(self, name): ? ? ? ?self.__name = name ? ?def getname(self): ? ? ? ?return self.__name ? ?def setname(self, name): ? ? ? ?self.__name = name # 实质上,Python解释器是通过修改属性名进行的私有化,它在属性名前拼接了类名,即由__age,变成了__Student__age。
继承描述的是事物之间的所属关系,父类的属性、方法都会继承给子类。在定义子类时小括号()中为父类的名字。
class Animal: ? ?def eat(self): ? ? ? ?print("-----吃饭----") ? ?def drink(self): ? ? ? ?print("-----喝水----") ? class Dog(Animal): ? ?def bark(self): ? ? ? ?print("----汪汪---") ? class Cat(Animal): ? ?def catch(self): ? ? ? ?print("----抓老鼠----") ? wangcai = Dog() wangcai.eat() wangcai.bark() ? tom = Cat() tom.eat() tom.catch()
Python中是可以多继承的,即一个子类有多个父类,并且具有它们的特征;如果多个父类中,有一个同名的方法,那么通过子类去调用的该方法的时候,和类的对象搜索方法时的先后顺序有关。
class A: ? ?def printA(self): ? ? ? ?print('----A----') ? ?def test(self): ? ? ? ?print('----A test----') ? class B: ? ?def printB(self): ? ? ? ?print('----B----') ? ?def test(self): ? ? ? ?print('----B test----') ? ? ? ? class C(A,B): ? ?pass ? obj_C = C() obj_C.printA() ?-> A obj_C.printB() ?-> B obj_C.test() ?-> A test ? # 方法重写就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法 class C(A,B): ? ?def test(self): ? ? ? ?print('----C test----') obj_C = C() obj_C.test() ?-> C test
# 在子类中调用父类的方法时: 父类类名.父类的方法(self) super(子类的类名,self).方法名() super().父类的方法名() class ju: chang = 0 kuan = 0 def mj(self): return self.chang * self.kuan class ti(ju): gao = 0 def tj(self): return super().mj() * self.gao def __init__(self, chang, kuan, gao): self.chang = chang self.kuan = kuan self.gao = gao
定义时的类型和运行时的类型不一样就称为多态
class F1: def show(self): print('F1.show') class S1(F1): def show(self): print('S1.show') class S2(F1): def show(self): print('S2.show') def Func(obj): obj.show() s1_obj = S1() Func(s1_obj) -> S1.show s2_obj = S2() Func(s2_obj) ->S2.show
class People1: address = '山东' #类属性 def __init__(self): self.name = 'xiaowang' #实例属性 self.age = 20 #实例属性 p = People1() p.age =12 #实例属性 print(p.address) #正确 print(p.name) #正确 print(p.age) #正确 print(People1.address) #正确 print(People1.name) #错误 print(People1.age) #错误
如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
class People(object): country = 'China' #类属性 print(People.country) --> China p = People() print(p.country) --> China p.country = 'USA' print(p.country) --> USA #实例属性会屏蔽掉同名的类属性 print(People.country) --> China del p.country #删除实例属性 print(p.country) --> China