目录
- 一.面向对象简介
- 二.类
- 1.类的定义和实例
- 2.类的属性
- 3.类的初始化
- 4.数据封装
- 5.访问限制
- 6.类的继承
- 7.多态
- 8.类的专有方法
一.面向对象简介
- 面向对象编程——简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
- 高级语言都有面对对象,Python也不例外,比起c++,java这些传统的语言,Python中的面向对象去掉了很多复杂的东西,理解和使用起来更简单一些
- 一般来说面对对象包含:数据封装、继承和多态这三大特点
- 在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
二.类
1.类的定义和实例
- 类其实是一种数据结构,我们可以用它来定义对象,一个类会包含属性和行为特性.类是现实世界抽象的实体以编程形式出现.
- python中类的声明用class关键字来命名。
用class来定义一个类,后面接着是类名Animal,通常类名首字母大写,()里表示这个类是从哪里继承下来的,没有合适的就用object,因为object是所有类的祖宗。
class Animal(object):
pass
如果说类是一种数据结构定义的类型,那么类的实例就是声明这种类型变量
dog 就是Dog类的一个实例
class Dog(Animal):
pass
dog = Dog() #创建实例是通过类名+()实现的
2.类的属性
每个类都会有各自相应的属性,比如人的年龄,姓名,身高等等,在类里面定义的属性,每个实例都是可以共享的。
class Dog(Animal):
name = 'party' #name和age就是Dog的属性
age = 5
dog = Dog()
print('name:%s age:%s' % (dog.name,dog.age))
3.类的初始化
- 在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,age等属性绑上去
- 注意:“ __ init__”前后分别有两个下划线!
- __init__的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
dog = Animal('Luckly',5)
print(dog.name,dog.age)
用了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去
4.数据封装
- 数据封装是面向对象编程的一个重要特点
- Animal实例本身就拥有这些数据,要访问这些数据,就没有必要从外面的函数去访问,可以直接在Animal类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Animal类本身是关联起来的,我们称之为类的方法
- 对类的属性进行封装,可以保证数据的安全,隐藏一些私有属性,降低程序出现问题的风险。
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
def print(self):#在Animal类中定义访问函数,在类外调用函数,这就隐藏了访问属性的细节
print('name:%s,age:%s' %(self.name,self.age))
dog = Animal('Luckly',5)
dog.print()
5.访问限制
- 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量,只有内部可以访问,外部不能访问
class Animal(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
dog = Animal('Luckly',5)
# 不能从外面看到__name属性,也不能通过__name访问
# 但是可以通过_类名__属性名的方法进行访问
print(dog._Animal__name)
如果外部代码要获取name和age怎么办?可以给Animal类增加get_name和get_age的方法
class Animal(object):
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
dog = Animal('Luckly',5)
print(dog.get_name(),dog.get_age())# 在外部用get_name获取name
如果外部代码要修改name和age怎么办?可以给Animal类增加set_name和set_age的方法
class Animal(object):
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
def set_name(self,name):
self.__name = name
def set_age(self,age):
self.__age = age
dog = Animal('Luckly',5)
dog.set_name('happy') # 用set_name修改name
print(dog.get_name(),dog.get_age())
6.类的继承
- 新的class类被称为子类,被继承的类称为父类
- 继承最大的好处是子类获得了父类的全部功能,提高代码的复用性
class Animal(object):
def animal(self):
print('i am a animal')
class Cat(Animal):
def cat(self):
print('i am a cat')
class Dog(Animal):
def dog(self):
print('i am a dog')
dog = Dog()
dog.dog() # i am a dog
dog.animal()# i am a animal 继承了父类Animal的功能
以上代码的Animal就是Dog和Cat的父类,而Dog和Cat就是Animal的子类,所以dog是Dog的实例,不仅能拥有Dog的方法,还能拥有Animal的方法。
当调用实例的属性和方法时,如果子类有一个名字和父类一样的方法,会首先从子类调用,即子类的方法会覆盖父类的方法。
class Animal(object):
def run(self):
print('i am a animal')
class Dog(Animal):
def run(self):
print('i am a dog')
dog = Dog()
dog.run() #i am a dog
python除了单继承,还有多继承,有几个父类就在括号中写几个类名,这就是实现多重继承的方法。如果多个父类中有同名的方法且没有指定使用那个,就会在从左到右依次寻找,找到第一个包含此方法的父类来使用。
class Animal(object):
def run(self):
print('i am a animal')
class Dog(Animal):
def run(self):
print('i am a dog')
class A(Dog,Animal):
pass
a = A()
a.run() # i am a dog 调用了Dog的方法
可以用类名.__bases__来显示类的所属父类
print(A.__bases__) #(<class '__main__.Dog'>, <class '__main__.Animal'>)
7.多态
- 多态就是指一类事物有多种形态(一个抽象类有多个子类,所以多态的概念依赖于继承)
- 多态的好处就是,当我们需要传入更多的子类,例如新增Rabbit,Fish等,我们只需要继承 Animal 类就可以了,子类可以共享Animal的方法,也可以重写一个特有的方法,调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保新方法编写正确,而不用管原来的代码
- 对扩展开放:允许子类重写方法函数
- 对修改封闭:不重写,直接继承父类方法函数
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
class Dog(Animal): #Dog继承Animal
def __init__(self,name,age,sex):
Animal.__init__(self,name,age) #子类对父类构造方法的调用
self.sex = sex
dog = Dog('happy',5,'male')
print(dog.name,dog.age,dog.sex) # happy 5 male
8.类的专有方法
__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方