一、面向对象的三个特征
封装、继承、多态。
1.封装
所谓封装,就是将属性和方法放在类中,然后通过类生成相应的对象。
class Student():
def __init__(self,name,age): #构造函数,可以自己执行
self.name = name
self.age = age
print("我叫{},今年{}岁。".format(self.name,self.age))
A=Student("张三",20)
B=Student("李四",22)
print(A.age)
我叫张三,今年20岁。
我叫李四,今年22岁。
20
2.继承
1.基本用法
多个类之间的所属关系,即子类默认继承父类的所有属性和方法,对继承的类进行拓展,且不改变继承的类。在实际开发过程中,除非真的需要,否则要根据实际情况来继承(总不能在属于人的特征的类中继承猪尾巴吧!)
子类:通过继承而生成的类。
父类:被继承的类,也叫作基类或者超类。
和其他语言不同,Python继承类的方法为再子类类名后面加上一个小括号,然后写上要继承的类名:
class A: #定义类A
x = 100 #在类A中定义一个属性 x
def say(self): #再类A中定义一个方法 say
print("hello,我是类A")
#Python继承类的方法为再子类类名后面加上一个小括号,然后写上要继承的类名
class B(A): #定义类B,并且继承类A
pass
b = B() #实例化对象b
b.x #输出x的值
b.say() #调用say()方法
100
hello,我是类A
子类可以访问父类的属性和方法,而父类不能访问子类的属性和方法,对于子类和父类中存在相同属性名或者方法名的时候,会优先再子类中寻找,如果没找到才会去上层类中去寻找调用。
class A: #定义类A
x = 100 #在类A中定义一个属性 x
def say(self): #再类A中定义一个方法 say
print("hello,我是类A")
class B(A): #定义类B,并且继承类A
x = 200 #在类A中定义一个属性 x
y = 100
def say(self): #再类B中定义一个方法 say
print("hello,我是类B")
b = B()
b.x
b.say()
a = A()
a.y #调用子类中的属性会报错
200
hello,我是类B
AttributeError: 'A' object has no attribute 'y'
2. 两个方法
1. isinstance()
用来检测一个对象是否属于某个类,如果属于则True,如果不属于则False。
isinstance(b,B) #判断实例对象b是否属于类B
True
2. issubclass()
用于检测一个类是否是一个类的子类,如果属于则True,如果不属于则False。
issubclass(B,A) #判断类B是否属于类A
issubclass(A,B) #判断类A是否属于类B
True
False
3. 多重继承
再Python中是支持多重继承的,也就是说一个子类可以继承多个父类。(类1,类2,...)
class A: #定义类A
x = 100 #在类A中定义一个属性 x
def say(self): #再类A中定义一个方法 say
print("hello,我是类A")
class B(A): #定义类B,并且继承类A
x = 200 #在类A中定义两个属性 x、y
y = 300
def say(self): ##再类B中定义一个方法 say
print("hello,我是类B")
class C(A,B): #定义类C,并且继承类A、B
pass
c = C() #创建实例对象 c
c.x #分别调用x、y、say()
c.y
c.say()
100
300
我是类A
通过上面的例子我们能看出来,实例对象c调用了类 A 的x属性和say方法,调用了类 B 的y属性,出现这种情况的原因是:当本类中没有相应的数据时,会优先访问类1,若类1中没有相应的数据会访问类2,按照从左向右的顺序进行访问。
当实例对象中没有某个属性时,不代表访问不到,因为他的类中可能会有该属性(被类实例过来)如果类中没有也会向继承的类中去寻找。
4.__dict__(内省)
对于__dict__,最常用的功能就是来看类中有哪些属性和方法。
class A: #定义类A
x = 100 #在类A中定义一个属性 x
def say(self): #再类A中定义一个方法 say
print("hello,我是类A")
def AAA(self): #再类A中定义一个方法 AAA
print("hello,我是类A")
class B(A): #定义类B,并且继承类A
x = 200 #在类A中定义两个属性 x、y
y = 300
def say(self): ##再类B中定义一个方法 say
print("hello,我是类B")
A.__dict__
B.__dict__
mappingproxy({'__module__': '__main__', 'x': 100, 'say': <function A.say at 0x01660D68>, 'AAA': <function A.AAA at 0x01660DB0>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})
mappingproxy({'__module__': '__main__', 'x': 200, 'y': 300, 'say': <function B.say at 0x01660E40>, '__doc__': None})
3. 多态
多态是指同一个运算符、函数或对象在不同的场景下具有不同的作用效果的一个功能。
1. 运算符的多态
对于 "+" 和 "*",作用再不同的数据类型上有不同的表示:
#对于数字类型的数据,会对其进行数学运算
2+2
# 4
2*3
# 6
#对于字符类型的数据,会将其进行拼接或"复制"
"Hello" +"World"
# 'HelloWorld'
"Hello"*3
# 'HelloHelloHello'
2. 方法的多态
对于方法,也是有多态的,这里我们用len()来进行举例。
len("Hello") #当输入的使字符串时,输出的时字符串的个数
# 5
len({"Hello","World","Python"}) #当输入的时列表时,输出的是列表中元素的个数
# 3
len(["小明:22","小刚:23"]) #当输入的是字典时,输出的时key的个数
# 2
3. 类继承的多态
对于类继承的多态其实就是重写方法:
class A: #创建类A,并且创建一个方法funA
def funA(self):
print("喵喵喵!")
class B(A): #创建类B,继承类A,重写类A的方法funA
def funA(self):
print("汪汪汪!")
class C(A): #创建类C,继承类A,重写类A的方法funA
def funA(self):
print("我不仅仅会喵喵喵,我还会汪汪汪!")
b = B() #创建实例对象b
b.funA() #调用方法funA
c = C() #创建实例对象b
c.funA() #调用方法funA
#汪汪汪!
#我不仅仅会喵喵喵,我还会汪汪汪!
其实self也是一种多态的体现,根据传入的对象不同,执行不同对象的属性或方法。