十 四、python基础:初识面向对象

一:初识面向对象

1、面向对象(object-oriented ;简称: OO) 至今还没有统一的概念 我这里把它定义为: 按人们认识客观世界的系统思维方式,采用基于对象(实体) 的概念建立模型,模拟客观世界分析、设计、实现软件的办法。

面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法,这种方法把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。

面向对象的三大特征:继承、多态、封装

2、

二:类和对象

1、在python中,若用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是"类",对象则是这一类事物中的具体一个

创建一个类就会创建一个类的名称空间,用来储存类中定义的所有名字,这些名字称为类的属性

类属性有两种:静态属性(直接在类中定义的属性)和动态属性(定义在类中的方法),其中类的数据属性是共享给所有对象的,而类的动态属性是绑定到所有对象的

2、使用关键字 class 创建类         格式为     class  类名:

3、类有两种作用:属性引用和实例化

①属性引用:   类名.属性    (类可以通过这种方法访问类属性(也叫类变量),但是类不能访问对象属性(也叫实例属性或实例变量))

②实例化:类名加括号就是实例化,会自动触发__init__方法(函数)的运行,可以用它来为每个实例定制自己的特征

实例化的过程就是类——>对象的过程,原本只有一个Person类,在这个过程中,产生了egg对象,并通过__init__接收参数

语法:   对象名 = 类名(参数)

对象名.属性            调用属性(对象可以通过这种方法调用对象属性和类属性,这里需要注意的是实例对象只能够调用类属性,却不能修改类属性,只有类才有资格修改类属性)

对象名.属性 = XXX     为对象添加或修改实例属性

del   对象名.属性         删除实例属性,不会影响类属性

对象名.方法( )         调用方法

__init__(self ) 是一种特殊方法,被称为类的构造函数或初始化方法,当创建一个类的实例时就会自动调用这个方法

__str__(self )       print(实例) 时,打印出__str__( ) 函数返回的数据,即 return 后面的参数

__del__(self )     程序结束时,如果还有引用,结束的最后会自动调用该函数,当引用数为0时,会立即执行该函数      

4、self

类的方法与普通函数只有一个特别的区别——他们必须要有一个额外的第一个参数名称 self(不是关键字)

self 代表类的实例,代表当前对象的地址, 必须放在第一位且不需要传参

5、对象:对象是关于类而实际存在的一个例子,即实例,通过:    对象名 = 类名(参数)    ,来创建一个对象

与类相似,创建一个对象就会创建一个对象的名称空间,存放对象的名字,称为对象的属性(实例属性)

对象(实例)只有一种作用——属性引用(方法也是属性,是一个类似于函数的属性,称为动态属性)

实例.方法    是引用方法 ,      实例.方法( )   才是调用方法 ,两者之间有本质区别

三:类属性(类变量)与实例属性(对象属性、实例变量)

为了能更好的理解类属性与实例属性,创建类Peopel,以及实例化 student1 和 student2

1、类属性与实例属性的区别:

类只能引用类属性,不能引用实例属性, 实例可以引用类属性与实例属性

结果如下:

2、类属性和实例属性在使用上的区别:

我们发现在进行运算前,这三个引用的都是类属性money

所以他们的属性money的内存地址都是相同的

下面进行如下运算:

我们发现 student1 引用的 money 属性的内存地址已经与另外两个不同了,且另外两个的内存地址是一样的

原因:student1.money -= 1000,是对实例属性的修改,在第一次修改 money 这个实例属性时,会先在实例中查找是否有 money 这个实例属性,如果有的话,直接对这个实例属性进行运算;如果没有的话,则会去类中查找是否有 money 这个类属性,如果在类中找到money类属性,那么 student1 就会创建一个实例属性 money ,在之后调用的时候就会调用自己的实例属性,而不是类People 中的类属性了,而 student2 因为没有修改实例属性,所以没有创建自己的实例属性 money ,而是引用了类People 的money这个类属性,所以 student2 和People 引用的是同一个类属性,于是他们指向的内存相同

student2 进行同样的运算后,student2 中也会创建一个 money 实例属性,此时三者的 money 属性的内存地址就都不同了

3、类属性的补充:

四:类方法、实例方法、静态方法

1、类方法在python中使用较少,通常情况下,类方法使用@classmethod装饰器来声明,类方法传入的第一个参数为cls,就像实例方法的 self 一样,但cls 代表类本身

2、类方法可以通过类直接调用,也可以通过该类的实例对象直接调用,但无论是哪种调用方法,传入的第一个参数为类本身,也就是cls

从运行结果可以看出,无论是类调用还是实例调用,类方法均能正常工作,且通过打印 cls ,可以看出传入的都是类本身

3、如果存在类的继承,那类方法获取的类(也就是 cls 获取到的类)是类树上最底层的类

代码中 ClassA 继承自 BaseA 和 BaseB ,在调用类方法时,虽然类方法是从 BaseA 继承而来,但是传入 func_a 的 cls 函数实际上是 ClsaaA ,(也就是说cls现在代表的是 ClsaaA 类,而不是 BaseA 类),也就是最底层(最具体)的类

4、实例方法:除类方法与静态方法,类的其他方法都属于实例方法

实例方法需要将类实例化后,实例名.实例方法( )     来调用,如果使用类直接调用实例方法,需显示地将实例作为参数传入,实例方法最左侧传入的参数为 self ,代表实例本身

5、静态方法:指在类中,无需实例即可调用的方法(也就是说不需要 self 参数),在调用过程中,无需将类实例化就可以调用,通过:     类名.静态方法( )      来调用,通常使用@staticmethod装饰器声明,也可以使用 :     实例名.静态方法( )     来调用

这里需要注意的是,在Python 2 中,如果一个类的方法不需要self参数,必须声明为静态方法,即加上@staticmethod装饰器,从而不带实例调用它

而在Python 3中,如果一个类的方法不需要self参数,不再需要声明为静态方法,但是这样的话只能通过类去调用这个方法,如果使用实例调用这个方法会引发异常

五:私有属性、私有方法

1、如果一个属性是以两个下划线开始,就标识这个属性是一个私有属性,相同的,如果一个方法也是以两个下换线开始,就标识这个方法也是一个私有方法

2、私有属性与私有方法只能在类中使用

3、子类继承父类时,父类的私有属性与私有方法不会被子类继承

4、由于私有属性不能在外面使用,所以可以在一个实例方法中修改私有属性,然后调用这个实例方法,间接修改私有属性

5、同样的,也可以通过调用一个实例方法来间接调用私有方法

6、使用property装饰器修改私有属性

如果是给 t.num 赋值,那么就是调用了 get

如果是获取 t.num 的值,那么就是调用了set

六:继承

1、继承是一种创建新类的方法,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为子类或派生类

2、python中的继承分为单继承和多继承,子类的实例对象可以调用父类属性和方法,子类不会继承父类的私有属性和私有方法

3、当父类的方法功能不能满足需求时,可以在子类中重写父类的方法

4、在子类中调用被重写的父类的方法

①父类名.方法( self )               self 参数必须要带上,如果有其他参数也需要写上去

②super( 子类名,self ) . 方法( 参数 )           (如果要调用的父类的方法中带有除self以外的其他参数,就需要传参)

5、在父类中为不同的子类返回不同的数据信息:

思路:通过在调用父类的方法的时候,传递不同的数据信息,父类接收信息,就可以通过接收到的数据进行不同的逻辑处理

① isinstance( obj,class ) 布尔函数:如果obj 是 class 类的实例对象或是 class 子类的实例对象,则返回True

 

6、多继承时,若父类A和父类B都有一个名字相同的方法,那么通过子类去调用时,会调用最左边的父类的方法,如果子类也重写了这个方法,那么就会调用子类的重写方法

七:动态添加属性和方法

1、动态添加属性

del  实例名.属性        ,可以动态的删除实例属性

2、动态添加方法

虽然p1对象中run属性已经指向了9行的函数,但是这句代码还不正确,因为run属性指向的run函数是后来添加的,但在p1.run()的时候,并没有把p1当做第1个参数,导致了第9行的函数在调用的时候,出现缺少参数的问题

使用 types.MethodType解决:

再给 run 函数定义一个参数speed:

3、__slots__( )函数,限制动态操作时,可操作的实例属性

__slots__( ) 函数限制了可动态操作的属性为 name 和 age ,即此时只能为实例对象动态添加 name实例属性和 age实例属性,无法动态添加其他属性。

__slots__( ) 函数 无法限制在类中添加的属性,也无法限制子类的实例对象,只能限制类实例对象的动态操作

八:__new__( )函数与单例模式

1、实例化一个实例时,第一个自动调用的是__new__( )方法,该方法用于创建,而__init__( )用来初始化,

2、若是__new__( )函数没有正确返回当前 cls 的实例,那么初始化函数也不会被调用

3、return object . __new__( cls )  正确返回当前 cls 的实例

  

4、单例模式:不管实例化多少次,实例对象只有一个

九:初识面向对象小结

猜你喜欢

转载自blog.csdn.net/weixin_42834609/article/details/81347528
今日推荐