Python中的面向对象

Python与Java一样是面向对象的语言之一。因此,理解Java中面向对象三大基本特征,对入门Python有很好的帮助。Linux中一切皆文件,Java中一切皆对象,Python同样如此。概念性的东西不讲太多,这里着重讲一些与Java的不同之处。

面向对象不是面向过程,因此首先考虑的是,某个类的实例应该视其为一个对象,该对象拥有若干个属性及方法,属性代表特性,方法代表行为,类代表模板。类和实例的概念,对应抽象和实体。例如学生是一个类,而实例指的是某一个具体的学生,该学生的名字、年龄等特征就是属性,学生可以上学、运动等行为就是方法

 

创建类:

class Student(object):

 pass

创建实例:

obj = Student()

添加属性

obj.name='xiaozhou'

 

封装

由于类起到模板的作用,可在__init__方法中定义需要的参数,后续创建实例时必须带上参数。注意,__init__方法第一个参数永远是self,代表实例本身。创建实例时,__init__方法会自动运行,传参时无需传self,解释器会自动处理

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

 

__init__方法用于创建实例,属于方法的一种。方法是特殊的函数,它与类的关系密切,一般来说,(查询、操作)类内部的数据,都是通过方法来访问的。如此一来,外部在创建实例时只需传入规定的参数,而获取数据通过方法,无需知道内部实现细节

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print('%s: %s' % (self.name, self.score))

注意:Python是动态语言,可以直接对实例对象绑定任意数据。因此,一个类下的不同实例,其属性不一定相同。这点需要与java中区分开

 

如果压根不想让外部访问,可以在属性名的前面加两个下划线 __ ,表示是一个私有变量。

而有些变量名是由 __xxx__组成,前后各两个下划线,是特殊变量,可以直接访问。跟私有变量需要区分。

另一种只由一个下划线开头的 _xxx表示非公开的,外部也是可以访问的,但也最好不要访问。属于约定式的私有变量:尽管可以访问,但最好不要访问。

 

回到私有变量的话题,如果一个变量变成了私有,那么Python解释器就将该变量名改成_Class__xxx,外部想访问需要使用obj._Class__xxx。但这种方式同样不建议使用。第一,不同版本的Python会将私有变量改成不同的变量名,不一定是_Class__xxx。第二,该变量已经是私有变量了,默认就是不能从外部访问了,Python希望调用者自觉一些。

 

继承与多态

继承的双方是继承类与被继承类,即对应的是父类与子类。添加了继承关系后:

首先,如果一个实例的数据类型是子类,那么同时它的数据类型同时也是父类(例如,狗属于动物这个类,但也属于生物这个大类);但如果一个实例的数据类型是父类,那它不会是其子类的数据类型(如人类属于动物这个大类,但不属于宠物这个小类)。

a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型

>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
>>> b = Animal()
>>> isinstance(b, Dog)
False

 

其次,一个子类自动拥有其父类的全部功能(变量、方法),子类也可以自行添加自己独有的功能。如果子类添加的方法与父类方法一致,那么子类的方法会覆盖父类的方法,也就是Java中的重写 orverride。当外部调用时,只要类型是属于父类,即isinstance() 对的上,那么不管传入的是父类还是某个子类,都可以调用到它实际运行时的真实类型。即:外部只管调用,无关细节。

 

另外,Python是多继承的,可以多层继承。

 

这里需要注意的是,Java是静态语言,在调用时就会规定调用的类型,而传入的对象必须是父类及其子类,否则就无法正确调用内部的方法。但Python是动态语言,你传进去的对象不管是不是父类或者子类,只要该方法存在,即可直接调用。并没有严格遵守继承规则

class Timer(object): #Timer继承自object,但拥有run方法,即可直接
    def run(self):
        print('Start...')

 

posted @ 2022-03-20 21:03  我永远喜欢石原里美  阅读(108)  评论(0编辑  收藏  举报