Python 之面向对象
0X00 创建一个类
Python也是一个和C++、Java一样的面向对象编程语言,所以Python里也有类和对象。
1class Person: #这是一个类
2 def sayHello(self): #这是一个方法
3 print 'hello,world'
4
5 def setName(self, inputName):
6 self.name = inputName
7
8 def getName(self):
9 return self.getName()在类中创建的方法使用def关键字定义,每个方法有一个或以上的参数,selft就是实例化的对象自己。需要返回值就return一个,不需要就可以不写return
Python的类和Java的类还是有点区别,Java的类里主要写的是属性和方法,Python里不写属性,因为Java的变量需要定义而Python的变量并不需要定义,最多也就是在前面个各个属性一个变量名并赋初值
0X01 实例化一个对象
类是一个很抽象的概念,可以由类实例化好多个对象出来。Java中我们习惯说成 new一个对象,而Python中并不需要new
1xiaoming = Person() #实例化了一个类
2xiaoming.setName('xiaoming') #调用一个方法
3print xiaoming.getName()
4xiaoming.sayHello()此段代码接着上面的类声明
0X02 Python的私有
Java和其他好多面向对象编程语言中会有一个private关键字,将属性和方法约束为私有的。然而Python并不能直接支持private,间接地支持也不是真正的private。在Python中的private由一种诡异的方式模拟,在方法前加上连续的两个下划线
1class Person:
2 def __hello(self):
3 return 'hello,world'
4
5 def sayHello(self):
6 print self.__hello()
7
8xiaoming = Person()
9xiaoming.sayHello()
10xiaoming.__hello()运行起来就是这样的,前面的xiaoming.sayHello()因为是可以直接调用的,然后在方法里调用了私有的__hello()方法,所以可以正常执行;后面的xiaoming.__hello()因为不能直接调用,所以报错了。
1hello,world
2Traceback (most recent call last):
3 File "./hello.py", line 12, in <module>
4 xiaoming.__hello()
5AttributeError: Person instance has no attribute '__hello'其实在方法前面加了两个下划线并没有真的把方法改了个名字而已,改成了_Class__name的类型,一个下划线+类名+两个下划线+方法名,当我们知道了这个问题之后就可以这样调用‘私有’方法了,但是既然我们都将其设为了’私有’就不要这么用了。
1>>> xiaoming = Person()
2>>> print xiaoming._Person__hello() #不要这样做,虽然可行
3 hello,world0X03 继承
面向对象编程的特性之一:继承。Python中的继承和Java的语法差异还是挺大的,像下面这样可以声明两个类,让 一个类继承自另一个
1#!/usr/bin/python
2
3class Person:
4
5 def sayHello(self):
6 print "hello, I'm person"
7
8class Jack:
9
10 def sayHello(self):
11 print "helo, I'm Jack"
12
13person = Person()
14jack = Jack()
15
16person.sayHello()
17jack.sayHello()输出是这样的
1hello, I'm person
2helo, I'm Jack这也体现了面向对象的覆盖的思想
0X04 多继承
一个类可以继承自另一个类,也可以继承自其他好多个类。
1class Student: #一个父类
2 def learn(self):
3 print "i'can learn"
4
5
6class Coder: #另一个父类
7 def programming(self):
8 print "I'can programming"
9
10class Jack(Student, Coder): #继承自两个雷的子类
11 pass
12
13jack = Jack()
14
15#可以调用两个父类中的方法
16jack.learn()
17jack.programming()书写多继承的时候要注意一个问题,如果某类继承自两个类,且那两个类有相同的方法,那么就会造成覆盖(重写) 是这样一个情况,如果我上面的Student和Coder类都有一个名为eat的方法,但是Student类里的eat方法是输出‘student can eat’但是‘Coder’类中eat方法是输出’coder can eat’,那么在写子类的时候就要格外小心 如果子类这样写
class Jack(Student, Coder)那么这个子类的ear方法就会是’Coder‘’中的方法,输出‘Coder can eat’,如果这样写class Jack(Coder, Student)的话,输出就是’Student can eat‘’
0X05 构造方法
我们实例化一个对象的时候是这样做的xiaoming = Person()其内部是调用了Person类的构造方法并返回给了xiaoming这个变量。在Java中在java中构造方法是一个没有返回类型的与类名同名的方法,但是在Python中所有构造方法都叫__init__()。自己不手动写构造方法的话Python就会自动生成一个,这点和Java相同。当然我们也可以自己手写构造方法
1class Person:
2 def __init__(self):
3 print 'new a person'
4
5xiaoming = Person()会输出一个new a person 这就能证明确实在实例化对象的时候回先调用这个类的构造方法。构造方法可以加参数,就像下面这样
1class Person:
2 def __init__(self, say='new a person'):
3 print say如果我实例化对象的时候这么写xiaoming = Person()那么就会输出一个’new a person’的字符串,因为我没传入参数,所以就使用了默认值,但是如果我这样实例化对象xiaohong = Person('xiaohong')就会输出一个’xiaohong’的字符串,因为我给构造方法传入参数了。
在Python中还有一个叫析构方法的__del__但是我们最好不要去碰它,因为Python里有像Java类似的自动垃圾回收,所以几乎不会需要我们自己去析构一个对象,但是如果真的有需要,也可以像C++一样手动析构
0X06 方法的重写
如果有一个类A,A中有一个sayHello的方法,然后有一个B类继承了A类,那么自然就也有了sayHello的方法,但是如果我们给B类单独设定sayHello方法会怎么样呢
1class Person:
2 def sayHello(self):
3 print "i'm Person"
4
5class Man(Person):
6 def sayHello(self):
7 print "i'm Man"
8
9xiaoming = Man()
10xiaoming.sayHello()输出的是”i’m Man”而不是”i’m Person”。这就是方法的重写,子类中写了一个和父类中相同名的方法,就会把已经继承过来的方法重写掉
如果这篇文章对你有帮助,可以请我喝杯咖啡 ☕
评论