类的三大特性(继承, 封装, 多态)

Posted zjaiccn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类的三大特性(继承, 封装, 多态)相关的知识,希望对你有一定的参考价值。

类的三大特性之继承

class Animals:
    a_type = "哺乳动物"
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("%s is eating ...."%self.name)


class Person(Animals):
    a_type = "高级动物"
    def talk(self):
        print("person %s is talking..."%self.name)
    def eat(self):
        print("person %s is eat zaofan"%self.name)

class Pig(Animals):
    def chase_rabbit(self):
        print("pig %s chase rabbit..."%self.name)


p = Person("Alex",22,"Man")
p.talk()
p.eat()
print(p.a_type)

pig = Pig("jack",2,"pig")
pig.chase_rabbit()
print(pig.a_type)

重写父类方法  - 单继承

# -*- coding:utf-8 -*-
class Animals:
    a_type = "哺乳动物"

    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("%s is eating ...."%self.name)


class Person(Animals):
    a_type = "高级动物"

    def __init__(self,name,age,sex,hobbie):
        #Animals.__init__(self,name,age,sex)
        #super(Person,self).__init__(name,age,sex)
        super().__init__(name,age,sex)
        self.hobbie = hobbie

    def talk(self):
        print("person %s is talking..."%self.name)

    def eat(self):
        super().eat()   #super继承执行父类的方法
        print("person %s is eat zaofan"%self.name)


class Pig(Animals):
    def chase_rabbit(self):
        print("pig %s chase rabbit..."%self.name)


p = Person("Alex",22,"Man","read book")
p.talk()
p.eat()
print(p.a_type,p.hobbie)

类的多继承

按顺序从左到右继承

继承顺序分为两种:这是简单的理解,深度理解完全不是这样的 

深度优先:先找M -MB - S -SB

广度优先: 一层一层的找 先M -S - MB -SB

 

实际上在python3上类的多继承的情况下,使用的是C3算法,既不能说是广度也不能说是深度

 

Python 中,类有两种写法: 在python 3上默认就是新式类

Class A:   #经典类

Class B(object):  #新式类

 

C3算法十分复杂,所以有兴趣去了解 

如果想要简单快速的查看一个类的继承方式可以使用:

Print(类名.mro())

# -*- coding:utf-8 -*-
class ShenXianBase:
    def fight(self):
        print("元祖在打架")


class ShenXian(ShenXianBase):

    def fly(self):
        print("shenxian is fly")

    def fight(self):
        print("神仙在打架")


class MonkeyBase:
    def fight(self):
        print("猿猴在打击")


class Monkey(MonkeyBase):

    def eat_peach(self):
        print("monkey like eat taozi ")

    def fight(self):
        print("猴子在打击")

class Monkeyking(ShenXian,Monkey):

    def play_goden_stick(self):
        print("sun wu kong play jinjubang")


sxz = Monkeyking()
sxz.eat_peach()

sxz.fly()
sxz.play_goden_stick()
sxz.fight()
print(Monkeyking.mro())

类的三大特性之--封装  :私有变量都是加两个下划线__

self.__name 将变量变成私有的  

方法也可以变成私有的 

def __sayhi():

# -*- coding:utf-8 -*-
class Person(object):
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    def __get_name(self):
        print("name is %s"%self.__name)


p = Person("Alex",22)
print(p._Person__name)  #强行访问私有变量
p._Person__name = "jack"   #强行修改私有变量

p._Person__get_name()   #强行访问私有方法

类的三大特性之- 多态

有时一个对象会有多种表现形式,比如网站页面有button按钮,可以有正方形的圆的,方的,但是他们有一个共同的调用方法onClick()

 

# -*- coding:utf-8 -*-
#多态
class Dog(object):

    def sound(self):
        print("wang wang wang ...")


class Pig(object):

    def sound(self):
        print("heng heng heng ...")


def animals_sound(obj1):
        obj1.sound()


d = Dog()
p = Pig()

animals_sound(d)
animals_sound(p)

 

# -*- coding:utf-8 -*-
#多态2
class Documents(object):
    def __init__(self,name):
        self.name = name

    def show(self):
        raise NotImplementedError("Subclass must implement abs")


class Pdf(Documents):
    def show(self):
        return "show pdf contents"


class Word(Documents):
    def show(self):
        return "show Word contents"


pdf = Pdf("xixixi.pdf")
word = Word("yyy.word")
obj = [pdf,word]
for o in obj:
    print(o.show())   # 这个show方法就是接口上边的pdf,word就是形态

  

 

类方法,静态方法:

类方法:

类方法通过@classmethod装饰器来装饰一下即只能访问类的变量,不能访问实例变量

# -*- coding:utf-8 -*-
class Dog(object):

    name = ‘gouzi‘

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

    @classmethod
    def eat(self):
        print("dog %s  is eating ...."%self.name)


d = Dog("mjj")
d.eat()

为什么不能访问实例变量,因为传进来的值不是实例本身,而是类本身,加上classmethod方法就会变成这样,去掉classmethod,传进来的就是实例本身了.

作用:

# -*- coding:utf-8 -*-
class Stu(object):

    __stu_num = 0

    def __init__(self,name):
        self.name = name
        self.add_stu(self)

    @classmethod
    def add_stu(cls,obj):
        if obj.name:
            cls.__stu_num += 1
            print("生成一个新学生",cls.__stu_num)

s = Stu(‘j‘) s2 = Stu(‘k‘) s3 = Stu(‘o‘)
s4 = Stu(‘5‘)

  

静态方法:

staticmethod 既不能访问实例变量,又不能访问类变量

静态方法割断了他和类或实例的任何关系

 

属性方法property

把一个方法变成一个静态的属性

class Stu(object):

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

    @property
    def fly(self):
        print("jack is flying")

s = Stu(‘rain‘)
s.fly    #不需要加括号了,调用这个方法

神奇的反射:

可以通过字符串的形式来操作对象的属性

Getattr 获取

Hsaattr 查询

Setattr 赋值

Delattr 删除

 

如何反射一个文件下指定的对应的属性

__name__    在当前文件主动执行的情况下(不是被导入执行),__name__ 就等于 __main__

在被其他文件当模块执行的时候,就等于这个文件(模块)名

# -*- coding:utf-8 -*-
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def drink(self):
        print("drink water ...")

def talk(self):
    print("talking...")

p = Person(‘alex‘,22)
#查询
if hasattr(p,"name"):
    print("11111")

user_command = input(‘>>‘).strip()
if hasattr(p,user_command):
    fun = getattr(p,user_command)
    fun()


#获取
a = getattr(p,"age")
print(a)

#修改,增加
setattr(p,"sex","Man")
print(getattr(p,‘sex‘))

setattr(Person,"speak",talk)
p.speak()

#删除
delattr(p,"age")


if __name__ == "__main__":  #只会被在别的模块导入的时候发挥作用
    print(‘jaja‘)

  



#动态获取当前模块下的属性

import sys
mod = sys.modules["__main__"]
if hasattr(mod,"p"):
    o = getattr(mod,"p")
    print(o.drink)

动态加载模块

# -*- coding:utf-8 -*-
#动态加载模块   ,热加载,在程序运行中,加入一个模块


#__import__("Property") #解释器用的
import importlib
importlib.import_module("Property")   #python官方推荐使用的  和上边的效果是一样的

importlib.import_module("function_def.List_builder")

反射的再应用:

#-*- coding:utf-8 -*-
class User(object):
        def __init__(self):
            print("welcome to yingxionglianmeng")

        def login(self):
            print("login...")

        def register(self):
            print("zhucejianmian...")

        def disk(self):
            print("welcome to save disk")

u = User()
while True:
    user_cmd = input(">>").strip()
    if hasattr(u,user_cmd):
        getattr(u,user_cmd)()

以上是关于类的三大特性(继承, 封装, 多态)的主要内容,如果未能解决你的问题,请参考以下文章

类的三大特性(继承, 封装, 多态)

Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)

C++的三大特性封装继承和多态

java三大特性封装继承多态

Python学习之旅---多态(类的相关知识,面向对象三大特性:继承-多态-封装)

(09)-Python3之--类的三大特性(封装继承多态)