精华内容
下载资源
问答
  • 抽象基类

    2019-10-08 02:10:05
    抽象基类不同于普通的父类。 普通父类,一般子类会直接继承。 抽象基类是在设计基类时就规定了子类如果继承该基类,必须实现的方法。 如果子类没有实现抽象基类实现的方法,那么子类在实例化的时候就会报错,提示...

    抽象基类不同于普通的父类。

    普通父类,一般子类会直接继承。

    抽象基类是在设计基类时就规定了子类如果继承该基类,必须实现的方法。

    如果子类没有实现抽象基类实现的方法,那么子类在实例化的时候就会报错,提示没有实现规定的方法。而不是在调用的时候再报错。

     

    具体例子:

    class Animal(object):
       def eat(self): raise NotImplementedError    def voice(self): raise NotImplementedError class Dog(Animal): def voice(self): print 'wow....' class Bird(Animal): def voice(self): print 'jiji....' class Cow(Animal): def voice(self): print 'Oh.....' if __name__ == "__main__": d=Dog() d.voice() d.Eat()

     最后三个类会实现voice方法,但是在调用traceback到eat方法的时候就会报错。很显然,这种直接继承的方法就是实现了实例化后,调用的时候才报错。

    而有的时候,我们需要的是,在实例化的时候就告诉我们报错。这个时候就需要这样使用抽象基类。

    抽象基类的使用方法:

     

     

    import abc
    class Animal(object):
        __metaclass__ = abc.ABCMeta
        @abc.abstractmethod
        def eat(self):
            return
        @abc.abstractmethod
        def voice(self):
            return 
    class Dog(Animal):
        def voice(self):
            print 'wow....

        def eat(self):
            print 'Dog eat....'

    class Bird(Animal):
        def voice(self):
            print 'jiji....'

    if __name__ == "__main__": d=Dog()
      c=Bird()

     

     使用了抽象基类的话,这个在实例化Bird类的时候,就会报错没有实现规定的eat方法。

    用抽象基本类的地方:
        1:用作父类
        2:用作检验实例类型
        3:用作抛出异常说明

     

        1:直接继承
            直接继承抽象基类的子类就没有这么灵活,抽象基类中可以声明”抽象方法“和“抽象属性”,只有完全覆写(实现)了抽象基类中的“抽象”内容后,才能被实例化,而虚拟子类则不受此影响。
        2:虚拟子类
        将其他的类”注册“到抽象基类下当虚拟子类(调用register方法),虚拟子类的好处是你实现的第三方子类不需要直接继承自基类,可以实现抽象基类中的部分API接口,也可以根本不实现,但是issubclass(), issubinstance()进行判断时仍然返回真值。
        Python 对于ABC的支持模块是abc模块,定义了一个特殊的metaclass:ABCMeta 还有一些装饰器:@abstractmethod 和 @abstarctproperty 。abc.ABCMeta 用于在Python程序中创建抽象基类。而抽象基类如果想要声明“抽象方法”,可以使用 @abstractmethod ,如果想声明“抽象属性”,可以使用 @abstractproperty 。

     

     



    转载于:https://www.cnblogs.com/shrimpPython/p/10677254.html

    展开全文
  • python 抽象基类

    2021-04-11 10:57:52
    python 抽象基类
  • // abstractbasepointerastemplatecontainerelement.cpp : Defines the entry point for the console application. // #include "stdafx.h" // 模板容器 template class vector ...// 抽象基类 clas
    // abstractclass.cpp : Defines the entry point for the console application.
    //
    
    
    #include "stdafx.h"
    #include <vector>
    using namespace std;
    
    
    class A
    {
    public:
    <span style="white-space:pre">	</span>virtual void f() = 0;
    };
    
    
    class B : public A
    {
    public:
    <span style="white-space:pre">	</span>void f()
    <span style="white-space:pre">	</span>{
    <span style="white-space:pre">	</span>}
    };
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    <span style="white-space:pre">	</span>vector<A *> vec(10);// 我们不可以声明抽象基类对象,但是可以声明抽象基类对象的指针
    <span style="white-space:pre">	</span>vec[0] = new B;
    <span style="white-space:pre">	</span>vec[0]->f();// 对抽象基类纯虚函数的调用,执行的是派生类的同名成员函数
    <span style="white-space:pre">	</span>delete vec[0];
    <span style="white-space:pre">	</span>return 0;
    }
    
    
    
    // abstractbasepointerastemplatecontainerelement.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    // 模板容器
    template <class T>
    class vector
    {
    public:
    	T m[10];
    };
    
    // 抽象基类
    class A
    {
    public:
    	virtual void f() = 0;
    };
    
    // 派生类
    class B : public A
    {
    public:
    	void f()
    	{
    	}
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	// 将抽象基类的指针作为模板容器的元素
    	vector<A *> vec;
    	// 动态创建派生类的对象,以抽象基类的指针指向
    	A *p = (A *)new B;
    	// 将指向派生类对象的抽象基类的指针入队
    	vec.m[0] = p;
    	// ...
    	// 将指向派生类对象的抽象基类的指针出队
    	A *q = vec.m[0];
    	// 此时,对抽象基类纯虚函数的调用,转为对派生类成员函数的调用
    	q->f();
    	// 动态释放派生类的对象
    	delete q;
    	return 0;
    }
    
    
    // remark i:变量都要初始化,指针尤其需要初始化,模板容器中的抽象基类指针也不例外:
    	vector<A *> vec(1);
    	vec[0] = NULL;
    
    // remark ii:因此,比如,对于一个带头结点的指针链表,要记得对其头结点进行初始化置为空。
    	LinkList()// 构造函数
    	{
    		m_head = new char *;
    		m_head->data = NULL;// 头结点
    		...
    	}
    
    // remark iii:但是,如果这个指针链表是一个以指针为元素的模板链表,那么初始化置空头结点的操作就不应该在模板链表的构造函数中进行,
    	LinkList()// 构造函数
    	{
    		m_head = new Node<T>;
    		memset(m_head->data, NULL, sizeof(T));// !不要在模板基类的构造函数中直接赋值元素!
    	}
    因为这样会一起置空其他的以具有自己构造函数的类为元素的类链表的头结点。例如一个初始时具有1个元素('\0')的字符串类:
    	String()// 构造函数
    	{
    		m_p = new char[1];
    		m_len = 1;
    		m_p[0] = '\0';//初始时具有1个元素('\0')
    	}
    以这种模板链表为模板,定义以字符串类为元素的字符串链表,那么链表头结点其成员m_len,m_p都将被值为0。
    
    // remark iv:正确的写法是,模板链表初始化时,对头结点多态地赋值一个模板类型的数据:
    	LinkList()// 构造函数
    	{
    		m_head = new Node<T>;
    		m_head->data = T();// 模板类型
    	}
    其中,模板类型的赋值操作其实在Node类的合成拷贝构造函数中已经隐含了。所以有一种更简洁的方法,就是省去模板类型显式赋值,使用new操作符,隐式地而且多态地调用模板类型的构造函数,对头结点进行初始化:
    	LinkList()// (推荐)构造函数
    	{
    		m_head = new Node<T>;
    	}
    此时如果定义一个字符串链表,头结点也能够具有1个元素('\0')。
    
    // remark v:但是,仍然需要注意,如果模板链表的模板类型是指针,因为指针本身是不会自动初始化的,所以需要记得在定义以指针为元素的模板链表时,对其头结点手动初始化,或者对模板链表继承后定义继承类构造函数对指针初始化。
    	LinkList<char *> linklist;
    	linklist.m_head->data = NULL;// 取头结点指针赋值为空
    

    展开全文
  • 主要介绍了python抽象基类用法,实例分析了Python抽象基类的使用方法与相关注意事项,需要的朋友可以参考下
  • C++ 抽象基类

    千次阅读 2018-08-20 17:50:49
    纯虚函数 纯虚函数是一个在基类中声明的虚函数,在基类没有定义,要求在任何派生类中都定义自己的版本; 纯虚函数为各派生类提供一个公共接口(接口的封装和设计、软件的模块功能划分);...抽象基类不...

    纯虚函数

    • 纯虚函数是一个在基类中声明的虚函数,在基类没有定义,要求在任何派生类中都定义自己的版本;
    • 纯虚函数为各派生类提供一个公共接口(接口的封装和设计、软件的模块功能划分);
    • 纯虚函数说明形式: virtual 函数类型 函数名(参数表) = 0;。

    抽象类

    • 抽象基类(ABC)为一个具有纯虚函数的基类(可有多个纯虚函数)。
    • 抽象基类不能建立对象;
    • 抽象基类不能作函数参数;
    • 抽象基类不能作函数返回类型;
    • 可以声明抽象基类的指针;
    • 可以声明抽象基类的引用。

    一个应用抽象基类编程的c++代码如下

    #include <iostream>
    
    //含有纯虚函数的基类为抽象基类
    //面向抽象类编程(面向一套预先定义好的接口编程)
    
    class Figure
    {
    public:
        virtual void GetArea() = 0;//纯虚函数
    };
    
    class Circle : public Figure
    {
    private:
        float m_r;
    public:
        Circle(float r) : m_r(r) {}
        virtual void GetArea()
        {
            std::cout << "圆的面积为:" << 3.14 * m_r * m_r << std::endl;
        }
    };
    
    class Triangle : public Figure
    {
    private:
        float m_a;
        float m_b;
    public:
        Triangle(float a, float b) : m_a(a), m_b(b) {}
        virtual void GetArea()
        {
            std::cout << "三角形的面积为:" << m_a * m_b / 2 << std::endl;
        }
    };
    
    void DisplayArea(Figure * p_figure)
    {
        p_figure->GetArea();//会发生多态
    }
    
    int main()
    {
        Circle Circle1(2.5);
        Triangle Triangle1(1.2, 3.6);
    
        DisplayArea(&Circle1);
        DisplayArea(&Triangle1);
    
        return 0;
    }
    展开全文
  • python抽象基类理解

    2020-03-12 20:19:02
    (what)什么是抽象基类抽象基类它提供了接口,但是又没有去把接口实现的类,需要由子类完成。感觉它就是老板,只告诉你要完成项目A, 你接到项目A后(继承),你自己去把它完成。 抽象基类特点: 1.继承类必须实现...

    (what)什么是抽象基类?

    抽象基类它提供了接口,但是又没有去把接口实现的类,需要由子类完成。感觉它就是老板,只告诉你要完成项目A, 你接到项目A后(继承),你自己去把它完成。
    抽象基类特点:
    1.继承类必须实现抽象基类的方法
    2.抽象基类无法实例化

    (why)为什么要有抽象基类这玩意?

    1.why 抽象基类?
    譬如要开发一个项目,你要规定项目开发者要去完成某些接口,有些接口会不会忘记实现了呢?你在担心…这时候抽象基类就帮上忙了,你可以给开发者提供抽象基类,因为它必须让继承它的子类去实现它所要求的方法(这个例子不知道牵强不?)。当然也有其他的优点:处理继承问题方面更加规范、系统,明确调用之间的相互关系,使得继承层次更加清晰。

    2.为什么抽象基类用collections.abc?
    假设我们要编写一种对象,本身虽然不属于list子类,但是却要让它可以像list那样子去访问。例如我们现在想让一颗二叉树可以像list那样子访问,那么我们要实现__geitem__(),要实现__len__(),这个还不完整,还要实现index, count方法,要实现那么多方法很复杂,用collections.abc模块的话,实现了抽象基类所要求的方法,模块会自动实现剩下的那些方法。

    (how)如何使用?

    我们一般都不会自己去定义抽象基类,而是使用collections.abc模块
    例如:

    import abc
    
    class A(abc.ABC):#自己定义一个抽象基类,
        @abc.abstractmethod
        def eat(self):
            pass
        
    class B(A):#继承抽象基类
        def voice(self):
            pass
            
    if __name__ == "__main__":
        a = A() 
    #报错,抽象类无法实现实例化
    #TypeError: Can't instantiate abstract class A with abstract methods eat
        a = B()
        a.eat()
    #报错,继承类必须实现抽象类的方法
    #TypeError: Can't instantiate abstract class B with abstract methods eat
    

    又如:

    from collections import abc
    
    class A(abc.Sequence): #继承抽象基类abc,Sequece
        def eat(self):
            pass
        
    class B(A):
        def __getitem__(self): #必须实现__getitem__()
            pass
        def __len__(self):  #必须实现__len__()
            pass
        def voice(self):
            pass
    if __name__ == "__main__":
        b = B()
    
    展开全文
  • 虚函数和抽象基类的应用。在上一题中介绍了以Point为基类的“点-圆-圆柱体”类的层次结构。现在要对它进行改写,在程序中使用虚函数和抽象基类。类的层次结构的顶层是抽象基类Shape(形状)。Point(点),Circle...
  • js 抽象基类

    2021-03-24 11:15:43
    1. 抽象基类 有时候可能需要定义这样一个类,它可供其他类继承,但本身不会被实例化。虽然 ECMAScript 没 有专门支持这种类的语法 ,但通过 new.target 也很容易实现。new.target 保存通过 new 关键字调用的类或...
  • Python之抽象基类

    2020-06-19 17:09:22
    1.抽象基类的定义 抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类, 纯虚函数只提供了接口,并没有具体实现。 2.抽象基类的特点 不能被实例化 抽象基类不能被实例化(不能创建对象)...
  • python抽象基类

    2019-06-10 18:08:09
    抽象基类不包含我们需要的所有方法,其他的类会将他当作基类来使用。 抽象基类为缺失的方法函数提供了签名,子类必须创建符合基类定义的接口。 抽象基类可以保证一组自定义类的一致性,可以用它创建一些通用、可重用...
  • C++抽象基类

    千次阅读 2019-04-26 22:53:04
    有时候我们需要表示一种抽象的概念,但是具体的实现方式可以有很多种,这个时候我们可以使用纯虚函数定义这种抽象概念,含有或未经覆盖直接继承纯虚函数的类时抽象基类抽象基类负责定义接口,我们不能直接创建一个...
  • 3.抽象基类

    2021-02-12 15:20:36
    抽象基类 python本身就是支持多态的语言。 python不是因为继承了某个类而又特定的特性,而是因为基类继承了某些魔法函数而具有了某些特性。 1)抽象基类是在基类中实现了一些抽象方法,继承该类的类都要覆盖这些...
  • 抽象基类有两个特点:规定继承类必须具有抽象基类指定的方法、抽象基类无法实例化。基于这两个特点,抽象基类主要用于接口设计。 使用模块abc可创建抽象基类。使用@abstractmethod来将方法标记为抽象的,即在子类中...
  • Python中的抽象基类

    千次阅读 2019-06-10 17:07:14
    Python中的抽象基类 abc —抽象基类 使用方法 import abc class A(abc.ABC): # 定义抽象方法 @abc.abstractmethod def a(self): pass class B(A): # 必须实现,否则运行报错 def a(self): pass 定义...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 173,804
精华内容 69,521
关键字:

抽象基类