3

I'm making an abstract Font class and I want to force subclasses to declare a constructor that takes a single int parameter (font size). I tried doing so as follows.

public abstract class Font {
  ...
  public abstract Font(int size);
  ...
}

But my compiler declares:

Error:(20, 19) java: <path omitted>/Font.java:20: modifier abstract not allowed here

This isn't exactly the end of the world - this isn't strictly necessary, I just wanted the Java compiler to force me to remember to implement that constructor. I just wonder why this isn't allowed?

Michael Dorst
  • 6,449
  • 10
  • 35
  • 64
  • 1
    This feature doesn't seem like a good idea. Say you have a concrete class that defines another private field `f` that must be initialized to some useful value, so all the concrete class constructors should have a value to store into `f`. Do you really want the compiler complaining because none of your constructors have the profile `(int size)`? – ajb Jan 12 '15 at 17:46
  • 1
    Constructors can't be overridden (they are always non-virtual against a concrete type). As to why this feature doesn't exist - well, if it did then that would be a different language. – user2864740 Jan 12 '15 at 17:48

3 Answers3

6

Any constructor you create must be called by any class that implements this abstract class, so there's not really a need to "remind" people to implement that constructor.

There are a lot of reasons that people extending your classes might want to create their own constructors. For example:

public MySpecialSize16Font()
{
    super(16);
}

or

public ColoredFont(int size, Color color)
{
    super(size);
    this.color = color;
}

It's not really your place to specify what constructors these classes can and cannot provide.

Michael Dorst
  • 6,449
  • 10
  • 35
  • 64
StriplingWarrior
  • 135,113
  • 24
  • 223
  • 283
  • In my case I already have a constructor for the `Font` class, but I want to be forced to implement both. – Michael Dorst Jan 12 '15 at 17:45
  • 2
    @anthropomorphic: That violates the open/closed principle. As long as child classes can provide the parent with everything it needs to be instantiated, why should you care whether a specific constructor is implemented? They should be able to create whatever constructors they want. – StriplingWarrior Jan 12 '15 at 17:47
  • Fair enough, I see your point. I'll just have to keep track of my own conventions then. – Michael Dorst Jan 12 '15 at 17:49
  • @anthropomorphic: Yeah, if you're thinking of this in terms of coding conventions, you might be able to enforce this with advanced style checker rules. – StriplingWarrior Jan 12 '15 at 17:53
  • Side note, I see you use the syntax `base(...)` to call a superclass' constructor. Is that legal? I've always used `super(...)`. – Michael Dorst Jan 12 '15 at 17:56
  • @anthropomorphic it isn't valid syntax, the answerer means `super(...)`. `base` is just saying that it means the base constructor. – bcsb1001 Jan 12 '15 at 17:59
  • Thanks for that correction. I've been too long in C# land. – StriplingWarrior Jan 12 '15 at 18:42
0

If you implement that constructor in the abstract class, at least at a trivial level (perhaps with no error checking), give it protected access, and make that size variable be only settable through it--that would effectively enforce its use by sub-classes, assuming that size is an important attribute.

aliteralmind
  • 18,274
  • 16
  • 66
  • 102
0

You should checkout this: Can an abstract class have a constructor?

Try to remove the abstract @ your constructor. It should be:

public Font(int size);

Should work then if im not mistaken :)

Community
  • 1
  • 1
LOLWTFasdasd asdad
  • 1,071
  • 2
  • 18
  • 30
  • No, it doesn't work, and you are mistaken. You cannot just leave a constructor with a semicolon, you must implement it. This does not compile. – bcsb1001 Jan 12 '15 at 17:56
  • @bcsb1001 Oh yes, you're right, I didn't look closely enough. LOLWTF, yes, it does look like you are mistaken. – Michael Dorst Jan 12 '15 at 17:59