Python_面向对象_类1
面向对象:减少重复代码,提高效率,比函数式编程更高效
类的创建:
实例属性又称:成员变量,成员属性(或者字段)
面向对象的三大特性:
一、封装
把客观事物封装为抽象的类,并对外只暴露一个可用接口
使用构造方法将内容封装到对象中,可通过对象直接或者通过self间接获取被封装的内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 创建类
class Foo(object):
def __init__(self, name, age): # 构造方法,根据创建的对象自动执行
self.name = name
self.age = age
# 类中的方法A
def A(self):
Foo.name = 'yeeh'
print('hello!', self.name)
print('hello!', Foo.name)
# 类中的方法B
def B(self):
print('word!',self.age)
obj = Foo('Vera', 18)
obj.age = 12
obj.A()
obj.B()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
hello! Vera
hello! yeeh
word! 12
二、继承
子类拥有父类的全部方法,也可以对父类方法进行重写,并且可以定义自身的方法(一般到特殊,父类定义一些公共的方法,子类可定义自身特殊的方法)
- 注:Python中一个子类可以继承多个父类
对于实例属性要进行 :先重写,再继承
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 父类
class People(object):
number = 0
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
self.drink() # 因为继承,所以调用的时候,都会打印drink ()里的东西
def eat(self):
print('都可以吃东西!')
def drink(self):
People.number += 1
print('[%s].[%s] 的年龄是[%s]' % (People.number, self.name, self.age))
# 子类1
class good_person(People):
def __init__(self, name, age, sex, goodness): # 先重写
super(good_person, self).__init__(name, age, sex) # 再继承
self.goodness = goodness
def good_ness(self):
print('善良的[%s]做好事' % self.name)
# 子类2
class bad_person(People):
def __init__(self, name, age, sex, sourness):
super(bad_person, self).__init__(name, age, sex)
self.sourness = sourness
def bad_ness(self):
print('坏人[%s]做坏事!' % self.name)
g1 = good_person('花花', 23, '女', '做好事') # 实例化后因为父类的继承,所以直接会打印drink()
g1.good_ness()
b1 = bad_person('李刚', 33, '男', '做了坏事')
b1.bad_ness()
b1.eat() # 继承会继承父类的所有方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[1].[花花] 的年龄是[23]
善良的[花花]做好事
[2].[李刚] 的年龄是[33]
坏人[李刚]做坏事!
都可以吃东西!
注:
新式类 继承的写法:super(bad_person,self).__init__(name,age,sex) # 利用关键字super
旧式(经典)类 继承的写法:People.__init__(self,name,age,sex)
有关super()继承:https://www.cnblogs.com/testview/p/4651198.html?utm_source=tuicool&utm_medium=referral
多继承:
- 在3.0里及以后多继承的经典类和新式类都是采用的广度优先原则
- 在3.0以下的版本,经典类和新式类就有深度和广度的区分
经典类:class A: 深度优先:继承了上一级里没有这个方法就直接到上一级的上一级去寻找,找到始祖没有找到,再从继承的上一级寻找再到它的始祖
新式类:class A(object): 广度优先 :继承的上一级,从左到右依次寻找继承的类里有没有那个方法,如果没有才再寻找上一级的上一级所继承的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A(object):
def f1(self):
print('我是 A')
class B(A):
def f2(self):
print('我是 B')
class C(A):
def f3(self):
print('我是 C')
class D(B, C):
def f4(self):
print('我是 D')
d = D()
d.f1() # D->B->C->A
d.f2() # D->B
d.f3() # D->B->C
d.f4() # D
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A:
def f1(self):
print('我是 A')
class B(A):
def f2(self):
print('我是 B')
class C(A):
def f3(self):
print('我是 C')
class D(B, C):
def f4(self):
print('我是 D')
d = D()
d.f1() # D->B->A
d.f2() # D->B
d.f3() # D->B->A->C
d.f4() # D
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
我是 A
我是 B
我是 C
我是 D
三、多态
多态:当子类和父类都存在相同的方法时,子类的 方法 覆盖了父类的方法,在代码运行时,会调用子类的方法(一种调用方式,拥有不同的执行效果),把接口进行统一(外部调用,内部可以直接转换到相应方法下)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Animal(object):
def func(self):
print('这是Animal。。')
class dog(Animal):
def func(self):
print('这是dog。。')
class pig(Animal):
def func(self):
print('这是pig。。')
def run(self):
print('这是pig中的run....')
def print_func(animal):
animal.func()
A = Animal()
d = dog()
p = pig()
print_func(Animal()) # 对外只暴露一个接口,但是可以直接打印多个不同的东西
print_func(dog())
print_func(pig())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
这是Animal。。
这是dog。。
这是pig。。