导航:首页 > 知识科普 > 怎么实现抽象方法的注释

怎么实现抽象方法的注释

发布时间:2022-12-30 21:28:15

如何使用静态方法,类方法或者抽象方法

方法是作为类的属性(attribute)存储的函数。你可以以下面的方式声明和获取函数:
>>> class Pizza(object):
... def __init__(self, size):
... self.size = size
... def get_size(self):
... return self.size
...
>>> Pizza.get_size
<unbound method Pizza.get_size>
Python告诉你的是,类Pizza的属性get_size是一个非绑定的方法。这又指什么呢?很快我们就会知道,试着调用一下:
>>> Pizza.get_size()
Traceback (most recent call last):
File "<stdin>", line 1, in <mole>
TypeError: unbound method get_size() must be called with Pizza instance as first argument (got nothing instead)
这里我们不能调用这个方法是因为它没有被绑定到任一Pizza的实例上。一个方法需要一个实例作为它第一个参数(在Python 2中它必须是对应类的实例;在Python 3中可以是任何东西)。我们现在试试:
>>> Pizza.get_size(Pizza(42))
42
现在可以了!我们试用一个实例作为get_size方法的第一个参数调用了它,所以一切变得很美好。但是你很快会同意,这并不是一个很漂亮的调用方法的方式;因为每次我们想调用这个方法都必须使用到类。并且,如果我们不知道对象是哪个类的实例,这种方式就不方便了。
所以,Python为我们准备的是,它将类Pizza的所有的方法绑定到此类的任何实例上。这意味着类Pizza的任意实例的属性get_size是一个已绑定的方法:第一个参数是实例本身的方法。
>>> Pizza(42).get_size
<bound method Pizza.get_size of <__main__.Pizza object at 0x10314b310>>
>>> Pizza(42).get_size()
42
如我们预期,现在不需要提供任何参数给get_size,因为它已经被绑定(bound),它的self参数是自动地设为Pizza类的实例。下面是一个更好的证明:
>>> m = Pizza(42).get_size
>>> m
<bound method Pizza.get_size of <__main__.Pizza object at 0x10314b350>>
>>> m()
42
因此,你甚至不要保存一个对Pizza对象的饮用。它的方法已经被绑定在对象上,所以这个方法已经足够。
但是如何知道已绑定的方法被绑定在哪个对象上?技巧如下:
>>> m = Pizza(42).get_size
>>> m.__self__
<__main__.Pizza object at 0x10314b390>
>>> m == m.__self__.get_size
True
易见,我们仍然保存着一个对对象的引用,当需要知道时也可以找到。
在Python 3中,归属于一个类的函数不再被看成未绑定方法(unbound method),但是作为一个简单的函数,如果要求可以绑定在对象上。所以,在Python 3中原理是一样的,模型被简化了。
>>> class Pizza(object):
... def __init__(self, size):
... self.size = size
... def get_size(self):
... return self.size
...
>>> Pizza.get_size
<function Pizza.get_size at 0x7f307f984dd0>
静态方法

静态方法是一类特殊的方法。有时,我们需要写属于一个类的方法,但是不需要用到对象本身。例如:
class Pizza(object):
@staticmethod
def mix_ingredients(x, y):
return x + y

def cook(self):
return self.mix_ingredients(self.cheese, self.vegetables)
这里,将方法mix_ingredients作为一个非静态的方法也可以work,但是给它一个self的参数将没有任何作用。这儿的decorator@staticmethod带来一些特别的东西:
>>> Pizza().cook is Pizza().cook
False
>>> Pizza().mix_ingredients is Pizza().mix_ingredients
True
>>> Pizza().mix_ingredients is Pizza.mix_ingredients
True
>>> Pizza()
<__main__.Pizza object at 0x10314b410>
>>> Pizza()
<__main__.Pizza object at 0x10314b510>
>>>

Python不需要对每个实例化的Pizza对象实例化一个绑定的方法。绑定的方法同样是对象,创建它们需要付出代价。这里的静态方法避免了这样的情况:

降低了阅读代码的难度:看到@staticmethod便知道这个方法不依赖与对象本身的状态;

允许我们在子类中重载mix_ingredients方法。如果我们使用在模块最顶层定义的函数mix_ingredients,一个继承自Pizza的类若不重载cook,可能不可以改变混合成份(mix_ingredients)的方式。

类方法

什么是类方法?类方法是绑定在类而非对象上的方法!
>>> class Pizza(object):
... radius = 42
... @classmethod
... def get_radius(cls):
... return cls.radius
...
>>> Pizza.get_radius
<bound method type.get_radius of <class '__main__.Pizza'>>
>>> Pizza().get_radius
<bound method type.get_radius of <class '__main__.Pizza'>>
>>> Pizza.get_radius is Pizza().get_radius
False
>>> Pizza.get_radius()
42
此处有问题。原文中
>>> Pizza.get_radius is Pizza().get_radius
True
还需要check一下。

不管你如何使用这个方法,它总会被绑定在其归属的类上,同时它第一个参数是类本身(记住:类同样是对象)
何时使用这种方法?类方法一般用于下面两种:
1. 工厂方法,被用来创建一个类的实例,完成一些预处理工作。如果我们使用一个@staticmethod静态方法,我们可能需要在函数中硬编码Pizza类的名称,使得任何继承自Pizza类的类不能使用我们的工厂用作自己的目的。
class Pizza(object):
def __init__(self, ingredients):
self.ingredients = ingredients

@classmethod
def from_fridge(cls, fridge):
return cls(fridge.get_cheese() + fridge.get_vegetables())

静态方法调静态方法:如果你将一个静态方法分解为几个静态方法,你不需要硬编码类名但可以使用类方法。使用这种方式来声明我们的方法,Pizza这个名字不需要直接被引用,并且继承和方法重载将会完美运作。

class Pizza(object):
def __init__(self, radius, height):
self.radius = radius
self.height = height

@staticmethod
def compute_circumference(radius):
return math.pi * (radius ** 2)

@classmethod
def compute_volume(cls, height, radius):
return height * cls.compute_circumference(radius)

def get_volume(self):
return self.compute_volume(self.height, self.radius)

抽象方法

抽象方法在一个基类中定义,但是可能不会有任何的实现。在Java中,这被描述为一个接口的方法。
所以Python中最简单的抽象方法是:

class Pizza(object):
def get_radius(self):
raise NotImplementedError

任何继承自Pizza的类将实现和重载get_radius方法,否则会出现异常。这种独特的实现抽象方法的方式也有其缺点。如果你写一个继承自Pizza的类,忘记实现get_radius,错误将会在你使用这个方法的时候才会出现。

>>> Pizza()
<__main__.Pizza object at 0x106f381d0>
>>> Pizza().get_radius()
Traceback (most recent call last):
File "<stdin>", line 1, in <mole>
File "<stdin>", line 3, in get_radius
NotImplementedError

有种提前引起错误发生的方法,那就是当对象被实例化时,使用Python提供的abc模块。

import abc
class BasePizza(object):
__metaclass__ = abc.ABCMeta

@abc.abstractmethod
def get_radius(self):
"""Method that should do something."""

使用abc和它的特类,一旦你试着实例化BasePizza或者其他继承自它的类,就会得到TypeError

>>> BasePizza()
Traceback (most recent call last):
File "<stdin>", line 1, in <mole>
TypeError: Can't instantiate abstract class BasePizza with abstract methods get_radius

混合静态方法、类方法和抽象方法

当我们构建类和继承关系时,终将会碰到要混合这些方法decorator的情况。下面提几个tip。
记住声明一个类为抽象类时,不要冷冻那个方法的prototype。这是指这个方法必须被实现,不过是可以使用任何参数列表来实现。

import abc
class BasePizza(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def get_ingredients(self):
"""Returns the ingredient list."""
class Calzone(BasePizza):
def get_ingredients(self, with_egg=False):
egg = Egg() if with_egg else None
return self.ingredients + egg

这个是合法的,因为Calzone完成了为BasePizza类对象定义的接口需求。就是说,我们可以把它当作一个类方法或者静态方法来实现,例如:

import abc
class BasePizza(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def get_ingredients(self):
"""Returns the ingredient list."""

class DietPizza(BasePizza):
@staticmethod
def get_ingredients():
return None

这样做同样争取,并且完成了与BasePizza抽象类达成一致的需求。get_ingredients方法不需要知道对象,这是实现的细节,而非完成需求的评价指标。
因此,你不能强迫抽象方法的实现是正常的方法、类方法或者静态方法,并且可以这样说,你不能。从Python 3开始(这就不会像在Python 2中那样work了,见issue5867),现在可以在@abstractmethod之上使用@staticmethod和@classmethod了。

import abc
class BasePizza(object):
__metaclass__ = abc.ABCMeta

ingredient = ['cheese']

@classmethod
@abc.abstractmethod
def get_ingredients(cls):
"""Returns the ingredient list."""
return cls.ingredients

不要误解:如果你认为这是强迫你的子类将get_ingredients实现为一个类方法,那就错了。这个是表示你实现的get_ingredients在BasePizza类中是类方法而已。
在一个抽象方法的实现?是的!在Python中,对比与Java接口,你可以在抽象方法中写代码,并且使用super()调用:

import abc
class BasePizza(object):
__metaclass__ = abc.ABCMeta
default_ingredients = ['cheese']
@classmethod
@abc.abstractmethod
def get_ingredients(cls):
"""Returns the ingredient list."""
return cls.default_ingredients
class DietPizza(BasePizza):
def get_ingredients(self):
return ['egg'] + super(DietPizza, self).get_ingredients()

文/Not_GOD(简书作者)
原文链接:http://www.jianshu.com/p/880d6a3ffdde
着作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

⑵ JAVA中,什么是抽象类抽象类中是否一定包还抽象方法~

java中用abstract声明的类就叫做抽象类,抽象类中抽象方法可有可无,但通常都含有抽象方法(这是定义抽象类的目的所在)让子类继承,如果子类没有把抽象类中所有的抽象方法都重写,则这个继承了抽象类的子类也会成为抽象类;如果子类把抽象类中所有的抽象方法都重写,则这个子类就可以实例化了。

⑶ java抽象类能不能加注解方式

抽象类是用来捕捉子类的通用特性的,是被用来创建继承层级里子类的模板。现实中有些父类中的方法确实没有必要写,因为各个子类中的这个方法肯定会有不同;而写成抽象类,这样看代码

php中什么是抽象方法和抽象类2020-07-29
抽象方法是指在类中定义的没有方法体的方法。如果一个类中有一个方法是抽象方法,那么这个类就是抽象类,抽象类中可以包含非抽象方法。在声明抽象方法和抽象类时,需要使用abstra

抽象类和接口有什么异同点2020-08-13
抽象类和接口的区别:(推荐教程:java入门教程)抽象类中既可以包含抽象方法,也可以包含非抽象的普通方法;而接口中的方法必须是抽象方法。抽象类中的抽象方法的访问类型可以是public

php中抽象类和接口有哪些不同点2020-11-05
php中抽象类和接口的不同点有:1、抽象类可以有属性和普通方法,接口不能有属性和普通方法;2、抽象类中不一定有抽象方法,接口中一定有抽象方法;3、抽象类的抽象方法必须用abstract

抽象类与接口有什么联系2020-08-03
联系:(推荐教程:java入门教程)1、都可以拥有抽象方法2、都不可以直接创建对象3、都依靠于子类存在才有意义,子类必须实现其所有的抽象方法4、都可以实现多态区别:成员不同:接口中没

php抽象类和接口之间有什么区别?2020-07-16
本篇文章给大家介绍一下php抽象类和接口的区别。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。抽象类官方描述请查看文档,下面是官方描述的梳理版本:定义为

详解PHP中abstract(抽象)、final(最终)和static(静态)原理与用法2020-07-14
本文实例讲述了PHP中abstract(抽象)、final(最终)和static(静态)原理与用法。分享给大家供大家参考,具体如下:abstract(抽象)PHP 5 支持抽象类和抽象方法。定义为抽象的类不能

什么是java注解2020-08-05
注解和反射是Java中非常让人容易忽略的东西,但却很重要,在主流的Spring中更是充满了注解,注解和注释很像,两者其实本质就差不多,注释是给我们程序员看的,而注解呢其实就是给程序看

常见的Java注解有哪些2020-07-21
注解(Annotation)(推荐教程:java入门教程)从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是Annotation(注解)Annotation 其实就是代码里的特殊标记, 这些标记可

C# 中虚方法和抽象方法2020-07-23
今天在云和学院学了很多,我这次只能先总结一下C#中的虚方法和抽象的运用。理论:虚方法:用virtual修饰的方法叫做虚方法虚方法可以在子类中通过override关键字来重写常见的虚方

java代码编译顺序是什么2020-10-27
java代码编译顺序:首先源代码进入词法分析器,token流后进入语法分析器;然后进行抽象语法树后进行语义分析器;接着注解抽象语法树,并使用字节码生成器;最后生成jvm字节码。java代码

抽象数据类型有哪些2020-07-02
抽象数据类型是一种对“数据结构”的描述,这种描述是“抽象”的,描述内容有:1、数据对象集;2、与数据集合相关联的操作集。抽象数据类型抽象数据类型(Abstract Data Type)是一种

工厂模式和抽象工厂模式的区别?2020-07-28
工厂模式和抽象工厂模式的区别?1、工厂模式在使用时可以随时设置变量,不用提前进行设置,抽象工厂模式则需要每次增加产品时,进行修改类方法;2、工厂模式可以使用两个接口以及三个

实例介绍java中的Calendar类2020-07-23
日历类,它是一个抽象类,封装了所有的日历字段值,通过统一的方法根据传入不同的日历字段可以获取值。(推荐教程:java入门教程)1、得到一个日历对象Calendar c = Calendar.getInstan

java和php接口的区别是什么2020-09-01
java和php接口的区别是:1、php中在接口中的抽象方法只能是public的,默认也是public权限;2、java中私有方法使用private修饰,供接口中的默认方法或者静态方法调用。【相关学习推

⑷ java抽象方法

new一个实例再指向原先的抽象类,这个在JAVA当中叫做多态性。当一个子类的实例指向父抽象类的时候,那么父抽象类所定义的一个没有被实例化的对象就可以使用父抽象类当中所有的被子类实现的抽象方法,但是不可以使用子类新加入的方法。不知道你清楚了没有!

⑸ 如何在类中声明抽象方法并使他返回一个字符串

用abstract修饰,同时将返回值设置为string类型即可。
抽象类,抽象方法都可用abstract修饰,来表示其抽象的意思。返回值是字符串,字符串用string表示,所以讲返回值的类型设置为string就行。

⑹ C# 子类实现父类抽象方法 如何显示父类注释

继承是实现代码的重用而不是注释的重用,程序运行时,会把注释当成废话给过滤掉

⑺ php中如何给类规范的注释

需要准备的材料分别是:电脑、phpstrom编辑器。

1、首先,打开phpstrom编辑器,新建php文件,例如:index.php,定义一个函数示例。

⑻ java里的抽象方法是怎么定义的

1 用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。例如 :
abstract class Animal { //用abstract来定义一个Animal为抽象类
}

public abstract void enjoy(); //用abstract来定义一个抽象方法"enjoy"

⑼ 什么是抽象类和抽象方法

抽象类就是不能使用new方法进行实例化的类,即没有具体实例对象的类。抽象类有点类似“模板”的作用,目的是根据其格式来创建和修改新的类。对象不能由抽象类直接创建,只可以通过抽象类派生出新的子类,再由其子类来创建对象。当一个类被声明为抽象类时,要在这个类前面加上修饰符abstract。 在抽象类中的成员方法可以包括一般方法和抽象方法。抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。当一个方法为抽象方法时,意味着这个方法必须被子类的方法所重写,否则其子类的该方法仍然是abstract的,而这个子类也必须是抽象的,即声明为abstract。 抽象类中不一定包含抽象方法,但是包含抽象方法的类一定要被声明为抽象类。抽象类本身不具备实际的功能,只能用于派生其子类。抽象类中可以包含构造方法,但是构造方法不能被声明为抽象。 抽象类不能用final来修饰,即一个类不能既是最终类又是抽象类。 abstract不能与private、static、final、native并列修饰同一个方法。 程序举例:abstract class Animal //定义抽象类 abstract void eat(); //定义抽象方法}class Horse extends Animal //定义继承Animal的子类 void eat() //重写父类的抽象方法 }class Dog extends Animal void eat() }class test}运行结果: 马吃草料! 狗吃骨头!

⑽ java,实现抽象方法的方法

答案是肯定的。我看你是不太理解抽象方法。我来是说一下我的理解吧。也不知道对不对。你掂量掂量吧。呵呵。抽象方法是这样的。
抽象方法就是把子类要一定要实现的方法抽象出来。放到父类。继承父类的子类就一定得重写父类中的抽象方法。而非抽象方法不一定要重写。父类的抽象方法不是一定要继承。而是一定要重写。重写就覆盖了父类的相应的方法(实际是隐藏,说覆盖形象点).子类可以使用父类的非私有方法和非私有变量。

阅读全文

与怎么实现抽象方法的注释相关的资料

热点内容
高压电路测量方法 浏览:827
挖雪洞的方法视频 浏览:162
烧疹子怎么治疗方法 浏览:182
建筑防火胶检测方法 浏览:266
往复泵通常用的方法来调节流量 浏览:537
小腿酸沉怎么治疗方法 浏览:923
云南正规进口鲜炖燕窝的食用方法 浏览:977
悦翔v5倒车异响解决方法 浏览:489
森威m40使用方法 浏览:250
一套完整的手关节锻炼方法 浏览:551
海螺七种植方法 浏览:275
治疗手足癣有效的方法 浏览:486
洗衣机墙排管安装方法 浏览:979
手机截屏菜单键在哪里设置方法 浏览:680
网络性能分析方法 浏览:129
早期白癜风治疗最佳方法 浏览:342
卤鸭子的方法及步骤 浏览:77
最先进的土地测量方法 浏览:985
8个月宝宝退热贴的正确使用方法 浏览:288
膝盖疼的食物治疗方法 浏览:667