python python代码的继承方法重写及动态语言

Posted 水木,年華

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python python代码的继承方法重写及动态语言相关的知识,希望对你有一定的参考价值。

面向对象的三大特征

封装:提高程序的安全性,将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在
类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
在Pvthon中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个”_”。

继承:提高代码的复用性

多态:提高程序的可扩展性和可维护性

继承

语法格式

class 子类类名 (父类1,父类2...) :
pass

如果一个类没有继承任何类,则默认继承object
Python支持多继承
定义子类时,必须在其构造函数中调用父类的构造函数

class Person(object): #Person继承object类
    def __init__(self,name,age):
              self.name=name
              self.age=age
    def info(self):
        print(self.name,self.age,)

class Student(Person):
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)
        self.stu_no=stu_no

class Teacher(Person):
    def __init__(self,name,age,teachofyear):
        super().__init__(name,age)
        self.teachofyear=teachofyear


stu=Student('张三',18,1006)
teacher=Teacher('李四',34,10)

stu.info()
teacher.info()

张三 18
李四 34


#多继承
class A(object):
    pass

class B(object):
    pass

class C(A,B):
    pass

方法重写

如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写。

子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法

class Person(object):
    def __init__(self,name,age):
              self.name=name
              self.age=age
    def info(self):
        print(self.name,self.age,)

class Student(Person):
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)
        self.stu_no=stu_no

    def info(self):
        super().info()
        print('学号',self.stu_no)

stu=Student('张三',18,1006)

stu.info()

张三 18
学号 1006

object类

object类是所有类的父类,因此所有类都有object类的属性和方法。

内置函数dir()可以查看指定对象所有属性。

Object有一个_str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对_str__()进行重写。

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
         return  "我的名字是0,今年1岁".format(self.name,self.age)
stu=Student('张三',20)
print(dir(stu))
print(stu) #默认调用__str__()这样的方法
print(type(stu))

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
我的名字是张三,今年20岁
<class '__main__.Student'>

多态

简单地说.多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。

class animal(object):
    def eat(self):
        print("动物会吃")

class dog(animal):
    def eat(self):
        print("狗吃骨头")

class  cat(animal):
    def eat(self):
        print("猫吃鱼")

class person:
    def eat(self):
        print("人吃五谷杂粮")

#定义一个函数
def fun(obj):
    obj.eat()

fun(dog())
fun(cat())
fun(animal())
fun(person())

狗吃骨头
猫吃鱼
动物会吃
人吃五谷杂粮

静态语言和动态语言关于多态的区别

静态语言实现多态的三个必要条件
继承
方法重写
父类引用指向子类对象

动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。

特殊方法和特殊属性

class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age
#创建C类的对象
x=C('Tom',20) #x是C类型的一个实例对象
print(x.__dict__) #实例对象的属性字典
print(C.__dict__)
print("---------------------------------")
print(x.__class__) #输出了对象所属的类
print(C.__bases__)  #C类的父类类型的元素
print(C.__base__)   #类的基类
print(C.__mro__)    #类的层次结构
print(A.__subclasses__()) #子类的列表

'name': 'Tom', 'age': 20
'__module__': '__main__', '__init__': <function C.__init__ at 0x0000013447030B80>, '__doc__': None
---------------------------------
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
<class '__main__.A'>
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>]
# __new__创建对象
class Student:
    def __init__(self,name):
        self.name=name
    def __add__(self,other):
        return self.name+other.name
    def __len__(self):
        return len(self.name)

stu1=Student('TOM')
stu2=Student('李四')

s=stu1+stu2 #实现了两个对象的加法运算(应为在Student类中 编写__add__()特殊的方法
print(s)
s=stu1.__add__(stu2)
print(s)
print('------------------------------')
lst=[11,12,13,14,15,16]
print(len(lst)) #len是内置函数len
print(lst.__len__())
print(len(stu1))
class Person(object):
    def __new__(cls, *args, **kwargs):
        print('__new__被调用执行了,cls的id值为0'.format(id(cls)))
        obj=super().__new__(cls)
        print('创建的对象的id为:0'.format(id(obj)))
        return obj

    def __init__(self,name,age):
         print('__int__被调用了,self的id值为:0'.format(id(self)))
         self.na=name
         self.ag=age
print('object这个类对象的id为:0'.format(id(object)))
print('Person这个类对象的id为:0'.format(id(Person)))

#创建Person类的实例对象
p1=Person('张三',20)
print('p1这个Person类对象的id为:0'.format(id(p1)))
print(p1.na,p1.ag)

object这个类对象的id为:140711051832144
Person这个类对象的id为:2053446623536
__new__被调用执行了,cls的id值为2053446623536
创建的对象的id为:2053477731920
__int__被调用了,self的id值为:2053477731920
p1这个Person类对象的id为:2053477731920
张三 20

类的浅拷贝与深拷贝

变量的赋值操作
只是形成两个变量,实际上还是指向同一个对象

浅拷贝
Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象

深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同。

总结

以上是关于python python代码的继承方法重写及动态语言的主要内容,如果未能解决你的问题,请参考以下文章

python python代码的继承方法重写及动态语言

在 Python 中如何实现类的继承,方法重载及重写?

29.Python面向对象类:主要讲初始化方法__init__,垃圾回收,继承&多继承,方法重写,super()函数

29.Python面向对象类:主要讲初始化方法__init__,垃圾回收,继承&多继承,方法重写,super()函数

29.Python面向对象类:主要讲初始化方法__init__,垃圾回收,继承&多继承,方法重写,super()函数

Python类的继承和方法重写总结