python基础之面向对象02
Posted MnCu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础之面向对象02相关的知识,希望对你有一定的参考价值。
---继承
当我们定义完成某个类时,可以再定义一个新类,新类可以继承第一个类。新类被称为子类,而被继承的类称为父类/基类/超类。
继承就是子类继承父类的属性和方法(注意是类属性和类方法)。
继承可以使子类使用父类中的方法,也可以在子类中新定义某个方法,或者在子类中覆盖父类的方法。
来看一个实例:
class animal(object): #定义一个动物类 def running(self): print(\'running....\') class dog(animal): #定义一个狗类,且狗类继承动物类 def wangwang(self): print(\'wang! wang!\') xiaohei=dog() xiaohei.running() xiaohei.wangwang() #结果 running.... wang! wang!
我们可以看到,在上面的例子中,dog类继承animal类后,就不需要再重新定义running方法,可以直接调用animal中的running方法。这就是继承的优点之一。
如果我们在dog类中也定义一个running方法会怎样?
class animal(object): def running(self): print(\'running....\') class dog(animal): def wangwang(self): print(\'wang! wang!\') def running(self): print(\'dog is running\') #结果 dog is running #父类的方法被子类同名的方法覆盖 wang! wang!
也就是,子类中的方法会覆盖父类中同名的方法!
子类如何执行父类的构造函数?
1 super(Son, self).__init()
2 Father.__init__(self)
class Animal(object): name = \'ahah\' def __init__(self): self.a = \'animal\' class Cat(Animal): def __init__(self): super(Cat,self).__init__() # Animal.__init(self) self.b = \'cat\' c1 = Cat() print(c1.a) #animal
---多继承
所谓多继承就是指一个子类可以继承多个父类。大家可能会问:
1 怎么样才能实现多继承?
2 如果每个父类都有一个名称相同的方法,当子类调用该方法时最终调用的是哪一个?
1 首先来看第一个问题,怎么样才能实现多继承?
class animal(object): def running(self): print(\'running....\') class mammal(object): def grow(self): print(\'吃奶\') class dog(animal,mammal): #<-----------在括号中加入父类名称,并以逗号分隔即可 def wangwang(self): print(\'wang! wang!\') def running(self): print(\'dog is running\') xiaohei=dog() xiaohei.running() xiaohei.wangwang() xiaohei.grow() #结果 dog is running wang! wang! 吃奶
注意:Python的类可以继承多个类,Java和C#中则只能继承一个类。
2 再来看第二个问题:如果每个父类都有一个名称相同的方法,当子类调用该方法时最终调用的是哪一个?或者说继承顺序是怎样的?
在回答这个问题之前,我们需要先了解经典类和新式类。
什么是经典类什么是新式类?
class class_name: #经典类的定义方法 pass class class_name(object): #新式类的定义方法 pass
新式类较之经典类添加了很多功能,所以现在推荐用新式类。
在Python3中不管是新式类还是经典类继承顺序都是深度优先
class a(object):
def f(self):
print(\'a\')
self.f1()
def f1(self):
print(\'a-f1\')
class b(object):
def f1(self):
print(\'b\')
class c(a):
def f1(self):
print(\'c\')
class d(b):
def f(self):
print(\'d\')
class e(c,d):
def f1(self):
print(\'e\')
e1 = e()
e1.f()
但有个特殊情况:
如果A和B都all类的子类,则找完A以后不会找all,而是去找D。
我们可以总结出Python多继承时的优先顺序:
1 本身最大,先从自身查找
2 从左到右优先级依次降低,深度优先
3 若左父类与右父类的上层存在共同的父类,则将共同的父类及其上层移动到右父类的深度级别中
---方法
python中的方法包括普通方法/静态方法/类方法。但静态方法和类方法并不常用。
所有方法均属于类属性,也就是在内存中只有一份
普通方法:只能由实例调用,最少有一个self参数
静态方法:不需实例化就可以调用,没有默认参数
类方法:不需实例化就可以调用。最少有一个cls参数
class test(object): def show1(self): print(\'普通方法\') @staticmethod #静态方法 def show2(): print(\'静态方法\') @classmethod #类方法 def show3(cls): print(\'类方法\') #不实例化 test.show2() test.show3() print(\'------------分隔-------------\') #实例化 a=test() a.show1() a.show2() a.show3() #结果 静态方法 类方法 ------------分隔------------- 普通方法 静态方法 类方法
---属性
之前我们讲过,在类中的某个变量前加上两个下划线,就可以将这个变量“隐藏”起来,使其外部不可见。
class atm00(object): def __init__(self,money): self.money=money def show_money(self): print(\'the atm has %s¥ \'%self.money) a=atm00(100) a.show_money() a.money=120 a.show_money() #结果 the atm has 100¥ the atm has 120¥ #很明显,我们可以直接在外部给a.money赋值,这样虽然操作简单,但是我们无法验证用户输入的money是否合法
这时,我们可以这样修改:
class atm01(object): def __init__(self,money): self.__money=money def show_money(self): print(\'the atm has %s¥ \'%self.__money) def set_money(self,money): #当修改money时,还可以检测用户输入的值是否合法 if not isinstance(money,int): print("money\'s value must be interger") else: self.__money=money a=atm01(100) a.show_money()
a.set_money(120
通过修改,我们让代码更健壮更安全,但是却没有之前在外部直接赋值时的便捷了。有没有一种方法,即可以在外部直接赋值,有可以检测用户输入值的合法性呢?这里我们就要用到属性了!
class atm01(object): def __init__(self,money_value): self.__money=money_value @property #第一种属性 def money(self): return self.__money @money.setter #第二种属性 def money(self,money_value): if not isinstance(money_value,int): print("money\'s value must be interger") else: self.__money=money_value @money.deleter #第三种属性 def money(self): print(\'no money\') a=atm01(100) print(a.money) a.money=120 print(a.money) del a.money #结果 100 120 no money
上面的代码可能会看不懂,没关系,上面仅仅是用来说明属性的重要性,接下来我们来正式的讲解一下属性。
如何定义属性?
属性共有三种。
首先来看第一种属性:
class test(object): def step1(self): pass @property #定义时,在普通方法的基础上添加 @property 装饰器,该方法就成为属性 def step2(self): return \'hello world\' a=test() print(a.step2) #结果 hello world
注意两点:
1 属性中仅能包含一个self参数
2 调用属性时,不需要加括号
第二种和第三种属性:
# ############### 定义 ############### class Goods(object): @property def price(self): print \'@property\' @price.setter def price(self, value): print \'@price.setter\' @price.deleter def price(self): print \'@price.deleter\' # ############### 调用 ############### obj = Goods() obj.price # 执行@property 修饰的 price 方法,并获取方法的返回值 obj.price = 123 # 执行@price.setter 修饰的 price 方法,并将 123 赋值给方法的参数 del obj.price # 执行@price.deleter 修饰的 price 方法
总结一下,这三种属性作用分别为显示,修改,删除。
以上是关于python基础之面向对象02的主要内容,如果未能解决你的问题,请参考以下文章
2022年最新Python大数据之Python基础面向对象与继承