概述
本文的前提是对java的面向对象语法和概念有一个基本的了解,试图从这里去学习理解python的面向对象。
一,用python去实现类
class Animal(object):
kind = 2000
def __init__(self, name):
self.name = name
def run(self):
print('Animal is running...')
上面的语法表示:
- 创建Animal类 继承object类
- __init__是初始化的方法,相当于java中的构造方法
- 添加一个run方法
两点需要注意的地方:
- java中的this改用self代替,并且每个方法都要用self做为第一个参数,但是调用方法的时候可以省略self参数
- name是实例属性,kind是类属性
二,python可以动态的绑定属性和方法
animal = Animal('佩奇')
print(animal.name)
animal.age = 7
print(animal.age)
Output:
佩奇
7
虽然上面的Animal类的定义中,只指出了一个实例属性name,但是可以在创建对象对,直接添加一个age属性进去。这一点对于java这种静态语言是不可能的,如果学过js或者matlab估计会很容易理解吧。
甚至可以添加一个方法
def pao(self):
print('Animal is pao...')
animal.pao = pao #Animal.pao = pao
animal.pao(animal) #animal.pao()
Output:
Animal is pao...
因为python的方法名可以理解成一个指向内存中方法的一个变量,所以原理上添加方法和添加属性是一样的。
如果这里调用的时候不想传参,需要把方法绑定到Animal类上 而不是对象上,如果就像绑定到对象上, 还不想传参,那么可以这样
from types import MethodType
def pao(self):
print('Animal is pao...')
animal.pao = MethodType( pao, animal)
animal.pao()
Output:
Animal is pao...
三,访问权限控制
java中有访问修饰符,private,default,protected,public,每一个修饰符都有明确的可访问范围。
那么python如何进行这种控制?在属性名称前加上__即可,代码如下
class Animal(object):
kind = 2000
def __init__(self, name):
self.__name = name
def run(self):
print('Animal is running...')
animal = Animal('佩奇')
print(animal.__name)
Output:
AttributeError: 'Animal' object has no attribute '__name'
可以看到,再直接访问animal.name就会报错,说Animal类中没有name这个属性
原理非常简单,只是python解释器把__name变成了_Animal__name(不同的编译器会变成不同的名字),所以如果你一定要访问的话,没人拦得住你。
四,python多态和'鸭子类型'
多态的概念就不阐述了,先来看看代码
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('Dog is running')
def AnimalRun(animal):
animal.run()
dog = Dog()
AnimalRun(dog)
Output:
Dog is running
乍一看,这段代码很正常,AnimalRun方法接收一个Animal类的实例,然后就可以调用这个实例的run方法了,也就是和java的多态一样,针对接口或者父类编程即可满足开闭原则。
但是,仔细看就会发现问题,AnimalRun方法的参数你是没办法在函数定义中限制类型的,因为python是动态语言,你传什么参数,它就是什么类型,那么只要这个类型有run方法,代码可以运行。也就是动态语言所谓的'鸭子类型':一个事物,看起来像鸭子,走起来像鸭子,那它就是鸭子。
从这一点去理解动态语言和静态语言在多态上的差异比较好,那么如果想要限制animal只能是Animal类的实例呢? 在代码中做限制即可
def AnimalRun(animal):
if isinstance(animal, Animal):
animal.run()
五,python获取对象的信息
这个事儿如果放在java里,就有一个比较高大上的名字,叫'反射',当然反射还有其他的作用,比如动态创建对象。
python中用 hasattr(), getattr(), setattr() 三个来查询,获取,添加设置属性方法。
animal = Animal('佩奇')
print(hasattr(animal, 'name'))
print(hasattr(animal, 'run'))
print(getattr(animal, 'age', '没有age')) #没有age属性就返回 没有
setattr(animal, 'age', 7)
print(animal.age)
Output:
True
True
没有age
7
还可以用dir()来查询所有的属性方法
print(dir(animal))
Output:
['__class__', '__delattr__', '__dict__', '__dir__', ... , 'age', 'name', 'run']
经过这番对比分析,相信对python面向对象的了解,甚至对动态语言和静态语言面向对象的基本区别应该比较清楚了
最后
以上就是炙热烧鹅为你收集整理的从java面向对象去分析python面向对象一,用python去实现类二,python可以动态的绑定属性和方法三,访问权限控制四,python多态和'鸭子类型'五,python获取对象的信息的全部内容,希望文章能够帮你解决从java面向对象去分析python面向对象一,用python去实现类二,python可以动态的绑定属性和方法三,访问权限控制四,python多态和'鸭子类型'五,python获取对象的信息所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复