面向对象进阶

面向对象——多态

什么是多态?

多态是同一种事物不同的形态

多态的目的?

多态也称为多态性,目的是为了在不知道对象具体类型的情况下,统一对象调用方法的规范(例如:名字)

多态的表现形式之一就是继承

​ 先抽象,再继承

父类:定制一套统一的规范

子类:遵循父类的统一规范

PS:Python中不会强制限制子类必须遵循父类的规范,所以出现了抽象类

# 动物类(父类)
class Animal:
    # 方法 吃
    def eat(self):
        pass

    # 方法 叫
    def spkea(self):
        pass


# 猪类(子类)
class Pig(Animal):
    def eat(self):
        print("bia唧....")

    def spkea(self):
        print("哼哼哼....")


# 猫类(子类)
class Cat(Animal):
    def eat(self):
        print("咬ji 咬ji....")

    def spkea(self):
        print("喵喵喵....")


# 狗类(子类)
class Dog(Animal):
    def eat(self):
        print("舔ji 舔ji....")

    def spkea(self):
        print("汪汪汪....")


animal1 = Pig()
animal2 = Cat()
animal3 = Dog()

# 让动物们叫起来
animal1.spkea()
animal2.spkea()
animal3.spkea()

多态——抽象类

什么是抽象类?

抽象类是在Python内置的abc模块中的

抽象类的作用?

让子类必须遵循父类编写的规范

如何实现抽象类?

父类需要继承abc模块中,metaclass = abc.ABCMeta

然后在父类的方法中要装饰上abc.abstractmethod

PS:在Python中不推荐使用抽象类

PS:子类必须按照父类的方法编写规范,缺一不可。(只要父类中有几个抽象方法,子类就必须要定义几个)

import abc


# 父类
class Animal(metaclass=abc.ABCMeta):
    # 方法  吃
    @abc.abstractmethod
    def eat(self):
        pass

    # 方法  叫
    @abc.abstractmethod
    def speak(self):
        pass


# 猪类
class Pig(Animal):
    def run(self):
        pass

    def eat(self):
        print("吧唧吧唧....")

    def speak(self):
        print("哼哼哼....")

多态——鸭子类型

什么是鸭子类型?

鸭子类型就是不同对象,只要长得像鸭子,动作行为像鸭子,那他就是鸭子

类与类之间不用共同继承一个父类,只需要将它们做得像一种事物即可。

为什么要有鸭子类型?

不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范

所有的类,在定义时都按照统一的规范进进行编写

在Python中强烈推荐使用鸭子类型

# 猪类
class Pig:
    def eat(self):
        print('bia唧...')

    def speak(self):
        print('哼哼哼...')


# 猫类
class Cat:
    def eat(self):
        print('咬ji 咬ji....')

    def speak(self):
        print('喵喵喵...')


# 狗类
class Dog:
    def eat(self):
        print('舔 ji 舔ji...')

    def speak(self):
        print('汪汪汪...')


def SPRAK(animal):
    animal.eat()
    animal.speak()


dog = Dog()
cat = Cat()
pig = Pig()


SPRAK(dog)
SPRAK(cat)
SPRAK(pig)

classmethod与staticmethod装饰器

classmethod与staticmethod都是Python内置的装饰器

classmethod

classmethod是一个装饰器,给在类内部定义的方法装饰,将类内部的方法变为“类的绑定方法”

类的绑定方法:由类来调用,会将谁(类)当做第一个参数传入

staticmethod

classmethod是一个装饰器,给在类内部定义的方法装饰,将类内部的方法变为“非绑定方法”

非绑定方法:可由对象或类来调用,谁来调用都是一个普通方式

# classmethod例子
class DB:
    __date = "kang is very handsome!"

    def __init__(self, user, pwd, role):
        self.user = user
        self.pwd = pwd
        self.role = role

    @classmethod
    def check_db(cls, user, pwd, role):
        obj = cls(user, pwd, role)
        if obj.user == "kang" and obj.pwd == "123" and obj.role == "admin":
            print("检验通过")
            print(cls.__date)
            return cls.__date


# DB.check_db("kang", "123", "admin")
db_obj = DB("kang", "123", "admin")
db_obj.check_db("kang", "123", "admin")


# staticmethod例子
class Foo:
    @staticmethod
    def func(res):
        print(res)


obj = Foo()

obj.func(123)

Foo.func(1234)

isinstance与issubclass

这两个都是Python的内置模块

isinstance:判断对象是否是另一个类的实例

issubclass:判断一个类是否是另一个类的子类

返回的都是True和False

# isinstance:判断一个对象是否是另一个对象的实例
class Foo:
    pass


class Boo:
    pass


foo_obj = Foo()
boo_obj = Boo()

print(isinstance(boo_obj, Boo))     # True
print(isinstance(foo_obj, Foo))     # True
print(isinstance(boo_obj, Foo))     # False


# issubclass:判断一个类是否是另一个类的子类
class Father:
    pass


class Sub(Father):
    pass


class Joo:
    pass


print(issubclass(Sub, Father))      # True
print(issubclass(Joo, Father))      # False

面向对象高级——反射

反射是通过“字符串”对 对象属性或方法进行操作

  • hasatter:通过字符串判断对象的属性或方法是否存在
  • getattr:通过字符串获取对象的属性或方法,找到返回值,找不到报错(如果设置了默认值就返回默认值)
  • setattr:通过字符串设置对象的属性或方法
  • delattr:通过字符串删除对象的属性或方法

反射的四个方法是Python内置的

class Foo:
    def __init__(self, x, y):
        self.x = x
        self.y = y


foo_obj = Foo(10, 20)


# hasatter:通过字符串判断对象的属性或方法是否存在
print(hasattr(foo_obj, "x"))        # True
print(hasattr(foo_obj, "y"))        # True
print(hasattr(foo_obj, "z"))        # False


# getattr:通过字符串获取对象的属性或方法
print(getattr(foo_obj, "x"))        # 10
print(getattr(foo_obj, "y"))        # 20
print(getattr(foo_obj, "z", 30))    # 30


# setattr:通过字符串设置对象的属性或方法
print(setattr(foo_obj, "z", 30))
print(hasattr(foo_obj, "z"))        # True


# delatter:通过字符串删除对象的属性或方法
delattr(foo_obj, "x")
print(hasattr(foo_obj, "x"))

反射的扩展例子

# 反射应用:
class FileControl:

    def run(self):
        while True:
            # 让用户输入上传或下载功能的命令
            user_input = input("请输入  上传(upload)或  下载(download)功能:").strip()
            # 通过用户输入的字符串判断方法是否存在,然后调用相应的方法
            if hasattr(self, user_input):
                func = getattr(self, user_input)
                func()

            else:
                print("输入有误")

    def upload(self):
        print("文件正在上传....")

    def download(self):
        print("文件正在下载....")


file_control_obj = FileControl()
file_control_obj.run()
posted @ 2019-11-28 20:00  小小小小小小小小小白  阅读(175)  评论(0编辑  收藏  举报