把数据及数据的操作方法放在一起,作为一个整体–对象
对同列对象抽象出其共性,形成类
类中的大多数数据,只能用本类的方法进行处理
类的设计:
事务名称(类):人
属性:身高
行为(功能):跑
创建类:
类是一种数据类型,本身并不占内存空间,跟所学的Number,string等类似,用类创建实例化对象(变量),对象占内存空间
格式:
class 类名(父类列表):
属性
行为
#object:基类,超类,所有类的父类,一般没有合适的父类就写object
class Person(object):
#定义属性(定义变量)
name = ''
age = 0
height = 0
weight = 0
#定义方法(定义函数)
#注意:方法的参数必须以self当第一个参数
#self代表类的实例(某个对象)
def run(self):
print('run')
def eat(self,food):
pritn(food)
实例化对象
格式:对象名 = 类名(参数列表)
注意:没有参数小括号也不能省略
per=Person()
(创造一个对象去做事情)
访问属性:
格式:对象名.属性名
赋值:对象名.属性名 = 新值
per.name = ‘tom’
per.age = 18
访问方法:
格式:对象名.方法名(参数列表)
per.run()
per.eat(‘apple’)
以上方法的所有的对象的属性都相同
构造函数:init() 在使用类创建对象的时候自动调用
per=Person()创建对象时调用
def init(self,name,age,height):
self.name=name (当前对象per的name为name)
self.age=age
self.height=height
per=Person(‘ha’,20,170)
(可以使不同的对象有不同的值的属性)
self代表类的实例,而非类
哪个对象调用方法,那么该方法中的self就代表那个对象
self.class 代表类名
析构函数:del() 释放对象时自动调用
del per
在函数里定义的对象,会在函数结束时自动释放,这样可以用来减少内存空间的浪费
def fun():
per=Person(‘z’,12,33)
fun()
重写:将函数重新定义写一遍
str():在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法
repr():是给机器用的,在python解释器里面直接敲对象名在回车后调用的方法
注意:在没有str时,且有repr,str = repr
class Person(object):
def __init__(self, name,age,height,weight):
self.name=name
self.age=age
self.height=height
self.weight=weight
def __repr__(self):
return '%s,%d,%d'%(self.name,self.age,self.weight)
per=Person('zhang',11,11,11)
print(per)
访问限制
让内部的属性不被外部直接访问(per.age=10),在属性前加两个下划线,属性就变成了私有属性,可以改为self.__money=money,外部不可使用per.__money。可以通过自定义的方法实现对私有属性的赋值和取值:def setmoney(self,money)
不能直接访问per.__money是因为python解释器把__money变成了Person__money,仍然可以用person__money去访问,但是不建议这么做,不同的解释器可能存在解释的变量名不一致
在Python中,__xx__属于特殊变量,可以直接访问
print(per.age)
人开枪射击子弹
class Gun(object):
def __init__(self,bulletBox):
self.bulletBox = bulletBox
def shoot(self):
if self.bulletBox.bulletCount == 0:
print('没有子弹了')
else:
self.bulletBox.bulletCount -= 1
print('剩余子弹%d'%self.bulletBox.bulletCount)
class Person(object):
def __init__(self,gun):
self.gun = gun
def fire(self):
self.gun.shoot()
def fillBullet(self,count):
self.gun.bulletBox.bulletCount += count
bulletBox=BulletBox(5)
gun=Gun(bulletBox)
per=Person(gun)
per.fire()
per.fire()
per.fillBullet(2)
per.fire()
继承:有两个类,A类和B类,当我们说A类继承自B类的时候,那么A类就拥有了B类中的所有的属性和方法。object类是所有类的父类,还可以称为基类或超类。继承者称为子类,被继承者称为父类。
继承的作用:简化代码,减少冗余;提高的代码的健壮性;提高了代码的安全性;是多态的前提
缺点:耦合与内聚是描述类与类之间的关系的,耦合性越低,内聚性越高代码越好,继承的耦合性高。
from person import Person
class Student(Person):
def __init__(self,name,age,stud):
#调用父类中的__init__
super(Student,self).__init__(name,age)
# 子类可以有自己独有的属性
self.stud = stud
stu=Student('tom',18,100)
print(stu.age)
print(stu.name)
stu.run()
print(stu.stud)
多继承:
class Child(Father,Mother):
def init(self,money,faceValue):
Father.init(self,money)
Mother.init(self,faceValue)
注意:父类中方法名相同,默认调用的是在括号中排前面的父类中的方法
多态:一种事务的多种形态
class Animal(object):
def __init__(self,name):
self.name = name
def eat(self):
print("%s is eating"%self.name)
class Dog(Animal):
def __init__(self,name):
super(Dog,self).__init__(name)
dog1=Dog('TOM')
dog2=Dog('JERRY')
class feedanimal(object):
def __init__(self,ani):
self.ani = ani
self.ani.eat()
feedanimal(dog1)
feedanimal(dog2)
对象属性与类属性
类属性是用类名来调用的,对象属性的优先级高于类属性
class Person(object):
name=‘person’
print(Person.name)
动态添加属性:
class Person(object):
slots = (’name’,‘age’,‘speak’)
per = Person()
per.name = ‘tom’
限制属性的添加
解决:定义类的时候,定义一个特殊的属性(slots),可以限制动态添加的属性
运算符重载
class Person(object):
def init(self,num):
self.num = num
def __add__(self,other):
return Person(self.num+other.num)
def __str__(self):
return str(self.num)
per1=Person(1)
per2=Person(2)
print(per1+per2)