Python-保护,继承,多态

1.7. 保护、继承、多态

1.私有对象和属性:

  1. Python中没有像C++中public和private这些关键字来定义公有和私有属性方法
  2. 它是以属性命名的方法来区分,如果在属性名前面加上2个下滑线__表示表示这是私有属性,否则为公有属性,方法也是类似的

示例:

class Msg:
def __init__(self,money):
    # 私有属性
    self.__money=money
def getMoney(self):
    return self.__money
#私有方法
def __sendMsg(self):
    print("---正在发送短信--")
def sendMsg(self):
    if(self.getMoney()>100):
        self.__sendMsg()
    else:
        print("余额不足")

msg=Msg(1000)
print(msg.getMoney())
msg.sendMsg()

结果是:1000
---正在发送短信--

2.__del()__方法

创建对象后,python解释器默认调用init()方法;

当删除一个对象时,python解释器也会默认调用一个方法,这个方法为del()方法

  • 当有1个变量保存了对象的引用时,此对象的引用计数就会加1
  • 当使用del删除变量指向的对象时,如果对象的引用计数不为1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除

示例1,删除一个,留一个:

class Dog:
    def __del__(self):
        print("over")

dog=Dog()
dog1=dog
del dog
print("=======")

结果是:

=======
over

示例2,删除完:

class Dog:
    def __del__(self):
        print("over")

dog=Dog()
dog1=dog
del dog
del dog1
print("=======")

结果是:

over
=======

测量对象引用个数

需要引入sys模块,并用sys.getrefcount(对象),它所测出来的个数要比实际个数多一个,因为调用的时候传了参数,增加了一个。

import sys
class Dog:
    def __del__(self):
        print("over")

dog=Dog()
dog1=dog
print(sys.getrefcount(dog))
del dog
print(sys.getrefcount(dog1))
del dog1
print(sys.getrefcount(dog1))

结果是:

3
2
over
Traceback (most recent call last):
  File "/home/shushu/PycharmProjects/pylearn35/del方法.py", line 12, in <module>
    print(sys.getrefcount(dog1))
NameError: name 'dog1' is not defined

最后一行检测的时候已经没有了,所以会报错

3.继承

示例:

# 定义一个父类,如下:
class Cat(object):

    def __init__(self, name, color="白色"):
        self.name = name
        self.color = color

    def run(self):
        print("%s--在跑"%self.name)


# 定义一个子类,继承Cat类如下:
class Bosi(Cat):

    def setNewName(self, newName):
        self.name = newName

    def eat(self):
        print("%s--在吃"%self.name)


bs = Bosi("印度猫")
print('bs的名字为:%s'%bs.name)
print('bs的颜色为:%s'%bs.color)
bs.eat()
bs.setNewName('波斯')
bs.run()

结果是:

bs的名字为:印度猫
bs的颜色为:白色
印度猫--在吃
波斯--在跑
  • 子类可以会默认执行父类的__init__方法
  • 子类在继承的时候,在定义类的时候,小括号()为父类的名字
  • 父类的属性,和方法会继承给子类

注意
* 私有的属性,不能通过对象直接访问,但是可以通过方法访问
* 私有的方法,不能通过对象直接访问
* 私有的属性、方法,不会被子类继承,也不能被访问,只有父类提供了访问私有属性和方法的方法,子类通过该方法去访问私有属性和方法
* 一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用

重写

所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法

调用父类的方法:

class Cat(object):
    def sayHello(self):
        print("halou-----1")


class Bosi(Cat):

    def sayHello(self):
        print("halou-----2")
        #第一种调用父类的方法
        Cat.sayHello(self)
        #第二种调用父类的方法
        super().sayHello()

a=Bosi();
a.sayHello()

结果是:

halou-----2
halou-----1
halou-----1

4.多继承

多继承时,相同方法调用顺序可以通过对象.__mro__来查看

class base(object):
    def test(self):
        print('----base test----')
class A(base):
    def test(self):
        print('----A test----')

# 定义一个父类
class B(base):
    def test(self):
        print('----B test----')

# 定义一个子类,继承自A、B
class C(A,B):
    pass


obj_C = C()
obj_C.test()

print(C.__mro__) #可以查看C类的对象搜索方法时的先后顺序

结果是:

----A test----
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.base'>, <class 'object'>)

5.多态

class Dog(object):
    def print_self(self):
        print("Dog")

class Xiaotq(Dog):
    def print_self(self):
        print("Xiaotq")

def introduce(temp):
    temp.print_self()

dog=Dog()
xiaotq=Xiaotq()
introduce(dog)
introduce(xiaotq)

6.类属性、实例属性

class Dog(object):
    age=0
    __name="tom"

    def __init__(self,color):
       self.color=color
dog=Dog("白")
print(dog.age)
print(Dog.age)
# print(Dog.__name) 不能调用私有属性
print(dog.color)
print("---------------------")

dog.age=1#设置与类属性相同的属性
print(dog.age)#实例属性会屏蔽掉类的属性
print(Dog.age)#但原来类的属性值并不会发生改变
print("---------------------")

Dog.age=1#用类可以去修改类属性,类属性会发生改变
print(dog.age)
print(Dog.age)
print("---------------------")

del dog.age
print(dog.age)
print(Dog.age)

结果是:

0
0
白
---------------------
1
0
---------------------
1
1
---------------------
1
1

7.类方法、静态方法、

class Dog(object):
    age=0
    __name="tom"

    def __init__(self,color):
       self.color=color

    #类方法是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数
    @classmethod
    def addAge(cls):
        cls.age+=10

    #静态方法需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数
    @staticmethod
    def msg():
        print("+---------+")
        print("|   Dog   |")
        print("+---------+")

dog=Dog("白")
Dog.msg()
dog.msg()
print("------------------------")

dog.addAge()
print(dog.age)
print(Dog.age)
print("------------------------")

Dog.addAge()
print(dog.age)
print(Dog.age)

结果是:

+---------+
|   Dog   |
+---------+
+---------+
|   Dog   |
+---------+
------------------------
10
10
------------------------
20
20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值