抽象类的公共构造函数有充分的理由吗

发布于 2024-10-14 08:20:25 字数 612 浏览 4 评论 0原文

无法通过直接调用抽象类的构造函数来创建对象。 抽象类的构造函数只能从派生类中调用。因此,在我看来,抽象类的构造函数必须是受保护的或包私有的(后者用于限制在派生类中使用构造函数的不寻常情况)包)。然而,Java 允许抽象 类的构造函数是public

是否存在将抽象类的构造函数声明为public而不是protected有用的情况code> 还是包私有?

这与问题“抽象类构造函数访问修饰符”不太重复:显然您可以将构造函数声明为public;我想知道是否有任何充分理由这样做。在我看来,没有。我发现 C# 也有类似的特性

It is not possible to create an object by directly calling the constructor of an abstract class. The constructor of an abstract class can be called only from a derived class. It therefore seems to me that constructors of an abstract class must be either protected or package-private (the latter for the unusual cases of restricting use of a constructor to derived classes within the package). Yet Java allows the constructor of an abstract class to be public.

Are there any circumstances in which it is useful to declare the constructor of an abstract class to be public, rather than protected or package-private?

This is not quite a duplicate of the question "Abstract class constructor access modifier": clearly you can declare a constructor to be public; I want to know whether there is ever any good reason to do so. It seems to me that there is not. I see that C# has a similar peculiarity.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

淡看悲欢离合 2024-10-21 08:20:25

对于java来说答案是一样的:

没有理由为抽象类提供公共构造函数。我认为编译器不抱怨的原因很简单,他们只是没有花时间讨论这一点,因为它是公共的还是受保护的并不重要。 (来源

您无法调用构造函数来自直接子类以外的任何抽象类。

因此,为抽象类的构造函数的访问修饰符添加特殊规则不会为该语言添加有用的内容。


有一点看起来像是此规则的例外 - 如果抽象类仅定义默认构造函数,则子类不必实现构造函数:这是合法的:

public abstract class A {
  public A() {}
}

public class B extends A {}

因此我们可以创建一个 B 通过调用 new B() - 但请注意,我们仍然创建一个 B 而不是 A。而且,A 中的构造函数是公共的还是受保护的并不重要。它不应该是私有的,但编译器会注意到并抱怨......

实际上我们在 B 上调用一个“不可见的”公共默认构造函数,它执行一个简单的 super() 打电话...

The answer is the same for java:

THere's no reason for a public constructor for an abstract class. I'd assume that the reason that the compiler doesn't complain is as simple that they just didn't spend time covering that since it really doesn't matter if it's public or protected. (source)

You can't call a constructor of an abstract class from anything other than a direct subclass.

So adding a special rule for access modifiers of constructors of abstract classes wouldn't add something useful to the language.


One thing that looks like an exception from this rule - if the abstract class only defines a default constructor, then the subclass does not have to implement a constructor: this is legal:

public abstract class A {
  public A() {}
}

public class B extends A {}

So we can create a B by calling new B() - but note, that we still create a B and not an A. And, again, it doesn't matter if the constructor in A is public or protected. It just shouldn't be private, but the compiler will notice and complain...

Actually we invoke an "invisible" public default constructor on B which does a simple super() call...

花开浅夏 2024-10-21 08:20:25

可见性还会影响 javadoc 中显示的内容(如果选择排除某些可见性级别)。否则并不重要,这可能是抽象类的公共构造函数的用法。

如果您未提供构造函数,则如果该类是公共的,则默认构造函数也是公共的。最简单的选择是允许这样做,而不是强制使用受保护的构造函数。

从这个意义上说,相反的问题可能会清楚地表明:为什么他们不在抽象类中强制使用受保护的构造函数?因为公共构造函数不会改变任何东西,所以它只会花费时间并增加复杂性。

The visibility also infuences what is shown in the javadoc (if it's selected to exclude certain visibility levels). As it doesn't matter otherwise, that could be a usage for a public constructor of an abstract class.

If you provide no constructor, then the default constructor is public if the class is public. Easiest option would be to allow that, rather than forcing protected constructors.

In that sense the reverse question may make it clear: why didn't they force protected constructors in abstract classes? Because public constructors won't change anything, so it would just take time and add complexity.

坏尐絯 2024-10-21 08:20:25

你可以称我为异教徒,但是……我看到构造函数在抽象类中至少有一种用途。

即:指定构造函数参数是什么样的。

指定一个抽象构造函数(从而使类抽象)。派生类必须使用其特定签名来实现此构造函数,以失去抽象状态。

我认为没有其他方法可以指定强制构造函数签名(如果您这样做,请帮助我)。

Call me a heretic, but ... I see at least one use for a constructor in an abstract class.

That is: to specify what the constructor parameters look like.

Specify an abstract constructor (thus making the class abstract). Derived classes have to implement this constructor with its specific signature to lose abstract status.

I see no other way to specify mandatory constructor signatures (help me out if you do).

∝单色的世界 2024-10-21 08:20:25

如果没有在子类的构造函数中定义,则可以拥有公共构造函数。
例如

abstract class Animal {
   String name;
   public void Animal(String name) {
         this.name = name;
   }
}


class Cat extends Animal{
    public String sayMayName() {
       return this.name;
    }
}

myCat = new Cat("tester");

name = myCat.sayMyName();

,如果没有定义构造函数,则将调用父类构造函数,如果它不是公共的,则它将不起作用。我认为使用工厂模式可以更优雅地完成此操作,但我在 PHP 实践中使用了它并且效果很好。

You can have a public constructor if you do not define in a constructor in the sub-class.
example

abstract class Animal {
   String name;
   public void Animal(String name) {
         this.name = name;
   }
}


class Cat extends Animal{
    public String sayMayName() {
       return this.name;
    }
}

myCat = new Cat("tester");

name = myCat.sayMyName();

if no constructor is defined the parent class constructor will be called, if it is not public it will not work. This I think is more elegantly done with a factory pattern, but I used it in practice in PHP and it works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文