首页 > 编程语言 >[Python学习日记-65] 抽象类

[Python学习日记-65] 抽象类

时间:2024-11-10 23:44:28浏览次数:6  
标签:Python self 接口 eat 65 抽象类 public def

[Python学习日记-65] 抽象类

简介

接口与归一化设计

抽象类

简介

        抽象类是由继承演变而来的,他可以很好的规范子类当中的统一函数属性,在不同的语言当中也会有类似的用法,下面我们会先讲讲什么是接口与归一化设计,然后再介绍什么是抽象类,我们在 Python 当中应该如何使用抽象类来帮助我们规范化子类的开发。

接口与归一化设计

一、什么是接口

        接口是一个定义了一组方法的抽象类型,这些方法在接口中声明但没有具体实现。接口可以被其他类实现,实现类必须提供接口中定义的所有方法。接口可以用来定义一些规范或约束,让不同的类实现相同的行为。

        在开发过程中可能你会听到你的同事会经常说给他开个什么什么接口之类的话语,例如开个查询接口之类的,此时的接口指的就是自己提供给使用者来调用自己功能的方式\方法\入
口,在 java 中的 interface 就是如此,它是这样使用的

==========第一部分:Java 语言中的接口很好的展现了接口的含义:IAnimal.java
/*
* Java 的 Interface 接口的特征:
* 1)是一组功能的集合,而不是一个功能
* 2)接口的功能用于交互,所有的功能都是 public,即别的对象可操作
* 3)接口只定义函数,但不涉及函数实现
* 4)这些功能是相关的,都是动物相关的功能,但光合作用就不适置放到 IAnimal 里面了 */

package com.oo.demo;
public interface IAnimal{
    public void eat();
    public void run();
    public void sleep();
    public void speak();
}

==========第二部分:Pig.java “猪”的类设计,实现了 IAnimal 接口
package com.oo.demo;
public class Pig implements IAnimal{    // 如下每个函数都需要详细实现
    public void eat(){
        System.out.println("Pig like to eat grass");
    }

    public void run(){
        System.out.println("Pig run: front leg, back leg");
    }

    public void sleep(){
        System.out.println("Pig sleep 16 hours every day");
    }

    public void speak(){
        System.out.println("Pig can't speak");
    }
}

==========第三部分:Person.java
/*
* 实现了 IAnimal 的“人”,有几点说明一下:
* 1)同样都实现了 IAnimal 的接口,但“人”和“猪”的实现不一样,为了避免太多代码导致影响问读,这里的代码简化成一行,但输出的内容不一样的
* 2)这里同样是“人”这个类,但和前面介绍类时定义的“人”的类完全不一样,这是因为同样的逻辑概念,在不同的应用场景下,具备的属性和功能是完全不同的*/

package com.oo.demo;
public class Person implements IAnimal{
    public void eat(){
        System.out.println("Person like to eat meat");
    }

    public void run(){
        System.out.println("Person run: left leg, right leg");
    }

    public void sleep(){
        System.out.println("Person sleep 8 hours every day");
    }

    public void speak(){
        System.out.println("Hello world, I am a person");
    }
}

==========第四部分:Tester.java
package com.oo.demo;
public class Tester{
    public static void main(String[] args){
        System.out.println("===This is a person===");
        IAnimal person = new Person();
        person.eat();
        person.run();
        person.sleep();
        person.speak();

        System.out.println("\n===This is a pig===");
        IAnimal pig = new Pig();
        pig.eat():
        pig.run();
        pig.sleep();
        pig.speak():
    }
}

        以上就是 java 中的接口。 

二、为什么要用接口

        接口提取了一群类共同的函数,可以把接口当做一个函数的集合,然后让子类去实现接口中的函数。这么做的意义在于归一化,什么叫归一化呢?归一化就是只要是基于同一个接口实现的类,那么所有的这些类产生的对象在使用时,从用法上来说都一样。归一化的好处如下:

  1. 归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度
  2. 归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合
    • 就好象 linux 的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者而言,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计,至于细致到什么程度,要视需求而定)
    • 再例如:我们有一个汽车接口,里面定义了汽车所有的功能,然后有本田汽车的类、奥迪汽车的类、大众汽车的类,他们都实现了汽车接口,这样就好办了,大家只需要学会了怎么开汽车,那么无论是本田、奥迪和大众我们都会开了,开的时候根本无需关心我开的是哪一类车,操作手法(函数调用)都一样

三、模仿 interface

        前面我们借 java 中的 interface 来说明了接口的概念,这是因为 Python 中根本就没有接口的概念,更不会有一个叫做 interface 的关键字,如果非要去模仿接口的概念,可以借助第三方模块:https://pypi.org/project/zope.interface/

        除了引入第三方模块我们也可以使用继承来达成这一效果,其实继承有两种用途:

  1. 继承父类(基类)的方法,并且做出自己的改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的。因为它使得子类与父类出现强耦合
  2. 声明某个子类兼容于某基类,定义一个接口类(模仿 java 的 interface),接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能,如下
class Interface:    # 定义接口 Interface 类来模仿接口的概念,Python 中压根就没有 interface 关键字来定义一个接口
    def read(self):    # 定接口函数 read
        pass

    def write(self):    # 定义接口函数 write
        pass


class Txt(Interface):    # 文本,具体实现 read 和 write
    def read(self):
        print("文本数据的读取方法")

    def write(self):
        print("文本数据的写入方法")


class Sata(Interface):    # 磁盘,具体实现 read 和 write
    def read(self):
        print("硬盘数据的读取方法")

    def write(self):
        print("硬盘数据的写入方法")


cLass Process(Interface):
    def read( self):
        print("进程数据的读取方法")

    def write(self):
        print("进程数据的写入方法")

        上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口,这就用到了抽象类。

抽象类

一、什么是抽象类

        与 java 一样,Python 也有抽象类的概念但是同样需要借助 abc 模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化。

二、为什么要有抽象类

        如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。例如我们有香蕉的类、苹果的类、桃子的类等,从这些类抽取相同的内容就是水果这个抽象的类,你在吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子之类的,而你永远无法吃到一个叫做水果的东西。

        从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

        从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,而且子类必须实现抽象类的方法,而这一点与接口有点类似,但其实并不相同。

三、如何实现抽象类

import abc    # 抽象类的模块 Python没有interface的关键字,需要引入模块abc来实现限制的功能

# 抽象类 统一化子类当中的方法名 metaclass=abc.ABCMeta是规定写法
# 抽象类是由继承演变而来的,实际上是做了子类归一化的功能,把所有的接口(函数名)都规范起来了,可以降低使用者的使用复杂度
class Animal(metaclass=abc.ABCMeta):    # 只能被继承,不能被实例化
    @abc.abstractmethod  # run = abc.abstractmethod(run)
    def run(self):
        pass

    @abc.abstractmethod
    def eat(self):
        pass


class People(Animal):    # 需要继承抽象类
    def run(self):
        print('People is walking')

    def eat(self):
        print('People is eating')


class Pig(Animal):
    def run(self):
        print('Pig is walking')

    def eat(self):
        print('Pig is eating')


class Dog(Animal):
    def run(self):
        print('Dog is walking')

    def eat(self):
        print('Dog is eating')


peo1 = People()
pig1 = Pig()
dog1 = Dog()

peo1.eat()
pig1.eat()
dog1.eat()

代码输出如下:

        如果我现在定义一个新的 Cat 类,不写抽象类中定义好的函数会如何呢?

class Cat(Animal):
    pass

cat1 = Cat()

代码输出如下:

        从输出可以看出会直接报错提示没有定义 eat 和 run 函数,那如果我们只定义其中一个函数会如何呢?

class Cat(Animal):
    def run(self):
        print('Cat is walking')

cat1 = Cat()

代码输出如下:

         可以看到只提示 eat 函数没有定义了,这样抽象类就规范了子类一定要包含抽象类当中强制要包含的几种函数了,从而达到归一化设计,最后还有一个点,抽象类到底能不能实例化,我们直接使用代码尝试一下,看一下是什么效果,如下

ani1 = Animal()

代码输出如下:

标签:Python,self,接口,eat,65,抽象类,public,def
From: https://blog.csdn.net/zjw529507929/article/details/143451622

相关文章

  • 大数据毕业设计:电影推荐系统 深度学习 协同过滤推荐算法 Python 爬虫 豆瓣电影 LSTM算
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业✌感兴趣的可以先收藏起来,点赞、关注不迷路✌1、毕业设计:2025年计算机专业毕业设计选题汇总(建议收藏)✅......
  • Python基于Flask的前程无忧招聘信息可视化系统【附源码,文档】
    博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w+、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......
  • Python 6
    目录Python61.求第n项的斐波那契数列值【源代码】2.青蛙跳楼梯,每一次只能跳一个台阶或者两个台阶,注意,不允许倒退如果第N个台阶,请问有多少种跳法:【源代码】3.小明高考结束,成绩非常理想,父母为了奖励他,为他买了一对刚刚出生的兔子刚刚出生的免子经过4个月成长为成年的兔子......
  • 深度学习电影推荐系统 协同过滤推荐算法 大数据毕业设计 Python 爬虫 豆瓣电影 LSTM算
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌>......
  • 基于Python电影票房数据分析可视化系统 Flask框架 豆瓣电影票房 MySQL数据库 大数据毕
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌>......
  • Python pandas库:强大的数据处理工具
        在Python的数据处理领域,pandas库无疑是一颗璀璨的明星。它为数据分析和处理提供了高效、便捷的方法。一、pandas简介    pandas是一个用于数据处理和分析的Python库,提供了数据结构Series和DataFrame,使得数据的操作和分析变得更加容易。二、主要数据结构......
  • Python捕获与处理异常
        在Python中,异常处理是一种重要的机制,用于处理程序运行时可能出现的错误情况。对程序的异常捕获与处理,可增强程序稳定性、可读性与可维护性,实现优雅的错误恢复。一、异常的概念    异常是程序在运行过程中发生的错误或意外情况。当出现异常时,程序的正常执行......
  • Python:条件分支 if 语句全讲解
    如果我拿出下面的代码,阁下该做何应对?ifnotreset_excutedand(terminatedortruncated):...else:...前言:消化论文代码的时候看到这个东西直接大脑冻结,没想过会在这么基础的东西上犯难运算符优先级在Python中,布尔运算符的优先级从高到低的顺序如下:括号():最高优先级,......
  • Python 实现微博舆情分析的设计与实现
    引言随着互联网的发展,社交媒体平台如微博已经成为公众表达意见、分享信息的重要渠道。微博舆情分析旨在通过大数据技术和自然语言处理技术,对微博上的海量信息进行情感分析、热点挖掘和趋势预测,为政府、企业和研究机构提供决策支持。本文将详细介绍如何使用Python实现微博舆情分......
  • 带参数的 Python 装饰器让你的代码更优雅
    引言在上一篇文章中,我们介绍了Python装饰器的基本概念及其简单用法。前面讲到的装饰器都是不带参数的装饰器,在需要对装饰器做一些针对性的处理的时候就不太适用了,这个时候需要对装饰器传入一些参数,根据传入的参数进行不同的处理。带参数装饰器在实际开发中能够灵活地调整函数......