Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop &引用;“抽象静态”;方法-如何?_Oop_Static Methods_Abstract Methods - Fatal编程技术网

Oop &引用;“抽象静态”;方法-如何?

Oop &引用;“抽象静态”;方法-如何?,oop,static-methods,abstract-methods,Oop,Static Methods,Abstract Methods,关于为什么不存在抽象的静态方法/字段,已经有几个这样的问题,但我想知道如何实现以下psuedo代码: class Animal { abstract static int getNumberOfLegs(); // not possible } class Chicken inherits Animal { static int getNumberOfLegs() { return 2; } class Dog inherits Animal { static in

关于为什么不存在抽象的静态方法/字段,已经有几个这样的问题,但我想知道如何实现以下psuedo代码:

class Animal {
    abstract static int getNumberOfLegs(); // not possible
}

class Chicken inherits Animal {
    static int getNumberOfLegs() { return 2; }


class Dog inherits Animal {
    static int getNumberOfLegs() { return 4; }
问题是:假设我希望确保继承
Animal
的每个类都包含
getNumberOfLegs()
方法(即,几乎像一个接口,除了我希望抽象类实现所有子类通用的几个方法之外,因此纯接口在这里不起作用)
getNumberOfLegs()
显然应该是一种静态方法(假设在一个完美的世界中,我们没有残废的鸡和狗,所以
getNumberOfLegs
不依赖于实例)

如果没有“抽象静态”方法/字段,则可以将该方法从
Animal
类中删除,这样就存在某些子类没有该方法的风险。或者你可以把
getNumberOfLegs
作为一个实例方法,但是你必须实例化一个类来找出这个动物有多少条腿,即使这不是必需的

人们通常如何实施这种情况


编辑:这里我可以如何使用这个。假设(现在这很可笑,但无论如何…)每只动物的腿数是唯一的,所以我可能会有这样的结果:

Animal getModelAnimal(int numberOfLegs) {
   if (numberOfLegs == Chicken.getNumberOfLegs()) return new Chicken();
   else if (numberOfLegs == Dog.getNumberOfLegs()) return new Dog();
}
  (Animal)Dog.getNumberOfLegs() //cast Dog to Animal first

您的伪代码看起来很像Java,所以我假设您使用的是Java

“抽象方法需要每个实例实现。静态方法属于整个类。抽象类中的静态方法属于抽象类,而不是潜在的实现。因此,允许抽象静态方法没有任何意义。此外,静态方法不能被重写,因此抽象静态方法也是一种异常。”


请同时查看

即使您可以拥有一个抽象静态方法,您将如何使用它?在您考虑如何实现它之前,请先考虑如何使用它,因为您的实现必须与用途相匹配。

这是一个非常好的观点,有时
抽象静态
确实缺失。 但是,由于现在内存不是问题,您当然可以将
getNumberLegs()
-方法作为实例方法来实现

说静态抽象是无意义的,这是不对的。PHP允许抽象静态方法(请参阅),您的场景表明,它在某些情况下可能很有用

static
方法不能被重写也是不对的;
final
方法不能被重写。在Java和C等语言中,
static
final
一起出现。这就是为什么许多人认为
static
等于“不可重写”

谈到C(在阅读你的评论后,我假设你说“C”),你可以考虑使用泛型和属性(或泛型和注释在爪哇):

人们通常如何实施这种情况

在Java术语中,我只需要在抽象类中声明一个构造函数,该构造函数接受一个固定参数,然后要求每个子类调用它,否则它将无法编译

abstract class Animal {
    private int numberOfLegs;

    public Animal(int numberOfLegs) {
        this.numberOfLegs = numberOfLegs;
    }

    public int getNumberOfLegs() {
        return numberOfLegs;
    }
}

class Chicken extends Animal {
    public Chicken() {
        super(2);
    }
}

class Dog extends Animal {
    public Dog() {
        super(4);
    }
}

更新:根据您的更新

编辑:这里我可以如何使用这个。 假设(现在这是荒谬的,但是 不管怎样…)这是 每种动物都是独一无二的,所以我可能 比如:

Animal getModelAnimal(int numberOfLegs) {
   if (numberOfLegs == Chicken.getNumberOfLegs()) return new Chicken();
   else if (numberOfLegs == Dog.getNumberOfLegs()) return new Dog();
}
  (Animal)Dog.getNumberOfLegs() //cast Dog to Animal first

这真是荒谬,这要求所有这些具体的动物都在抽象工厂方法中预先知道。每次添加新的具体动物类型时,都需要更新抽象工厂方法。那么抽象工厂的意义是什么?你事先已经知道了一切?不,让抽象工厂来吧工厂方法将完全限定的类名作为标识符,这样它就可以尝试从类路径加载(仍然使用Java术语)。

这是一个有趣的问题。在我看来,“静态抽象”方法很少需要,而且总是有很好的替代方法

例如,在您提供的用例中,工厂方法按名称对具体的动物类进行寻址;对于每个新的动物类,都应该添加新的特定代码。因此,似乎并不真正需要“抽象”限定。提供静态方法getNumberLegs()的约定就足够了

更一般地说,将抽象和静态结合起来(在Java中)是没有意义的,因为抽象意味着多态性,而静态调用完全是非多态的,并且在编译时处理已知的类

一个人通常怎么走 实施这种情况

通常的解决方案是将所讨论的方法设置为实例方法

getNumberOfLegs()
显然应该 静态方法(假设在 完美的世界我们没有残废 鸡和狗所以
getNumberOfLegs
是 不依赖实例)

这显然是不明显的!我们不为完美世界编程,在现实世界中,四足动物有时有一条腿、两条腿或三条腿(或五条腿)

如果您的程序需要动物定义而不是动物实例,请继续并为此创建一个类


然后在程序开始时初始化一个集合——理想情况下是从数据库或配置文件中,在那里你可以添加动物定义,而无需编写或编译另一行代码。(而且你可以使用更少的类型。)

您可以使用运行时检查方法是否通过让基类在其实现中抛出异常来实现。这没有多大价值,但最好什么都不做…

如果您调用抽象方法来帮助基类,那么这些方法是有意义的。请注意,在您的示例中,您根本没有使用polimorphism。在示例中,应类似于:

Animal getModelAnimal(int numberOfLegs) {
   if (numberOfLegs == Chicken.getNumberOfLegs()) return new Chicken();
   else if (numberOfLegs == Dog.getNumberOfLegs()) return new Dog();
}
  (Animal)Dog.getNumberOfLegs() //cast Dog to Animal first
无论如何,PHP实现了所谓的“后期静态绑定”
abstract class AnimalFactory
{
    public abstract Animal CreateAnimal();
    public abstract int GetLegs();

}
abstract class Animal
{

}
internal class Chicken : Animal
{

}
class CreateChicken : AnimalFactory
{
    public override Animal CreateAnimal()
    {
        return new Chicken();
    }
    public override int GetLegs()
    {
        return 2;
    }

}
Animal modelAnimal;
int numLegs;

modelAnimal = this.getModelAnimal(4); // Got a dog

numLegs = modelAnimal.getNumberOfLegs();