目录

  • 一.面向对象简介
  • 二.类
  • 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__: 乘方