三、python面向对象

2018-09-25  本文已影响0人  井上皓

1.面向对象基础


类和对象(类和实例)

其实python面向对象的概念和c++、java等高级语言没什么区别,只是语法有区别而已。

我暂且简述一下类和对象( 类和实例 )的概念。

简单来说类是实例的抽象!

类相当于字符串、变量、数组一样是一个单独的数据类型,但是又有自己独到之处。

而一个数据类型的单独拥有变量名的一个变量就相当于这个类的实例。

以足球这项运动来举例:

类里显示的一些变量和字符,相当于告诉你组成足球队的基本人员有什么,比如球队的基本队员和教练、后勤等。类里的一些方法就相当于足球的各种规则(包括如何选择球员和教练、怎么踢足球、具体游戏规则等)。

但是类只是一个结构,他像一个说明书,告诉了你足球这项运动的人员组成和玩法。但是知道了说明书却不代表你拥有了一个球队,你必须按照说明书自己组建一个球队并且按照说明书的要求去玩才行。即当你创建完足球队的时候,也就是你实现了一个实例的时候。

a.创建和封装 


 创建

创建类和其实例

(   )中的是继承的父类,如果没有合适的继承类,就使用object类,因为这是所有类的源头(所有的类都最终继承于它)。

可见,变量s指向一个Student类的实例,s的内容是一个内存地址。

现在我们以下的例子来在说明:如何在说明书中设定人员的组成。

__init__方法

首先第一个参数self表示创建的实例本身,其次__init__方法在创建实例的时候不能传入空的参数了,并且要与要求的参数匹配。

创建实例的时候传入参数 结果

和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。

封装 

即在类的内部定义的方法来调用自身变量和方法就是封装

封装 结果

b.访问限制


在原理上与其他高级语言一致

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__就变成了私有变量(private),只有内部可以访问,外部不能访问。

访问限制 无法从外部访问私有变量

如果此时想改变变量可以从访问内部方法来改变或者访问私有变量

访问内部方法来访问私有变量 访问内部方法 结果

注意:变量名类似__xxx__的是特殊变量,不是私有变量。

有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。

最后注意下面的这种错误写法

错误写法

表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。

c.继承和多态


这里涉及了子类和父类的关系

这种关系你可以看成:哺乳动物这个概念和狗还有猫这两个概念的关系。哺乳动物属于父类,狗和猫属于子类。

子类继承父类的全部功能下,可以拥有自己的特性。这相当于猫和狗都继承了哺乳动物的特征并且又有自己独特的地方。

这里还要注意一点,可以把子类当成一个父类看但是不能把父类当成子类看。同样,你可以说狗都是哺乳动物,但不能说哺乳动物都是狗!

继承

即子类通过继承父类获得了父类的全部功能。

继承 结果

我们看到即使Cat类里什么都没有,但是仍然能调用父类的内容。

多态

即当子类和父类都存在相同方法时,子类的方法覆盖了父类的方法,在代码运行的时候,总是会调用子类的方法。

多态 结果

多态的好处就是,当我们需要传入Dog、Cat时,我们只需要接收Animal类型就可以了,因为Dog、Cat都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思:

对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog还是Cat对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:

对扩展开放:允许新增Animal子类;

对修改封闭:不需要修改依赖Animal类型的run_animal()等函数。

继承可以不断的继承!

继承

动态语言

静态语言对继承要求严格在必须只能是子类或者父类可以调用父类功能!

Python这样的动态语言只需要保证传入的对象有一个run()方法就可以了

动态语言 结果

d.获取对象信息


type()

使用type()返回对应的Class类型或者是一个变量指向函数或者是基本类型。

type() 结果

isinstance()

要判断class的类型最好使用isinstance()函数。

isinstance() 结果

dir()

获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:

上一篇下一篇

猜你喜欢

热点阅读