20201222-1 类的继承2
2021-04-16 23:41
74 查看
1-1-1 Man 在初始化时 可以多传入一个属性吗? 可以在类 Man 下进行重构class People:def __init__(self,name,age): self.name = name # 等号两边的 name 变量名可以不一致,比如 self.NAme = name; name 是(self,name,age)中的参数名,NAme 是赋的变量名self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name) class Man(People):# def __init__ 这个动作相当于完全重构,会覆盖 # 这样用户实例化时,不会调用父类,将直接调用这里的 def __init__ # 这样需要重新写一遍参数def __init__(self,name,age,money): People.__init__(self,name,age) # self.name 和 age 在父类中实现self.money = money # 新增功能 money 在子类中实现print("%s 一出生就有%s money"%(self.name,self.money))def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(People):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222,10) # 这样就需要 传入 money m1.eat() m1.piao() m1.sleep() w1 = Woman("ChenRonghua",26) w1.get_birth()--->NiuHanYang 一出生就有 10 money NiuHanYang is eating... NiuHanYang is piaoing.....20s......done. NiuHanYang is sleeping... man is sleeping ChenRonghua is born a baby.... 这就是对 构造函数 进行重构 父类的参数都要写一遍,因为用户调用时,不是调用父类,是在调用初始化构造函数 写完后,加入新增的属性,这时候就与父类无关了 注:没有高级方法,只可以这样写
1-1-2父类通常不会有很多参数,不固定的加 *args 即可 还有一种其他的方法可以调用父类,另一种方式,叫做 superclass People:def __init__(self,name,age): self.name = name # 等号两边的 name 变量名可以不一致,比如 self.NAme = name; name 是(self,name,age)中的参数名,NAme 是赋的变量名self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name) class Man(People):def __init__(self,name,age,money):# People.__init__(self,name,age) # self.name 和 age 在父类中实现super(Man,self).__init__(name,age)# super(Man,self).__init__(name,age) 这种写法与 People.__init__(self,name,age) 是完全一样的 # super 的作用就是 继承父类的 构造函数 self.money = money print("%s 一出生就有%s money"%(self.name,self.money))def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(People):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222,10) # 这样就需要 传入 money m1.eat() m1.piao() m1.sleep() w1 = Woman("ChenRonghua",26) w1.get_birth()--->NiuHanYang 一出生就有10 money NiuHanYang is eating... NiuHanYang is piaoing.....20s......done. NiuHanYang is sleeping... man is sleeping ChenRonghua is born a baby....
1-1-3既然 super(Man,self).__init__(name,age) 这种写法与 People.__init__(self,name,age) 是完全一样的 为什么还会有 super 呢? super 没有写 People,这样以后修改父类名称时,super 无需修改 如果有多个子类,无需修改多个子类中的 "People" 类可以进行多继承,比如:class Man(People,Animal):def __init__(self,name,age,money): People.__init__(self,name,age) Animal.__init__(self,name,age)# 如果用 super 就会变得方便,直接多继承了super(Man,self).__init__(name,age)
1-1-4 其实还有一个地方可以改进,其实标准的写法如下:# 好比 python 2.7 和 3.0; 新式类中多了一些升级# class People: 经典类class People(object): # 新式类def __init__(self,name,age): self.name = name # 等号两边的 name 变量名可以不一致,比如 self.NAme = name; name 是(self,name,age)中的参数名,NAme 是赋的变量名self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name) class Man(People):def __init__(self,name,age,money):# People.__init__(self,name,age) # self.name 和 age 在父类中实现super(Man,self).__init__(name,age)# super(Man,self).__init__(name,age) 这种写法与 People.__init__(self,name,age) 是完全一样的 # super 的作用就是 继承父类的 构造函数 self.money = money print("%s 一出生就有%s money"%(self.name,self.money))def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(People):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222,10) # 这样就需要 传入 money m1.eat() m1.piao() m1.sleep() w1 = Woman("ChenRonghua",26) w1.get_birth() 我们只需要关心,新式类多继承的方式变了 在继承上,新式类和经典类是有明显不同的 super(Man,self).__init__(name,age) 是新式类的写法 People.__init__(self,name,age) 是经典类的写法
1-2经典类和新式类的变化,主要体现在继承上 首先需要了解多继承,才可以知道区别在哪里 不是所有语言都支持多继承,比如 java 就是不支持的# 现在有一个 People,添加一个关系类class People(object): # 新式类def __init__(self,name,age): self.name = name # 等号两边的 name 变量名可以不一致,比如 self.NAme = name; name 是(self,name,age)中的参数名,NAme 是赋的变量名self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name)class Relation(object):# 结果生成两个人,调用的是 m1 的 friends;得有交朋友的对象,所以obj就是w1# 为什么这地方写的是 obj 而不是 "chenronghua",因为传的只是一个字符串,并没有真的关联# 真正要传的是 w1def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name))# 在男人这里直接继承 Relation class Man(People,Relation):def __init__(self,name,age,money):# People.__init__(self,name,age) # self.name 和 age 在父类中实现super(Man,self).__init__(name,age)# super(Man,self).__init__(name,age) 这种写法与 People.__init__(self,name,age) 是完全一样的 # super 的作用就是 继承父类的 构造函数 self.money = money print("%s 一出生就有%s money"%(self.name,self.money))def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")# 在Woman这里也继承 Relation;多写一个就是多继承一个class Woman(People,Relation):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222,10) # 这样就需要 传入 money # 既然继承了,就代表可以用 Relation 里的方法w1 = Woman("ChenRonghua",26) m1.make_friends(w1)--->NiuHanYang 一出生就有10 money NiuHanYang is making friends with ChenRonghua 这样就可以多继承了 这个 Relation 并没有写构造函数,也没有传参数,为什么就可以直接 .name了呢? 在继承父类时,name就已经传进去了,名字已经有了,所以不需要在继承一遍 只需要把额外的需要继承的功能填进去就可以了 自己已经有一些功能了,在添加一些新功能还是给自己添加,所以Relation中,可以 self.name,因为已经有名字了
1-2-1这是因为 People 类中,已经先有名字了吗? 如果调用 People 和 Relation 的顺序呢?class People(object): # 新式类def __init__(self,name,age): self.name = name # 等号两边的 name 变量名可以不一致,比如 self.NAme = name; name 是(self,name,age)中的参数名,NAme 是赋的变量名self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name)class Relation(object):def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name))# 在男人这里直接继承 Relation class Man(Relation,People):def __init__(self,name,age,money):# People.__init__(self,name,age) # self.name 和 age 在父类中实现super(Man,self).__init__(name,age)# super(Man,self).__init__(name,age) 这种写法与 People.__init__(self,name,age) 是完全一样的 # super 的作用就是 继承父类的 构造函数 self.money = money print("%s 一出生就有%s money"%(self.name,self.money))def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")# 在Woman这里也继承 Relation;多写一个就是多继承一个class Woman(People,Relation):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222,10) # 这样就需要 传入 money # 既然继承了,就代表可以用 Relation 里的方法w1 = Woman("ChenRonghua",26) m1.make_friends(w1)--->NiuHanYang 一出生就有10 money NiuHanYang is making friends with ChenRonghua# 结果依然是成立的# 不过,class Man(Relation,People), Relation 和 People 的放置顺序,其实是有关系的# 真正生成名字,不是在People里生成的,是在 Man 中构造时 生成的# 本来要继承父类的 __init__ ;但是 Man 自己有 __init__ 了,所以就不执行父类的了,这里执行的是自己的# 所以是先执行了自己的 __init__ 之后,由执行了父类的方法# 所以,name就已经有了
1-2-2如果Man没有自己的构造方法呢?这时就需要寻找父类的构造方法 类Man 先 Relation,后 People 能否找到呢?class People(object): # 新式类def __init__(self,name,age): self.name = name self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name)class Relation(object):def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name)) class Man(Relation,People):def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(People,Relation):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222) w1 = Woman("ChenRonghua",26) m1.make_friends(w1)--->NiuHanYang is making friends with ChenRonghua 结果依然没有报错,为什么? 因为 Man 没有构造方法,实例化时会找父类,先找到了 Relation,Relation中没有构造方法,为什么没有报错? 因为 Relation 中的 make_friends 方法还没有执行,没执行所以没问题
1-2-3可以进行验证class People(object): # 新式类def __init__(self,name,age): self.name = name self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name)class Relation(object):def __init__(self):print(self.name)# 验证,是不是按照从左到右的顺序执行的,如果是从左到右执行的,是会报错的def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name)) class Man(Relation,People):def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(People,Relation):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222) w1 = Woman("ChenRonghua",26) m1.make_friends(w1)--->TypeError: __init__() takes 1 positional argument but 3 were given 报错中说,传了三个参数,虽然继承了父类,但是子类需要传参数class Relation(object):def __init__(self):print(self.name) 里面必须接收参数
1-2-4所以传入两个参数 n1 n2class People(object): # 新式类def __init__(self,name,age): self.name = name self.age = agedef eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name)class Relation(object):def __init__(self,n1,n2):print(self.name)# 验证,是不是按照从左到右的顺序执行的,如果是从左到右执行的,是会报错的def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name)) class Man(Relation,People):def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(People,Relation):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222) w1 = Woman("ChenRonghua",26) m1.make_friends(w1)--->AttributeError: 'Man' object has no attribute 'name'这个时候报错说里面没有 name 所以,默认的执行顺序是 从左到右;这时左边还没有这个 name,所以就没有 name
1-3# class People: 经典类class People(object): # 新式类def __init__(self,name,age): self.name = name self.age = age self.friends = [] # 默认的朋友列表def eat(self):print("%s is eating..."%self.name)def talk(self):print("%s is talking..."%self.name)def sleep(self):print("%s is sleeping..."%self.name)class Relation(object):def make_friends(self,obj):print("%s is making friends with %s"%(self.name,obj.name)) self.friends.append(obj)# 现在 Relation 和 People 没关系,通过子类继承才有关系# 这样加上 obj 两个人就真正联系起来了class Man(Relation,People):def __init__(self,name,age,money):# People.__init__(self,name,age) # self.name 和 age 在父类中实现super(Man,self).__init__(name,age)# super(Man,self).__init__(name,age) 这种写法与 People.__init__(self,name,age) 是完全一样的 # super 的作用就是 继承父类的 构造函数 self.money = money print("%s 一出生就有%s money"%(self.name,self.money))def piao(self):print("%s is piaoing.....20s......done."%self.name)def sleep(self): People.sleep(self) print("man is sleeping")class Woman(Relation,People):def get_birth(self):print("%s is born a baby...."%self.name) m1 = Man("NiuHanYang",222,10) # 这样就需要 传入 money w1 = Woman("ChenRonghua",26) m1.make_friends(w1)print(m1.friends)--->NiuHanYang 一出生就有10 money NiuHanYang is making friends with ChenRonghua [<__main__.Woman object at 0x0000021283609C08>]# obj.name 是字符串
相关文章推荐
- 2015 5.16 C# 继承和多态
- 再谈javascript原型继承
- 继承
- SE24新建类步骤以及如何继承一个系统类的属性
- C++继承中的访问控制实例分析
- CppPrimer自学(3)公有继承
- php 的继承中需要注意的地方
- 多继承基类中有同名虚函数
- C++的继承,多继承,虚继承的对象分布的总结
- java基础总结九(继承、抽象类)
- 用公用继承方式 第五章第一题
- 多重继承下的类型转换
- 前端学习日记(七):css中伪元素选择器、级联、继承、颜色、长度与尺寸、字体样式的简单应用
- linux C++ 面向对象线程类(封装,继承,多态)
- 139邮箱JS的继承体系
- Maven之继承与聚合
- 代码块 继承思想
- java中的成员方法与成员变量的继承
- windows phone (13) 样式继承
- JAVASCRIPT面向对象(继承)第三章