Passing construction to super class - java

I was wondering if i have an abstract super class with x different constructors, and i want to be able to use all those constructors in a subclass, do i have to write all x constructors in the subclass and just let them all call super(...) ? Seems like redundant code..
An example for the clarity:
public class SuperClass {
public SuperClass() {
...
}
public SuperClass(double d) {
...
}
public SuperClass(BigDecimal b) {
...
}
public SuperClass(BigDecimal b, String s) {
...
}
[...]
}
Do i than need:
public class SuperClass {
public SubClass() {
super();
}
public SubClass(double d) {
super(d);
}
public SubClass(BigDecimal b) {
super(b);
}
public SuperClass(BigDecimal b, String s) {
super(b, s);
}
[...]
}

But you have to do it this way. As this way you are deciding what you want to expose in the subclass. Also some constructors might be not appropriate for a sub class thus this is not working by default without you coding it explicitly.

You do not need to supply constructors for every overload of base's constructors. You simply need one. If your base constructor offers a default (parameterless) constructor, then you do not even need to provide a constructor yourself. The compiler will automatically generate a default constructor for your class that automatically calls the default constructor of your base class.
Note: it is not necessary to call super() directly, as it is implied without parameters. It is only required when no default constructor exists.
Seeing that many different constructors, and the fact that you do not need them all might imply that the parent class is doing too much.

you can have a code like this:
public class SuperClass {
public SuperClass() {
...
}
public SuperClass(double d) {
...
}
public SuperClass(BigDecimal b) {
}
public SuperClass(BigDecimal b, String s) {
this(b);
}
[...]
}
And have a subclass as:
public class SubClass extends SuperClass{
public SubClass() {
super();
}
public SubClass(double d) {
super(d);
}
public SuperClass(BigDecimal b, String s) {
super(b, s);
}
[...]
}

If you want every type of constructor in both parenr and child, then yes, you need to specify them explicitly, but no need to call super() explicitly.

Related

Question about constructor of superclass and subclass

Why the the code (1) is not result an error while code (2) (3) will?
I think when the subclass calls the constructor, it will calls super class constructor first, but I do not know why the code (1) is right while other two are wrong.
//(1)
public class Parent {
public int a;
public Parent() {
this.a = 0;
}
}
public class Child extends Parent {
public Child() {}
}
//(2)
public class Parent {
public int a;
public Parent(int number) {
this.a = number;
}
}
public class Child extends Parent {
public Child() {}
}
//(3)
public class Parent {
public int a;
public Parent(int number) {
this.a = number;
}
}
public class Child extends Parent {
public Child(int numb) {
}
}
Code(1) is right while other two are wrong.
Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the
no-argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem.
So, here it is, your code (2)(3) doesn’t have a no-argument constructor, and also you didn’t explicitly invoke a has-argument constructor, you got a compile-time error. More details from https://docs.oracle.com/javase/tutorial/java/IandI/super.html
In code 1, the constructor for Parent has no arguments, so a call to the default one is implicit:
public Child () {
super();
} /* This code is not necessary, but is implied. */
But in codes 2 and 3, the constructor has a parameter, and since there is no overload provided with no parameters, then a call to the superclass constructor must be provided. To do this, you must reference super().
public class Parent {
public int a;
public Parent(int number) {
this.a = number;
}
}
public class Child extends Parent {
public Child(int numb) {
super(numb); // Calls Parent(int) and sets this instance’s Parent.a value to numb.
}
}

Is there a way in Java to call different child method depending on which subclass is the object?

In my project I have a superclass and two subclasses extending from it. There is a method in the superclass that is overriden differently in each subclass.
I want to know if it's possible to introduce a method (in another class) that takes object of either subclass as a parameter and calls a method overriden in one of subclasses (depending on to which subclass does the object belong).
public class Superclass{
public int method(){return 0;}
}
public class Subclass1 extends Superclass{
public int method(){return 1;}
}
public class Subclass2 extends Superclass{
public int method(){return 2;}
}
public class CallingClass{
public static int dependantCall(Superclass parameter){return parameter.method}
I want to be able to do something like
Subclass1 subclassObject = new Subclass1;
System.out.println(CallingClass.dependantCall(subclassObject));
and get output
1
That is what Polymorphism is for! Defining the Superclass as a parameter type will allow you to pass either subclass in.
For example in your other class you can define it like this:
// classes Dog and Cat extend Animal and override makeNoise()
class Owner{
playWith(Animal a){
a.makeNoise();
}
}
Now the Owner can accept owner.makeNoise(cat) and owner.makeNoise(dog)
More reading: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
Yes, it is entirely possible. Here's how that method would look like:
public <T extends Superclass> void foo(T subclassObject) {
...
}
Or:
public void foo(Superclass obj) {
...
}
Note that in the above method, you can pass subclasses' objects as well (they are covariant data types).
This is what Java does by default when you create subclases, so no need to do anything special. Each object carries it's type information at run time, and the method invoked would always be the most specific one for the object. Example:
public class Doer {
public void doSomething() {
// Body presence
};
}
public class Painter extends Doer {
#Override
public void doSomething() {
// Paint here
}
}
public class Manager extends Doer {
#Override
public void doSomething() {
// Micromanage here
}
}
// Elsewhere in your code:
public void busyness(Doer doer) {
doer.doSomething();
}
A style note: if it is possible, one should prefer using interfaces instead of base classes (base classes those should be used only if you want to share implementation between subclasses). Example with interfaces:
public interface Doer {
void doSomething();
}
public class JackOfAllTrades implements Does {
#Override
public void doSomething() {
// Do whatever necessary
}
}
// Client code stays exactly the same as above:
public void busyness(Doer doer) {
doer.doSomething();
}
Note that in Java a class can have only one base class but can implement multiple interfaces.
#Override annotations are not strictly required, but they help Java compiler to spot some errors for you (e.g. if you misprint method name).
In your example it would look like
public class CallingClass {
public static int dependantCall(Superclass parameter) {
return parameter.method();
}
}
Subclass1 subclassObject = new Subclass1();
System.out.println(CallingClass.dependantCall(subclassObject));

Java: Inherit all superclass's constructors by default

I'm only beginner in Java.
My Superclass has several constructors:
public class Superclass {
protected Superclass () {
//some stuff
}
protected Superclass (typeA a){
//some other stuff
}
protected Superclass (typeB B){
//another stuff
}
}
I want to make subclasses, but all of them will only use all super constructors of Superclass and some specific for that class actions. Example for subclass:
public class Subclass extends Superclass {
protected Subclass () {
super();
//subclass stuff
}
protected Subclass (typeA a){
super(typeA a);
//the same subclass stuff
}
protected Subclass (typeB B){
super(typeB B);
//the same subclass stuff
}
}
Does in Java exist something to inherit all superclass constructors? Because I don't want to copypaste code, but I want to do like this:
#InheritsAllConstructors
public class Subclass extends Superclass {
{
//some stuff
}
}
Or there is more suitable solution?)
NO, because subclasses are not forced to have the same constructors as their superclasses (They can have more or fewer constructors).
Superclass has no explicit constructors: Subclasses are not forced to have an explicit constructor.
Superclass has one explicit constructor: Subclasses are forced to have at least one constructor. The constructor in the subclass doesn't have to match the one in superclass but it should call it using super(...)
public class Super {
public Super(String value) {
//...
}
}
Subclasses should provide a constructor that calls super(..):
Like this:
private class Sub extends Super {
public Sub(String value) {
super(value);
}
}
Or even this:
private class Sub extends Super {
public Sub() {
super("some default value");
}
}
Superclass has more than one explicit constructor: Subclasses are forced to provide at least one constructor that calls any of the superclass's constructors:
public class Super {
public Super(String value) {
//...
}
public Super(int intValue) {
//...
}
}
Subclasses could be any of the following:
private class Sub extends Super {
public Sub() {
super("some default value");
}
}
Or:
private class Sub extends Super {
public Sub(String value) {
super(value);
}
}
Or:
private class Sub extends Super {
public Sub(int intValue) {
super(intValue);
}
}
Or any combination of those constructors.

How should I restrict usage of methods of predefined class

Suppose I have created StringUtil class by extending String. Now any third party calling StringUtil can use all the methods defined for String class. How can I restrict usage of some methods?
String class is final, and you can't extend a final class in Java. You have to read more about Java core. For example, begin by reading https://www.w3schools.in/java-tutorial/super-final-keywords/
Also, when you want a string utility, you have several options like Apache-Commons-Lang or Spring-Core that makes your code readable and has more functionalities.
In case you have multiple classes such that you want to give each of them access to a group of methods inside StringUtil, you can do the following:
If Class1, for example, needs only methods: f1, f2, f3 then you could create an interface interface1 such that exposes only f1, f2, f3 and Class will receive an object of type interface1 as a param to its constructor. StringUtil implements interface1.
Do the same for other classes so each class will be able to use only what you expose to them.
You should read also on dependency injection.
The interfaces:
interface Interface1 {
void f1();
}
interface Interface2 {
void f2();
void f3();
}
StringUtils class:
class StringUtils implements Interface1, Interface2 {
#Override
public void f1() {
}
#Override
public void f2() {
}
#Override
public void f3() {
}
}
The classes who use StringUtils class:
class A {
private Interface1 interface1; // you can mark it as final if it's permanent.
public A(Interface1 interface1) {
this.interface1 = interface1;
}
}
class B {
private Interface2 interface2; // you can mark it as final if it's permanent.
public B(Interface2 interface2) {
this.interface2 = interface2;
}
}
In such scenarios, however, there may be some workaround like: override the method in the base throw some expectation from it, but it will not be a real solution. My recommendation will be to use composition over inheritance. That means your base should has a relationship with superclasses. For example, a let assume 2 classes A (same as your String class) and B (same as your StringUtil class).
class A {
public int add(int a, int b) {
return a + b;
}
public int square(int a) {
return a * a;
}
}
class B {
A obj;
B(A obj) {
this.obj = obj;
}
public int add(int a, int b) {
return obj.add(a, b);
}
}
Now your class B only expose only one method add which delegates its behavior to class A's add method. Also square is not available on B.

Overriding a base class method in a derived class

I have a base class A, having a method "say" that calls from constructor of A. All the heritable classes uses the method "say" like it is. But one of the classes need to redefine this method. How is it possible?
For sure, I can denote base method "say" as abstract, but in that way, i have to copy the same method "say" in all the heritable classes.
If i just redefine method without denoting base one as abstract, it is not gonna be called.
public abstract class A(){
public A(){
say(); // <- wanna call this method from heritable class, if its redefined.
}
protected void say(){};
}
public class B extends A(){
public B(){
super();
}
private void say(){};
}
refactoring 1
public abstract class A(){
public A(){
// constructor methods
}
protected void say(){};
protected void executeSay(){
say();
}
}
public class B extends A(){
public B(){
super();
executeSay();
}
#Override
protected void say(){};
}
First of all one must be made clear: calling an overridable method from a constructor is a well-known antipattern. It will almost certainly break your code because the subclass method will be invoked before the subclass constructor is done and so will observe an uninitialized object. Thus I should better refrain from giving you detailed advice on Java technicalities involved in achieving this antipattern.
The only safe way to acomplish your requirement is to let the construction finish and only afterwards call an initialize-kind of method. If you want to ensure initialize is always invoked, make the constructors non-public and provide a factory method instead.
Unfortunately, Java requires quite a bit of work on your part to make this work properly.
You cannot instantiate a abstract class. That saying you have to link the abstract class reference to the concrete inherited class.
eg. A a = new B();
If that's the case, and B have redefined the say() method, then the say method in B will be called.
public class TestPad {
public static void main(String[] args) {
A a = new B();
}
}
abstract class A {
public A() {
say();
}
public void say(){
System.out.println("A");
};
}
class B extends A {
public B() {
super();
}
public void say() {
System.out.println("B");
}
}
The output will be B
public class B extends A {
public B() {
super();
}
#Override
protected void say() {
// your diffent say code
};
}
I'm not sure if you are allowed to reduce visibility to private.
Because of polymorphic method invocation, in your case the B.say() will be invoked if you override it.
But as #sanbhat commented, you need to change visibility of say() to protected.

Categories

Resources