一、面向对象概述
1、编程语言的分类
面向机器:
比较底层的、接近机器能理解的编程语言,比如汇编语言,最早接触汇编的时候还是在做一些免杀脱壳和加壳的时候,汇编就是各种指令,非常底层的CPU指令集,所以非常不适合企业级快速的开发。
面向过程:
在处理业务需求的时候,把事情的处理分为各个阶段,按照流程规范进行解决,先解决什么,再解决什么,一步一步的解决然后达到我们的目的,最常见的就是C语言和shell了。这种编程理念比较好理解,就跟人做事一样去解决业务问题。
面向对象:
面向对象的编程思想是相对比较高级的,它借鉴了我们现实世界的当中的理念,对事物的抽象和具体这种概念带进了编程的世界。以一种更加贴近人类的思想去编程,最具代表的就是C++,java,python。它更适合当今这种软件工程发展和快速开发的模式。
2、什么是面向对象
面向对象,重点是对象这两个字,这里的对象就不是男女朋友的对象了,这里的对象指的是从某个抽象的概念实例化出一个具体的东西,感觉这么描述还是有点抽象,但是你要知道的是,对象就是一个具体的,实实在在的东西。
我们针对这个具体的对象去做编程,或者说,我们的编程就是围绕怎么去构建这个对象,比如给这个对象赋予什么属性或者方法,这样就可以实现我们的功能。
类:class,一个虚拟的抽象的概念,和我们现实世界中的类是一个意思,就是具有共同特征的一类事物的集合,比如说人类,鸟类,汽车类等等。一个类中最重要的就是属性和方法,这里的属性就好比如人类中的头发颜色,皮肤颜色等等,而方法就好比如人类的能力,比如会跑,会跳,会搞事等等。
对象:从类实例化而来,是一个具体的概念,一个实实在在的东西,它是一个一个实体,就好比如人类实例化出了张三李四,他们最重要的也是属性和方法,他们的属性和方法都是从类而来,但是张三和李四是两个不同的人,张三可能有自己的头发颜色,李四也有可能自己的头发颜色。
3、面向对象的三要素
封装:在面向对象编程中,最显而易见的特征就是封装,我们在定义一个类的时候,对这个类添加了很多属性和方法,但是我们在调用的时候,一般不会直接去调用类里面的方法或者属性的,而是通过实例化出一个具体对象,通过对象去调用,所以类的第一个作用就是可以把数据和方法封装起来,对外只暴露可以调用的接口。
继承:类的继承和人类血缘关系的继承也是很类似的,祖类的方法继承给了父类,父类就同样拥有这个方法,而不需要再去编写一个一样的方法,所以跟函数一样,也可以实现代码复用的功能,这就是类的第二个作用。
多态:子类继承不同的父类,就会拥有不同的方法和能力
二、Python类的基本概念
1、类的定义
class ClassName: 语句块
说明:
① 定义类的关键字:class
② 类的名字使用大驼峰(单词首字母大写)命名方式
③ 定义一个类之后,就产生了一个类对象,和前面学的函数对象是一样的,而我们的类名就是标识符,指向定义的这个类对象。
示例:
class Connect: name = 'jimmy' def __init__(self, ip): self.ip = ip def ssh_connect(self): pass
2、类的基本概念
类对象:指的是类本身,把整个类看成一个整体,它就是一个对象
类的属性:一般指的是类的变量或者类的方法,还有以双下划线开头和结尾的特殊属性,都叫类的属性
类的变量:比如上面示例中的变量‘name’,它定义在类中,所以是类的变量
类的方法:比如上面示例中的方法‘ssh_connect’,它定义在类中,所以它已经不是普通的函数,它是类的方法,类的方法的第一个参数必然是self(self只是惯例名称,可以使用其他名称),他指的是当前实例本身,因为类的方法是给类的实例调用的,当类的实例调用类的方法时,会自动的把当前实例本身传入这个self当中,我们就可以在这个类的方法中,拿到这个实例进行一些操作。
类的实例:定义一个类之后,肯定是要实例化一个对象的,类是抽象的,对象才的具体的。所以我们一般叫类的实例或者类的对象,都是指具体的某个对象。
3、__init__方法
说明:在类中,以双下划线开头和结尾的方法,一般具体特殊意义,称为魔法方法,后面会详细介绍,这里先介绍第一个最最常用的__init__,它的作用就是每实例化一个对象时,自动调用该方法,所以我们很多初始化操作都会放在init这个方法中实现。
① __init__方法不是必须的,如果没有定义,则不调用,可以正常实例化对象
② __init__方法可以定义多个参数,它也是类的方法,所以第一个参数仍然是self,这个会自动传入,而其他参数就必须在实例化对象的时候传入,和我们的函数调用类似。
③ __init__方法不能有返回值,也就只能是None
#定义一个类,并且定义__init__初始化方法 class Connect: def __init__(self, ip, username, password, timeout=10, try_times=1): self.ip = ip self._username = username self._password = password self._ssh = None self._timeout = timeout self._try_times = try_times self.ssh_connect() def ssh_connect(self): pass
4、实例对象
类定义完成之后,就需要实例化对象,实例化多少个对象看实际需求,一般是一个类,会实例化多个对象,而且每个实例对象都是独立的,有自己的属性,叫做对象属性。
实例化对象:
#根据上面定义的类,实例化多个对象 host1 = Connect('10.10.11.1', 'root', 'root123') host2 = Connect('10.10.11.2', 'root', 'root123') host3 = Connect('10.10.11.3', 'root', 'root123')
实例对象调用类的方法:
#实例调用类的方法 host1.ssh_connect() host2.ssh_connect()
关于self的说明:
我们在定义类的方法的时候,第一个参数都会默认保留给self,而在调用的时候,也不用手动传入参数,这个self指的就是每个实例对象本身,比如这里的host1,host2,host3,当用host1调用ssh_conncet()时,Python会自动的把host1这个实例对象传入第一个参数,也就是self。
实例对象属性:
实例化一个对象后,这个对象就可以拥有自己私有的属性,也叫对象变量,这些属性是绑定到每一个对象上的,比如host1和host2,这里的ip,就是属于每个对象本身的变量,因为在init初始化方法中,我们指定了self.ip,这就是将ip这个变量绑定到对象上了。
>>> print(host1.ip) 10.10.11.1 >>> print(host2.ip) 10.10.11.2
5、实例对象属性的查找顺序
从上面的介绍当中,可以了解到,实例对象有自己的属性,类也有属性,那么当我们需要获取一个属性的时候,应该优先从哪里获取呢?
在这之前,先认识两个特殊属性:
__class__:对象的类型,可以知道对象是哪个类的实例化的,比如host1.__class__就是Connect
__dict__:对象的属性字典,可以知道对象有哪些属性,这个非常有用。
#实例对象的类型 >>> print(host1.__class__) <class '__main__.Connect'> #实例对象的属性 >>> print(host1.__dict__) {'ip': '10.10.11.1', '_username': 'root', '_password': 'root123', '_ssh': None, '_timeout': 10, '_try_times': 1} #类对象的属性 >>> print(Connect.__dict__) {'__module__': '__main__', '__init__': <function Connect.__init__ at 0x7fa888706730>, 'ssh_connect': <function Connect.ssh_connect at 0x7fa888706a60>, '__dict__': <attribute '__dict__' of 'Connect' objects>, '__weakref__': <attribute '__weakref__' of 'Connect' objects>, '__doc__': None}
示例演示:
class Person: #定义两个类的属性 age = 10 height = 170 def __init__(self, name, age=19): #定义两个对象的属性 self.name = name self.age = age #分别实例化两个对象 >>> tom = Person('Tom') >>> jerry = Person('Jerry', 20) #修改类的属性,不影响对象的属性 >>> Person.age, tom.age, jerry.age (10, 19, 20) >>> Person.age = 100 >>> Person.age, tom.age, jerry.age (100, 19, 20) #修改类的属性,对象的属性也变化 >>> Person.height, tom.height, jerry.height (170, 170, 170) >>> Person.height = 200 >>> Person.height, tom.height, jerry.height (200, 200, 200)
实例说明:
① 当类的属性和对象的属性同时存在时,优先使用对象的属性,并且修改类的属性,不会影响对象的属性。
② 当对象没有这个属性时,会去找类的属性,如果有就使用类的属性,这个时候如果修改了类的属性,那么访问的时候,自然也就会随之变化。
6、类和实例对象的总结
① 一定要分清楚类的属性和实例对象的属性。
② 类的属性有变量和方法,而对象的属性只有变量,所以方法都是属于类的。
③ 查看一个对象有哪些属性,可以使用特殊变量__dict__,类对象查看类的属性,实例对象查看实例的属性。
④ 类的属性是所有实例共享的,实例的属性是属于每个实例独有的。
⑤ 属性的访问优先使用实例的,如果没有再找类的。
⑥ 类中的self,它是一个名称符号,指的是每个具体实例对象,通过操作self,可以给每个实例对象绑定属性。