面向对象之继承

面向对象之继承

面向对象的三大特性: 封装,继承,多态.

什么是继承?

专业角度: B 继承 A类, B就叫做A的子类,派生类, A叫做B的父类,基类,超类. B类以及B类的对象使用A类的所有的属性以及方法.

字面意思: 继承就是继承父母所有的资产.

单继承,多继承.

继承的优点.

  1. 节省代码.

  2. 增强的耦合性.

  3. 代码规范化.

继承分为单继承与多继承.

  1. Person Dog Cat : 子类,派生类
  2. Animal: 父类, 基类, 超类
  3. 单继承: 使用.
  4. 多继承:有区别.
  5. 单继承.
    class Person:

def init(self,name,sex,age):

self.name = name

self.age = age

self.sex = sex

class Cat:

def init(self,name,sex,age):

self.name = name

self.age = age

self.sex = sex

class Dog:

def init(self,name,sex,age):

self.name = name

self.age = age

self.sex = sex

class Animal:

def init(self, name, age, sex):

self.name = name

self.age = age

self.sex = sex

class A:

pass

class Person(Animal):

pass

class Dog(Animal):

pass

class Cat(Animal):

pass

继承的优点:

继承分为单继承与多继承.

Person Dog Cat : 子类,派生类

Animal: 父类, 基类, 超类

单继承: 使用.

多继承:有区别.

class Animal(object):

live = '有生命的'

def init(self, name, age, sex):

self.name = name

self.age = age

self.sex = sex

def eat(self):

print(f'self----> {self}')

print('动物都需要进食')

class Person(Animal):

pass

# 1.从类名执行父类的属性.

# print(Person.dict)

# print(Person.live)

# Person.eat(55)

# 2. 从对象执行父类的一切.

# 实例化对象一定一定会执行三件事. 一定会执行__init__

# p1 = Person('dsb', 21, 'laddy_boy')

# # print(p1.dict)

# print(p1.live)

# p1.eat()

# print(f'p1--->{p1}')

Person.live = 'xxx'

print(Person.live)

注意: 子类以及子类对象只能调用父类的属性以及方法,不能操作(增删改).

class Animal(object):

live = '有生命的'

def init(self, name, age, sex):

self.name = name

self.age = age

self.sex = sex

def eat(self):

print(f'self----> {self}')

print('动物都需要进食')

class Person(Animal):

def eat(self):

print('人类需要进食')

p1 = Person('dsb', 21, 'laddy_boy')

# 子类将父类的方法覆盖了,(重写父类的方法)

p1.eat = '李业'

p1.eat() # 对象查找顺序先从对象空间找名字, 子类找名字, 父类找名字.

如何既要执行父类方法又要执行子类方法

两种解决方式:

class Animal:

live = '有生命的'

def init(self, name, age, sex):

self.name = name

self.age = age

self.sex = sex

def eat(self):

print(f'self----> {self}')

print('动物都需要进食')

class Person(Animal):

def init(self,name, age, sex, hobby):

'''

self : p1

:param name: 怼怼哥

:param age: 23

:param sex: 不详

:param hobby: 吹牛逼

'''

# 方法一:

Animal.init(self, name, age, sex)

# 方法二:

# super(Person, self).init(name, age, sex)

# super().init(name, age, sex)

self.hobby = hobby

def eat(self):

print('人类需要进食')

super().eat()

p1 = Person('怼怼哥', 23, '不详','吹牛逼')

# print(p1.dict)

p1.eat()

class Base:

def init(self, num):

self.num = num

def func1(self):

print(self.num)

class Foo(Base):

pass

obj = Foo(123)

obj.func1()

class Base:

def init(self, num):

self.num = num

def func1(self):

print(self.num)

class Foo(Base):

def func1(self):

print("Foo. func1", self.num)

obj = Foo(123)

obj.func1()

class Base:

def init(self, num): # 2

self.num = num

def func1(self): # 4

print(self.num) # 123

self.func2() # self ---> obj # 对象查询顺序:

def func2(self):

print("Base.func2")

class Foo(Base):

def func2(self):

print("Foo.func2")

obj = Foo(123) # 1

obj.func1() # 3

class Base:

def init(self, num):

self.num = num

def func1(self):

print(self.num)

self.func2()

def func2(self):

print(111, self.num)

class Foo(Base):

def func2(self):

print(222, self.num)

lst = [Base(1), Base(2), Foo(3)]

for obj in lst:

obj.func2()

class Base:

def init(self, num):

self.num = num

def func1(self):

print(self.num)

self.func2()

def func2(self):

print(111, self.num)

class Foo(Base):

def func2(self):

print(222, self.num)

lst = [Base(1), Base(2), Foo(3)]

for obj in lst:

obj.func1()

子类以及对象可以调用父类的属性方法.
多继承.
class God:

# def init(self,name):

# self.name = name

def fly(self):

print('会飞')

def climb(self):

print('神仙累了也需要爬树')

class Monkey:

# def init(self,sex):

# self.sex = sex

def climb(self):

print('爬树')

class MonkeySun(God, Monkey):

pass

# 多继承的难点就是继承顺序的问题

sun = MonkeySun()

sun.climb()

python2x

class A: # 经典类

pass

class B(object): # 新式类

pass

python3x:(默认继承object)

class C: # 新式类

pass

class A:
pass

class B(A):
pass

class C(A):
pass

class D(B, C):
pass

class E:
pass

class F(D, E):
pass

class G(F, D):
pass

class H:
pass

class Foo(H, G):
pass

print(Foo.mro())

mro算法 面试中有可能会遇到

mro(Child(Base1,Base2)) = [ Child ] + merge( mro(Base1), mro(Base2), [ Base1, Base2] )

mro(Foo(H,G)) = [Foo] + merge(mro(H), mro(G),[H,G])

表头:

列表的第一个元素

表尾:

列表中表头以外的元素集合(可以为空)

表头,表尾

[A,B,C] : 表头: A 表尾: [B,C]

[A] : 表头: A 表尾: []

'''
class O:
pass

class D(O):
pass

class E(O):
pass

class F(O):
pass

class B(D,E):
pass

class C(E,F):
pass

class A(B,C):
pass

a = A()

a.func()

'''
'''
mro(A) = mro(A(B,C))
= [A] + merge(mro(B), mro(C), [B,C])

mro(B) = mro(B(D,E))
= [B] + merge(mro(D), mro(E), [D,E])
= [B] + merge([D,O], [E,O], [D,E])
= [B,D] + merge([O], [E,O], [E])
= [B,D,E,O]

mro(C) = mro(C(E,F))
= [C] + merge(mro(E), mro(F),[E,F])
= [C] + merge([E,O],[F,O],[E,F])
= [C,E] + merge([O],[F,O],[F])
= [C,E,F,O]

mro(A) = mro(A(B,C))
= [A] + merge([B,D,E,O], [C,E,F,O], [B,C])
= [A,B] + merge([D,E,O], [C,E,F,O], [C])
= [A,B,D] + merge([E,O], [C,E,F,O], [C])
= [A,B,D,C] + merge([E,O], [E,F,O])
= [A,B,D,C,E] + merge([O], [F,O])
= [A,B,D,C,E,F,O]

'''
class O:
pass

class D(O):
pass

class E(O):
pass

class F(O):
pass

class B(D,E):
pass

class C(E,F):
pass

class A(B,C):
pass

工作中用mro()方法研究新式类的继承顺序

print(A.mro())
面向对象:

  1. python2.2之前:都是经典类,

  2. python2.2直至python2.7之间存在两种类型: 经典类,新式类.

  3. 经典类: 基类不继承object,查询规则 依靠:深度优先的原则.

  4. 新式类: 基类必须继承object,查询规则: mro算法.

  5. python3x 只有新式类.

原文地址:https://www.cnblogs.com/-777/p/11159871.html