面向对象之继承

mac2022-06-30  29

面向对象之继承

面向对象之继承

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

什么是继承?

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

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

单继承,多继承.

继承的优点.

节省代码.

增强的耦合性.

代码规范化.

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

Person Dog Cat : 子类,派生类Animal: 父类, 基类, 超类单继承: 使用.多继承:有区别.

单继承. 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()) 面向对象:

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

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

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

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

python3x 只有新式类.

posted on 2019-07-09 19:44  七橼77 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/-777/p/11159871.html

最新回复(0)