一,面向对象的三大特征
在面向对象中,有三大特征1.封装,2. 继承, 3. 多态。
1. 继承
1. 什么是继承:继承就是一种新建类的方式,新建出来的类我们称为新生类,或子类,被继承的就是父类或者叫基类,新建出来的子类可以继承父类的索引属性。
2. 为什么需要继承:类解决了对象与对象之间代码冗余的问题,而继承解决了类与类之间的代码冗余问题。
3. 怎么使用继承:分为经典类与新式类
经典:没有继承object类的子子孙孙类的都是经典类
新式:继承了object类的子子孙孙类的都是新式类
注:在python2中彩分为经典类与新式类,而在python3中只有新式类,也就是说在python3中所有的类都继承了object类,所以在python3中没有金典类的说法了。
单继承与多继承:
class A: print('form A') school = 'BJ' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class B(object): print('from B') class C(A): print('c') """C继承了A,那么C就是子类,而A被继承的就是父类或基类""" class D(A, B): print('d') """同理D继承了A,B那么D就是子类,而A,B被继承的就是父类或基类 同时继承了一个以上的又被称为多继承""" print(C.__bases__) print(D.__bases__)
2. 继承的实列
class A:
print('form A')
school = 'BJ'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class B(A):
def __init__(self, name, age, gender, course=None):
if course is None:
course = []
A.__init__(self, name, age, gender)
self.course = course
def C(self):
print('%s选课成功,%s' % (self.name, self.course))
"""进行属性查找"""
stu = B('kiki', 19, 'male', 90)
print(stu.__dict__)
print(stu.name)
print(stu.age)
print(stu.gender)
class D(A):
def __init__(self, name, age, gender, level):
A.__init__(self, name, age, gender)
self.level = level
def score(self):
print('%s得了%s分' % (self.name, 100))
stu1 = D('ll', 19, 'male', 100)
print(stu1.name)
print(stu1.age)
print(stu1.gender)
3 .单继承的属性查找
"""单继承的查找属性"""
class A:
def f2(self):
print('form f2')
class B(A):
def __f1(self):
print('from f1')
class C(B):
def __f1(self):
print('form v')
"""单继承查找属性时,现在自己的对象空间里去寻找,
如果没有再去别的对象空间寻找,最后再去被继承的父类空间里去寻找"""
4. 多继承属性的查找
多继承下分菱形查找和非菱形查找
菱形查找分 经典类 和 新式类
经典类:按照深度优先的查找顺序
新式类:按照广度优先查找"""多继承属性的查找又分为菱形查找与非菱形查找,而菱形查找又分为经典类与新式类""" class G: def test(self): print('from G') class F(G): def test(self): print('from F') class E(F): def test(self): print('from E') class D(E): def test(self): print('from D') class C(D): def test(self): print('from C') class B(C): def test(self): print('from B') class A(B, C, D): def test(self): print('from A') obj = A() obj.test() """查找顺序为:obj->A->B->E->G->C->F->D->object"""
5. super和mro的用法
class A():
def test(self):
super().test()
class B():
def test(self):
print('form B')
class C(A, B):
print('from c')
"""在打印mro列表的时候,一定是从其实位置开始的,"""
print(A.mro()) # [<class '__main__.A'>, <class 'object'>]
print(B.mro()) # [<class '__main__.B'>, <class 'object'>]
print(C.mro()) # [<class '__main__.C'>, <class '__main__.A'>
# , <class '__main__.B'>, <class 'object'>]
"""mro是使用C3算算出来的,我们无需知道底层的原理,只要知道每个mro列表到底是什么,然后根据列表去查就好了"""
a = A() #A().text()
print(A.mro()) # [<class '__main__.A'>, <class 'object'>]
print(A.__mro__) # (<class '__main__.A'>, <class 'object'>)
7. 多态与鸭子形态
什么是多态:
他是面向对象三大特征中的一种,指同一事物的多种形态。
面向对象中的多态是指在不同的对象上调用同一个方法,可以产生不同的行为。具体来说,多态有两种实现方式:继承和接口。
在继承中,子类可以重写父类的方法,就像是继承了父类方法的一部分,但对于子类而言,重写的方法和父类的方法可能会有所不同,调用该方法的时候会根据实际子类类型调用子类的方法。
在接口中,不同的类实现同一个接口,实现接口的类可以重写接口中的方法,但每个类对接口中方法的实现不尽相同,同样在调用接口方法时也会根据实际对象类型调用不同的实现。
多态的优点在于提高了代码的灵活性和复用性,减少了代码的重复,提高了代码的可扩展性。同时,多态也是面向对象的关键特征之一。
举例:
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass
@abc.abstractmethod
def jiao(self):
pass
class People(Animal):
def speak(self):pass
# print('from People.speak')
def jiao(self):
pass
class Dog(Animal):
def speak(self):
pass
class Pig(Animal):
def speak(self):
pass
"""多态带来的特性:在不考虑对象类型的情况下,直接调用对象的方法或者属性"""
def animal(obj):
return obj.speak()
animal(obj)
animal(obj1)
animal(obj2)