Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java constructor extending [closed]

Tags:

java

When I extend some class,for example:

public class First {
    int id;
    public First(int _id) {
        id = _id;
    }
}

and

public class Second extends First {

}

I must redeclare the constructor for Second class, when I just need to do the same. I can:

public Second(int _id) {
    super(_id);
}

But every time I change the parent constructor all of the extended classes' constructors need to be edited.

How can I extend the constructor fully?

Damn, don't tell me about phone and antenna, I have used OOP many times.

Now I only ask - can't I write public Class(){} on extended classes, and use the parent constructor?

It seems that I can't. Okay.

like image 717
ShadowPrince Avatar asked May 20 '12 16:05

ShadowPrince


People also ask

Can constructor be extended in Java?

Calling Constructors in Superclasses In Java a class can extend another class. When a class extends another class it is also said to "inherit" from the class it extends. The class that extends is called the subclass, and the class being extended is called the superclass.

Can a class with private constructor be extended?

When you have a class with only private constructors, you can also change the class to final because it can't be extended at all.

Can you use this () and super () both in a constructor?

“this()” and “super()” cannot be used inside the same constructor, as both cannot be executed at once (both cannot be the first statement). “this” can be passed as an argument in the method and constructor calls.

How does super () work in Java?

The super keyword refers to superclass (parent) objects. It is used to call superclass methods, and to access the superclass constructor. The most common use of the super keyword is to eliminate the confusion between superclasses and subclasses that have methods with the same name.


2 Answers

When you define a subclass, it does not inherit constructors from the superclass. For anything other than the default superclass constructor, you need to explicitly call a superclass constructor in each subclass constructor. (That means, among other things, that if the base class does not have a default constructor, neither can any child class every child class constructor must explicitly call a superclass constructor—and no child class can have simply a compiler-generated default constructor. There's one exception to this; see [*] below.)

Inheriting constructors could cause all sorts of problems. Imagine something like this:

class Base {
    private int mId;
    public Base(int id) {
        mId = id;
    }
    . . .
}

Now we want to derive a class that has a second attribute—a tag—that we want to ensure is never null. So we write the following:

class Derived extends Base {
    private Object mTag;
    public Derived(Object tag, int id) {
        super(id);
        if (tag == null) {
            throw new IllegalArgumentException("tag cannot be null");
        }
        mTag = tag;
    }
    . . .
}

Now imagine constructing an instance of Derived like this:

Derived derived = new Derived(3);

If constructors were inherited, this would presumably be legal. What would it mean? For one thing, mTag would be set to its default value of null. There would be no way for Derived to enforce the rule that all instances of Derived must have a non-null tag.

At the cost of requiring a bit more typing, Java rules out inheriting constructors precisely to allow each class to fully control how its instances get created.

[*] There's one case where the compiler will automatically generate a non-default constructor. Consider the Base class above and this code:

Base foo = new Base(3) {
    . . . // some extended functionality
};

Now foo is being initialized to an anonymous subclass of Base. For ease of reference, let's call this subclass Base$Anon. The compiler will generate code equivalent to:

class Base$Anon extends Base {
    Base$Anon(int id) {
        super(id);
    }
    . . . // some extended functionality
}

Base foo = new Base$Anon(3);

This is the only case where the compiler generates a non-default constructor if you don't specify any constructors of your own. In fact, the language syntax doesn't even let you declare a constructor for an anonymous class; you must rely on the compiler generating one for you.

like image 167
Ted Hopp Avatar answered Sep 28 '22 00:09

Ted Hopp


This limitation is one of the reasons why I prefer composition over inheritance. Consider using code like this instead:

public class Second {
    private final First first;

    public Second(final First first) {
         this.first=first;
    }

    public int getId() {
        return first.getId();
    }
}

This construct also leaves your two classes less coupled and makes the relation between the classes clearer in my opinion. For a more thorough discussion of composition over inheritance, see for instance this question: Prefer composition over inheritance?

like image 33
Alexander Torstling Avatar answered Sep 28 '22 00:09

Alexander Torstling