1.面向过程和面向对象的区别

面向过程 : 需要用什么代码去解决什么问题

面向对象 : 我有什么可以给你什么

2.面向对象的特征

(1)封装

数据不想让别人接触到的

函数(过程) =》 方法(在面向对象中):提供函数、方法对数据进行访问和操作

(2)继承

有一块代码块 A(函数)

B 也想有一个代码块(函数)

(3)多态

一个对象可以体现不同的特征

3. 实验

创建一个类

>>>classPerson(object):...pass...

创建一个实例对象

>>>kk=Person()>>>type(kk)<class'__main__.Person'>

创建实例对象的属性

>>>kk.name='kk'>>>dir(kk)['__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__',\'__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__'\,'name']

定义类的属性

>>>classperson(object):...name='kk'...>>>kk=person()>>>kk.name'kk'

类、实例对象查找属性也是有顺序的:先在实例对象中找,如果实例对象中没,接着去类中属性找,如果类中属性没的话就报错了

小案例: 更好的区分类的属性和实例对象的属性

创建一个类

>>>classPerson(object):...name='kk'...

创建实例对象name1 并给实例对象添加 addr 属性

>>>name1=Person()>>>name1.addr='西安市'

创建实例对象name2 并给实例对象添加 age 属性

>>>name2=Person()>>>name2.age=25

测试访问name1 的age 属性 是报错的 因为 实例对象name1和类中都没有age属性

>>>name1.ageTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>AttributeError:'Person'objecthasnoattribute'age'

分别打印类、实例对象name1、实例对象name2的name属性

>>>print(person.name,name1.name,name2.name)kkkkkk

给实例对象name1重新设置一下name 属性,在依次打印name属性

>>>print(person.name,name1.name,name2.name)kkkk1kk

案例总结:

(1)类的属性和实例的属性可以动态赋值

(2)在访问实例对象的属性时,优先访问实例对象的属性;当实例对象的属性不存在的时候,去访问类的属性,类的属性不存在就报错

(3)实例对象设置和修改属性的时候,不会影响类的属性

4.类

初始化函数(构造函数)

以下类中的初始化函数

>>>classperson(object):...def__init__(self):...self.name='kk'...self.age=24...

创建一个实例对象

>>>name1=person()>>>name1.name'kk'>>>name1.age24

重新创建一个类

>>>classperson(object):...name='Dog'...def__init__(self):...self.name='dog'...

分别打印类和实例对象的name属性

>>>name1=person()>>>print(name1.name,person.name)dogDog

类的方法,如下创建类的方法

>>>classTest(object):...Name='Test'...@classmethod...defclass_method(cls):...print(cls.Name)...

访问类的方法

>>>Test.class_method()Test

创建实例对象test ,实例对象访问类的方法

>>>test=Test()>>>test.class_method()Test

实例的方法

>>>classTest(object):...Name='Test'...def__init__(self):...self.name='test'...definstance_method(self):...print(self.name)...print(self.Name)..

访问实例的方法

>>>t=Test()>>>t.instance_method()testTest

静态方法 (@staticmethod)

>>>classTest(object):...@staticmethod...defstatic_method():...print('static_method')...>>>Test.static_method()static_method

小案例

猫狗大战,猫的初始生命值是120 , 狗的初始生命值是100,random随机掉血,采用继承的方式

#!/usr/bin/pythonimportrandomclassAnimals(object):def__init__(self,name,blood=100):self.name=nameself.blood=blooddefget_name(self):returnself.namedefget_blood(self):returnself.blooddefdrop_blood(self,blood):self.blood-=blooddefattack(self,rival):drop=random.randint(0,20)rival.drop_blood(drop)print(self.name,'让',rival.name,'掉血',drop,'对手剩余:',rival.get_blood(),'血')classDog(Animals):passclassCat(Animals):passif__name__=='__main__':dog=Dog('wangwang')cat=Cat('miaomiao',120)whileTrue:dog.attack(cat)ifcat.get_blood()<0:print('胜利方是:',dog.get_name())breakcat.attack(dog)ifdog.get_blood()<0:print('胜利方是:',cat.get_name())break

执行结果:

重写父类的***方法,让狗***猫时掉血范围在10-30

classDog(Animals):defattack(self,rival):drop=random.randint(10,30)rival.drop_blood(drop)print(self.name,'让',rival.name,'掉血',drop,'对手剩余:',rival.get_blood(),'血')

重写父类的方法,当猫受到的***大于20 的时候自动补血 8

classCat(Animals):defdrop_blood(self,drop):super(Cat,self).drop_blood(drop)ifdrop>20:print('我掉了',drop,'滴血,触发自动补血技能')self.blood+=8

5.实例的私有属性

定义一个类

>>>classPerson(object):...def__init__(self,name,age):...self.__name=name...self.__age=age...

创建一个实例,并尝试访问实例的属性,会报错

>>>kk=Person('kk',30)>>>kk.nameTraceback(mostrecentcalllast):File"<stdin>",line1,in<module>AttributeError:'Person'objecthasnoattribute'name'

私有属性的访问

>>>kk._Person__age30

@property 和 @方法名.setter的使用

@property 把一个方法变成属性去调用

@方法名.setter是把一个方法变成属性赋值

>>>classPerson(object):...def__init__(self,name,age):...self._name=name...self._age=age...@property...defname(self):...returnself._name...@name.setter...defname(self,value):...self._name=value...

访问测试

>>>kk=Person('kk',20)>>>kk.name'kk'>>>kk.name='kk1'>>>kk.name'kk1'