面向对象全称 Object Oriented Programming 简称OOP,是一种编程思想。是把对象作为一个程序的基本单元,把数据和功能封装在里面,能够实现很好的复用性,灵活性和扩展性。
基本概念:
面向对象是一种抽象,有两个基本概念:类和对象。
类是定义一件事物的抽象特点,而对象是类的一个实例。
例子:例如程序员是一个类,而具体的一个人,比如我就是一个对象。
基本要素:
属性和方法。以程序员为例。程序员具体下面属性和功能:
属性:年龄,性别和身高。
功能(方法):写代码,修电脑。
继承:
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
多态:
用一个类继承几个不同的类,调用同一方法的时候,会有不同的反应。
实战一、定义类:
class ClassName:
statement1
...
statement2
构造函数
def init(self,[...):
析构函数,在销毁一个对象时使用的,当调用python垃圾回收的时候,才会调用。
def del(self,[..):
两个内建函数:
dir()返回一个对象的属性
type() 返回一个对象的类型
实战二、定义类的属性
1、直接在类里定义
类的对象会被所有类的对象所共享,所有类的属性都一样。
class Programer(object):
sex = 'male'
2、在构造函数里定义
class Programer(object):
def __init__(self,name,age):
self.name = name
self.age = age
python的类没有访问权限的问题,也就是说所有的变量都是可访问的。实际上python有私有的机制,就是在属性前加__,但是这种私有机制实际上也是伪私有,因为它其实是用一个别名来保存这个属性。例如在类A中的self.__a = 4, 实际上__a被修改成了_A__a保持在类中了。
3、常用属性定义
class Programer(object):
def __init__(self,name,age,weight):
self.name = name # 可以公开访问
self._age = age # 类的私有属性,但仍然可以访问
self.__weight = weight # 实现了部分私有属性
class Programer(object):
hobby = 'Play Computer'
def __init__(self, name,age,weight):
self.name = name
self._age = age
self.__weight = weight
def get_weight(self):
return self.__weight
if __name__ == '__main__':
programer = Programer('Albert',25,80) # 将对象实例化
print(dir(programer)) # 打印所有属性
print(programer.__dict__) # 从构造函数里获得的属性
print(programer.get_weight()) # 获取weiht 属性的方法
print(programer._Programer__weight) #
print(programer.name)
运行结果:
['_Programer__weight', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', 'get_weight', 'hobby', 'name']
{'_age': 25, '_Programer__weight': 80, 'name': 'Albert'}
80
80
Albert
实战三、定义类的方法
函数和方法介绍:
函数:是直接调用函数名调用的。
方法:必须是类的一部分,由别的程序来调用的。
@classmethod
调用的时候用类名,而不是某个对象。
@property
像访问属性一样调用方法。
class Programer(object):
hobby = 'Play Computer'
def __init__(self, name,age,weight):
self.name = name
self._age = age
self.__weight = weight
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_weight(self):
return self.__weight
def self_introduction(self):
print(('My Name is %s\nI am %s years old\n') % (self.name,self._age))
if __name__ == '__main__':
programer = Programer('Albert',25,80)
print(dir(programer))
print(Programer.get_hobby()) # 类方法调用的函数
print(programer.get_weight) # 已属性的方式调用的函数
programer.self_introduction()
运行结果:
['_Programer__weight', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', 'get_hobby', 'get_weight', 'hobby', 'name', 'self_introduction']
Play Computer
80
My Name is Albert
I am 25 years old
实战四、类的继承
继承的子类:
1、会继承父类的属性和方法;
2、也可以自己定义,覆盖父类的属性和方法
用super()调用父类的方法:
class A(object):
def method(self,arg):
pass
class B(A):
def method(self,arg):
super(B,self).method(arg)
用类名调用父类的方法:
class A(object):
def method(self,arg):
pass
class B(A):
def method(self,arg):
A.method(arg)
子类的类型判断:
isinstance # 判断类型
issubclass # 判断是否是子类
class Programer(object):
hobby = 'Play Computer'
def __init__(self, name,age,weight):
self.name = name
self._age = age
self.__weight = weight
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_weight(self):
return self.__weight
def self_introduction(self):
print(('My Name is %s\nI am %s years old\n') % (self.name,self._age))
class BackendProgramer(Programer):
def __init__(self,name,age,weight,language):
super(BackendProgramer,self).__init__(name,age,weight)
self.language = language # 定义language这个属性
if __name__ == '__main__':
programer = BackendProgramer('Albert',25,80,'Python')
print(dir(programer))
print(programer.__dict__)
print(type(programer))
print(isinstance(programer,Programer)) # 判断是否是Programer这个类
运行结果:
['_Programer__weight', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', 'get_hobby', 'get_weight', 'hobby', 'language', 'name', 'self_introduction']
{'_Programer__weight': 80, '_age': 25, 'language': 'Python', 'name': 'Albert'}
<class '__main__.BackendProgramer'>
True
实战五、类的多态
多态的要素:继承和方法重写
class Programer(object):
hobby = 'Play Computer'
def __init__(self, name,age,weight):
self.name = name
self._age = age
self.__weight = weight
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_weight(self):
return self.__weight
def self_introduction(self):
print(('My Name is %s\nI am %s years old\n') % (self.name,self._age))
class BackendProgramer(Programer):
def __init__(self,name,age,weight,language):
super(BackendProgramer,self).__init__(name,age,weight)
self.language = language
# 重写父类的 self_introduction方法
def self_introduction(self):
print(('My Name is %s\nMy favorite language is %s\n') % (self.name,self.language))
# 判断传进来的参数是否属于Programer对象,如果是,直接调用对象的self_introduction()方法
def introduce(programer):
if isinstance(programer,Programer):
programer.self_introduction()
if __name__ == '__main__':
# 将对象实例化
programer = Programer('Albert',25,80)
backend_programer = BackendProgramer('Tim',30,70,'Python')
introduce(programer)
introduce(backend_programer)
运行结果:
My Name is Albert
I am 25 years old
My Name is Tim
My favorite language is Python
多态优点:
添加功能比较简单,只要判断是否属于这个父类,而不需要判断传进来的是哪个子类,直击调用这个方法。