说明
本次问们将学习面向对象部分的知识,我们需要掌握以下几点:
1.了解面向对象编程思想,掌握类和对象的定义和使用
2.熟悉self的使用技巧,掌握构造方法的使用。
3.了解如何使用封装保护属性,掌握单继承和多继承的使用
4.掌握类属性和实例属性的使用,熟悉类方法和静态方法的使用技巧
如果要完全掌握,就需要不断练习,最好是找一个小项目,例如使用类写一个简单的学生信息管理系统,再难一点就是写一个简易的poker游戏,在上一层可以写一个游戏,例如贪吃蛇
类的创建
在程序中使用对象来映射现实中的事物,使用对象间的关系来描述事物之间的联系,这种思想就是面向对象。面向对象编程有两个非常重要的概念:类和对象。对象是面向对象编程的核心。具有相似特征和行为的事物的集合统称为类,对象是根据类创建的,一个类可以对应多个对象。类是由3部分组成的:(1)类的名称:类名,首字母必须大写,比如Person;(2)类的属性:一组数据,比如性别;(3)类的方法:允许进行操作的方法,比如说话。使用class关键字来声明一个类,基本格式如下:
class 类名:
类的属性
类的方法
class Person:
def __init__(self,name):
self.name=name
def __str__(self):
return "我的名字是"+self.name
def get_name(self):
return self.name
类的使用
根据类创建对象的语法格式如下:
对象名 = 类名()
person=Person("小明")
要想给对象添加属性,可以通过如下方式:
对象名.新的属性名 = 值
person.name="小红"#会覆盖之前的值
构造方法
init
构造方法指的是__init__方法。当创建类的实例的时候,系统会自动调用构造方法,从而实现对类进行初始化的操作。
class Animal:
def __init__(self,color):
self.color=color
del
当删除一个对象来释放类所占用资源的时候,Python解释器默认会调用另外一个方法,这个方法就是__del__( )方法。__del__方法被称为析构方法。
class Person:
def __del__(self):
print("——del--")
person=Person()
del person
print("——end--")
在方法的列表中,第1个参数永远都是self。self的字面意思是自己,我们可以把它当做C++里面的this指针理解,表示的是对象自身。当某个对象调用方法的时候,Python解释器会把这个对象作为第1个参数传给self,开发者只需要传递后面的参数就可以了。
class student:
def __init__(self,name,age,scoure):
self.name=name
self.age=age
self.scoure=scoure
运算符重载
运算符重载是通过实现特定的方法使类的实例对象支持Python的各种内置操作。例如:+运算符是类里提供的__add__这个函数,当调用+实现加法运算的时候,实际上是调用了__add__方法。加法运算是通过调用__add__方法完成重载的,当两个实例对象执行加法运算时,自动调用__add__方法。跟索引相关的重载方法包括如下3个:getitem:索引、分片;setitem:索引赋值;delitem:索引和分片删除。在对实例对象执行索引、分片或者for迭代操作时,会自动调用__getitem__方法;通过赋值语句给索引或者分片赋值时,调用__ setitem __方法实现对序列对象的修改;当调用del方法时,实质上会调用__delitem__方法实现删除操作。
方法 | 说明 | 何时调用 |
---|---|---|
_ _ add _ _ | 加法运算 | 对象加法:x+y,x+=y |
_ _ sub _ _ | 减法运算 | 对象减法:x-y,x-=y |
_ _ mul _ _ | 乘法运算 | 对象乘法:xy,x =y |
_ _ diy _ _ | 除法运算 | 对象除法:x/y,x/=y |
_ _ getitem _ _ | 索引,分片 | x[i]、x[i:j]、没有__iter__的for循环等 |
_ _ setitem _ _ | 索引赋值 | x[i]=值、x[i:j]=序列对象 |
_ _ delitem _ _ | 索引和分片删除 | del x[i]、del x[i:j] |
保护类里面的属性
私有属性
为了保护类里面的属性,可以采用如下方式解决:
把属性定义为私有属性,即在属性名的前面加上两个下划线;
class cars:
__names=[]
__ids=[]
def __init__(self, name,ID):
self.__names.append(name)
self.__ids.append(ID)
def get_names(self):
return self.__names
def get_ids(self):
return self.__ids
cars=cars("biyadi","001")
print(cars.get_names(),"\n",cars.get_ids())
封装
添加用于设置或获取属性值的两个方法供外界调用。此即为封装。在程序中,继承描述的是事物之间的所属关系。
class feng_zhuang:
def __init__(self,name,age):
self.name=name
self.age=age
def get_name(self):
return self.name
def get_age(self):
return self.age
fg=feng_zhuang("小刘",21)
print(fg.name,fg.age)
def get_name():
return fg.get_name()
def get_age():
return fg.get_age()
print(f"{get_name()}\n{get_age()}")
继承
类的继承是指在一个现有类的基础上构建一个新的类,构建出来的新类被称作子类。Python程序中,继承使用如下语法格式标注:
class 子类名(父类名):
class cars:
def __init__(self, name,ID):
self.name=name
self.ID=ID
class biyadi(cars):
def __init__(self,color,name,ID):
cars.__init__(self, name,ID)
self.color=color
def get(self):
return f"颜色:{self.color}\n名称:{self.name}\nID:{self.ID}"
cars=biyadi("red","biyadi","001")
print(cars.get())
多态
Python支持多继承,多继承就是子类拥有多个父类,并且具有它们共同的特征,即子类继承了父类的方法和属性。多继承可以看做是单继承的扩展,语法格式如下:
class 子类名(父类1,父类2…):
如果子类继承的多个父类间是平行的关系,子类先继承的哪个类就会调用哪个类的方法。
class cars:
def __init__(self, name):
self.name=name
def get_name(self):
print("cars",self.name)
class car:
def __init__(self,name):
self.name=name
def get_name(self):
print("car",self.name)
class biyadi(cars,car):
def __init__(self, color, name):
super().__init__(name)
self.color=color
cars=biyadi("red","biyadi")
cars.get_name()
调换一下顺序后
在继承关系中,子类会自动拥有父类定义的方法,但是有时子类想要按照自己的方式实现方法,即对父类中继承来的方法进行重写,使得子类中的方法覆盖掉跟父类同名的方法。需要注意的是,在子类中重写的方法要和父类被重写的方法具有相同的方法名和参数列表。
class cars:
def __init__(self, name):
self.name=name
def get_name(self):
print("cars",self.name)
class biyadi(cars):
def __init__(self, color, name):
super().__init__(name)
self.color=color
def get_name(self):#此处为重写
print("after super:",self.name)
cars=biyadi("red","biyadi")
cars.get_name()
类属性
在Python中,多态指在不考虑对象类型的情况下使用对象,它不关注对象的类型,而是关注对象具有的行为。
类属性是类所拥有的属性,它需要在类中进行显示地定义(位于类内部,方法的外面),它被所有类的实例对象所共有,在内存中只存在一个副本。通过“实例.属性”添加属性的属性都是实例属性。
@classmethod
使用修饰器@classmethod来标识类方法。要想调用类方法,既可以通过对象名调用类方法,又可以通过类名调用类方法,这两种方法没有任何区别。
class 类名:
@classmethod
def 类方法名(cls):
方法体
class cars:
@classmethod
def get_name(cls,a,b):
print("classmethod",a+b)
cars.get_name(1,2)#直接调用类.方法
----------------------------------
#a=cars()#这两种方法都是等效的
#a.get_name(1,2)
@staticmethod
使用修饰器@staticmethod来标识静态方法。
class 类名:
@staticmethod
def 静态方法名():
方法体
class cars:
@staticmethod
def get_name(a,b):
print("classmethod",a+b)
cars.get_name(1,2)
-----------------------------------
#a=cars()#这两种方法都是等效的
#a.get_name(1,2)
静态方法是没有self参数,在静态方法中无法访问实例变量;静态方法中不可以直接访问类属性,但是可以通过类名引用类属性;静态方法跟定义它的类没有直接关系,只是起到了类似函数的作用。
写于 2021.01.24 16:39