Java转Python之面向对象编程

来源:互联网 发布:深圳软件企业认定 编辑:程序博客网 时间:2024/05/22 00:29

1 class的编写与语法

 class中所有函数的第一个入参必须是self命名的,相当于Javathis,只不过Java类中的方法没有显式的将this放入入参内,而python中却将self显示的声明在函数的入参里,当然函数真正被调用时self这个变量是不需要传入的。SelfPython中约定俗成的参数名名,可以换成别的命名。

 class的构造器一定要是__init__命名的,这一点与java差别很大,Java是自己的类名。

 Pythonclass中的成员变量是__init__构造的时候指定并赋值的,这一点与Java的差异是巨大的,在Java中成员变量是提前声明好的。

 __init__对应的销毁函数是__del__函数,对象被销毁时调用。

 

2实例的创建没有new关键字,直接通过类名的方式来创建对象:

        entityName= ClassName(param1,param2,……)

 

3实例成员变量和函数的访问与java一样,对象名加“.”的方式。实例创建后可以随时添加和删除成员变量,与JS语法一样,这个是与强对象类型Java语言天壤之别的差距,Java刚转Python感觉很不理解,这算哪门子的面向对象,这明明是面向过程的。可能pythonclass更多的定义的是能力,是函数功能,对于成员变量是弱化的,与Javainterface更贴近一些。

        getattr(obj,name[, default]) : 访问对象的属性。

hasattr(obj,name):检查是否存在一个属性。

setattr(obj,name,value):设置一个属性。如果属性不存在,会创建一个新属性。

delattr(obj,name) :删除属性。

 

4内置类属性,通过所有class可以通过这些内置类获取class的相关信息

__dict__:类的属性

        __doc__:类的文档(class声明的第一行)

        __name__:类名

        __module__:类所在的模块

        __bases__:类的所有父类

 

结合1234给出的例子:

class User:    'This is user class'    count=0    def __init__(self,name,age):        self.name=name        self.age=age        User.count+=1    def showMe(self):        print("Name: %s age: %s No. %d" %(self.name,self.age,self.count))    def __del__(self):        User.count -= 1        print("%s die: " % self.name)zhangsan = User('zhangsan',21)zhangsan.showMe()lisi = User('lisi',32)lisi.showMe()print(zhangsan.count)zhangsan.wife='瑛姑'lisi.children=['小明','小美']print(zhangsan.wife)print(lisi.children)#内置类print(User.__doc__)del zhangsan.wife#print(zhangsan.wife)

执行结果:

Name: zhangsan age: 21 No. 1Name: lisi age: 32 No. 22瑛姑['小明', '小美']This is user classzhangsan die: lisi die: 

如果将最后一行放开会报错,因为成员变量已经被删除了!


5 Python也是自动GC的,虽然表面上跟JVMGC效果一样,但是实现机制却完全不一样。JVMGC是寻根,有没有被栈中指针或者句柄使用决定是否被回收;Python是引用计数设计,罗列了一些需要排查的场景,例如循环垃圾收集。

 

6 Python既然号称是OO的那么它也支持继承来解决代码的重用性,继承的语法是

        class subClassName(parentClassA,parentClassB,…):

        没错,语法中发现是多继承,也可以思考下这种继承方式下如果在父类中有重复的函数怎么办?经过实测是以class声明时继承类括号中的先后顺序决定的,左边优先级大于右边。这一点做为Java开发人员就感觉很别扭,都是父亲,根据顺序还有亲爹、养父、干爹之分……同理多继承时子类代码在调用父类函数时也要指定父类名称,这也是多继承带来的强制性要求。

        多继承带来的另一个分歧来了,左边的爷爷有的函数和右边的爹有的函数,哪个优先级更高?只能通过代码来亲测下:

        例子:

class A:   def foo(self):      print('called A.foo()')class B(A):   def foo(self):      print('called B.foo()')class C(A):   def foo(self):      print('called C.foo()')class D(B, C):   passd = D()d.foo()

D继承的括号中BC的顺序交换下执行试试,将Class Bfoo方法去掉后再试试,从结果看得出Python的继承顺序是先按辈分再按左右顺序的。

        其他方面与Java一样,例如相同函数名先匹配子类再匹配父类;子类重写父类函数等


 

7Java所有对象都继承自Object一样,我们也可以理解为python的类也隐形的继承了一个object超类,从那个超类中继承下来了这些函数:

        __init__( self [,args...] ) 构造器

        __del__(self ) 销毁函数

        __str__(self ) 相当于Java中的toString

        __cmp__(self, x )比较函数

        __add__(self, other ) 加法运算函数

 

8类函数的修饰及范围。

 Java中的方法分为privateprotected、默认、public四种开放级别,python对函数也有范围限定,只不过不是通过修饰符来定义的,是通过函数命名规范来定义的。

 __function__左右各两个下划线包围起来的函数名,是系统级别的函数,例如__init__

 __function:两个下划线开头的函数名,相当于Java中的private

 _function:一个下划线开头的函数名,相当于Java中的protected

 function:默认的没有修饰符的是public

结合5678给出的例子:

class People :    def __init__(self,name):        print('This is people init')        self.name=name    def __del__(self):        print('%s die' %self.name)    def _protectedFunction(self):        print('This function is protected')    '''    def __str__(self):        return self.name    '''#工人class Worker(People) :    'This is Worker class'    def __init__(self,name,job,salary):        print('This is mother init function')        People.__init__(self,name)        self.job=job        self.salary=salary    def doJob(self,someBody):        print('Do job for somebody %s for %d salary' %(someBody,self.salary))    def __add__(self, other):        return Worker(self.name+other.name,self.job+other.job,self.salary+other.salary)    def __privateFunction(self):        People._protectedFunction(self)    def publicFunction(self):        People._protectedFunction(self)#家长class Parent(People) :    'This is Parent class'    def __init__(self,name,children):        print('This is Parent init function')        People.__init__(self, name)        self.children=children    def teach(self):        print('teach children %s' %self.children)class WorkingParent(Worker,Parent) :    'This is WorkingParent class'    def __init__(self,name,job,salary,children):        print('This is WorkingParent init function')        Worker.__init__(self, name,job,salary)        self.children = children    def think(self):        print('How to balance job and children?')children=['小明','小华']zhangsan = WorkingParent('zhangsan','pastor',1000,children)zhangsan.think()zhangsan.teach()zhangsan.doJob('king')lisi = Worker('lisi','student',100)newOne = lisi+zhangsannewOne.doJob('newJob')newOne.publicFunction()print(newOne)

执行结果

This is WorkingParent init functionThis is mother init functionThis is people initHow to balance job and children?teach children ['小明', '小华']Do job for somebody king for 1000 salaryThis is mother init functionThis is people initThis is mother init functionThis is people initDo job for somebody newJob for 1100 salaryThis function is protected<__main__.Worker object at 0x000001AB16D0B128>zhangsan dielisi dielisizhangsan die

People中的__str__注解放看,可以看到最终打印对象时发生了变化,相当于重写了Java中的toString()方法。

可以在主程序中尝试调用__privateFunction()方法,会抛异常方法不存在。

还可以将People中的_protectedFunction()方法替换成双下划线的试下


总结:PythonOOJavaOO跨度不大,最大的区别就是多继承会带来一些变化,但是只要理解了继承的顺序使用多集成时需要注意的地方也很清晰。






原创粉丝点击