面向对象特性
1、封装特性
隐藏对象的属性和方法实现细节,仅对外提供公共访问方式。
__属性或者方法名称。(也叫私有属性或者方法)
封装的目的:保护隐私
私有化封装后的限制
类中 可以访问
类外/对象外 不可以访问
子类/子类对象 不可以访问
私有属性
class Girl():
def __init__(self,name,age):
self.name=name
self.__age=age
def show(self):
print(self.name,self.__age)
zs=Girl("张三",18)
zs.show()#在内部
print(zs.__age)#在外部
class Girle():
def __init__(self):
pass
def setAge(self,age):
if age<0 or age>95:
print("来自星星的你")
self.age=0
else:
self.age=age
def getAge(self):
return self.age
zs=Girle()
zs.setAge(20)
print(zs.getAge())
zs.age=-9
print(zs.getAge())
class A():
def __init__(self,age):
self.__age=19
def setAge(self,age):
self.__age=age
def __str__(self):
return str(self.__age)
a=A(1)
a.__age=100
print(a.__dict__)
print(a._A__age)
a._A__age=99#不建议这样修改私有变量
print(a.__dict__)
私有方法
class Phone():
def test(self):
print("test1")
def __test1(self):
print("test1")
x=Phone()
x.test()
x.__test1()#在外部调用不到私有方法
class Phone():
def __phone(self):
print("正在拨打电话")
def phone(self,m):
if m>30:
self.__phone()
else:
print("请先给手机缴费30,")
x=Phone()
x.phone(38)
2、继承特性
继承就是让类和类之间产生父子关系,子类可以拥有父类的静态属性和方法。
python 中继承分为:单继承和多继承
父类:用于被继承的类,称之为父类,也叫基类或者超类
子类:继承其他类的类,称之为子类,也叫派生类
作用:提高代码的重用率
class Animal():
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def jiao(self):
print("叫")
def eat(self):
print("吃")
class Cat(Animal):
def climb(self):
print("爬树")
class Dog(Animal): # 子类,继承谁就在括号中写谁
def swiming(self):
print("游泳")
d = Dog("aha", 3, '公')
c = Cat("ha", 3, '母')
c.climb()
d.swiming()
print(Cat.__bases__)
print(Dog.__bases__)
print(Animal.__bases__)
注:__bases__ 查看继承的父类,所有的类都是从object类中继承下来的
class A():
def hehe(self):
print("A,呵呵")
class B(A):
def hehe(self):
print("B,呵呵")
a=A()
b=B()
a.hehe()
b.hehe()#自己有的方法调用自己的不用父类A的,即覆盖了A也叫方法的重写
class A():
def __init__(self,x,y):
self.x=x
self.y=y
class B(A):
def __init__(self,x,y,z):
self.z=z
super().__init__(x,y)
b=B(1,2,3)
print(b.x)
注:子类和父类有相同的方法,如果子类想调用父类相同的方法。可以使用super()方法
class A():
num=3
__num1=2
def __init__(self,x,y):
self.x=x
self.y=y
class B(A):
num=10#静态属性、类属性
def __init__(self,x,y,z):
self.z=z
super().__init__(x,y)
b=B(1,2,3)
print(b.x)
print(B.num)
print(A.num)
print(super(B,b).num)#用B的父类中num,调用父类的num
多继承
class A():
def t1(self):
print("A:t1")
class B():
def t2(self):
print("B:t2")
class C(A,B):
def t3(self):
print("C:t3")
c=C()
c.t1()
c.t2()
c.t3()
class A():
def tx(self):
print("A:t1")
class B():
def tx(self):
print("B:t2")
class C(A,B):
def t(self):
print("C:t3")
c=C()
c.t()
c.tx()#先用继承前面的父类A,
钻石继承的super是根据广度优先的
class A():
def func(self):
print("A开始")
print("A结束")
class B(A):
def func(self):
print("B开始")
super().func()
print("B结束")
class C(A):
def func(self):
print("C开始")
super().func()
print("C结束")
class D(B,C):
def func(self):
print("D开始")
super().func()
print("D结束")
d=D()
d.func()
print(D.mro())
注:mro()可以求出线性列表,根据这个顺序走
3、多态
声明的形参的时候是父类对象,实际运行的时候是子类对象
class Dog():
def jiao(self):
print("汪汪")
class Cat():
def jiao(self):
print("喵喵")
class Pig():
def jiao(self):
print("哼哼")
def honghong(a):
a.jiao()
d=Dog()
c=Cat()
p=Pig()
honghong(d)
honghong(c)
honghong(p)
class Ali():
def pay(self,money):
print("阿里支付",money)
class Weixin():
def pay(self,money):
print("微信支付",money)
class Person() :
def consume(self,pay,money):
pay.pay(money)#多态用谁就调谁
ali=Ali()
weixin=Weixin()
zs=Person()
zs.consume(ali,100)
zs.consume(weixin,200)
实例方法(对象方法),类方法,静态方法
实例方法(对象方法),类方法,静态方法
class A():
num=10
def hehe(self):
print("我是实例方法,也叫对象方法,我的第一个参数是进来的对象")
@classmethod
def haha(cls):
print("我是类方法,我的第一个参数代表的是类例如此例子是A",cls.num)
@staticmethod
def heihei():
print("我是静态方法我跟这个类没有太多的血缘关系")
a=A()
a.hehe()
A.haha()
A.heihei()
a.haha()#对象(实例)访问了类方法。没出问题。因为我传进去的参数虽然是对象,但是我知道他是那个类
a.heihei()
A.hehe(a)用类名访问对象方法,第一个参数如果传过来对象,是可以运行的,
如果考试问:用类名可以访问对象方法吗?答案不能