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.
Related
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.
}
}
I want to create a new instance depending on an object, where I have the super class variable. Is this somehow possible without implementing a getNew() function or without usage of an ugly if chain?
In other words: How to implement the following newSubClass(..) function without using the getNew() function?
public abstract class SuperClass {
abstract public SuperClass getNew();
}
public class SubClassA extends SuperClass {
#Override
public SuperClass getNew() {
return new SubClassA();
}
}
public class SubClassB extends SuperClass {
#Override
public SuperClass getNew() {
return new SubClassB();
}
}
private SuperClass newSubClass(SuperClass superClass) {
return superClass.getNew();
}
After having some time to think about and zv3dh's contribution I decided this second answer.
I'am getting now you want an new instance of an instance of a subclass' type of SuperClass without knowing the concrete sub-type at runtime.
For that you have "reflexion".
public abstract class A_SuperClass {
public A_SuperClass createNewFromSubclassType(A_SuperClass toCreateNewFrom) {
A_SuperClass result = null;
if (toCreateNewFrom != null) {
result = toCreateNewFrom.getClass().newInstance();
}
// just an example, add try .. catch and further detailed checks
return result;
}
}
public class SubClassA extends A_SuperClass {
}
public class SubClassB extends A_SuperClass {
}
If you search for "java reflexion" you will get lots of results here on SO and on the web.
Have a look at the "FactoryMethod" design pattern.
It is exactly what you are looking for: It does encapsulate the "new" operator.
However your example makes me wonder:
Your getNew() reimplements what the constructor would do anyway
Try something like this:
public abstract class SuperClass {
public SuperClass createSuperClass(object someParam) {
if (someParem == a) return new SubClassA();
if (someParem == b) return new SubClassB();
}
}
public class SubClassA extends SuperClass {
}
public class SubClassB extends SuperClass {
}
As you see you need some IF at some place ...
Let say I have a class:
package inheritanceexample;
public class SuperClass {
public SuperClass() {
System.out.println("super class constructor 1");
}
public SuperClass(int a) {
System.out.println("super class constructor 2");
}
public SuperClass(int a, int b) {
System.out.println("super class constructor 3");
}
}
public class SubClass extends SuperClass {
public SubClass() {
System.out.println("sub class constructor 1");
}
public SubClass(int a) {
System.out.println("sub class constructor 2");
}
public SubClass(int a, int b) {
System.out.println("sub class constructor 3");
}
}
public class SubClass1 extends SubClass {
public SubClass1(int a) {
super(a);
System.out.println("sub class 1 constructor 1");
}
}
How can I access the constructor in super class with parameters, lets say the constructor SuperClass(int a), if I'm going to access it in the SubClass1 which extends SubClass because when I put super(int a) in the SubClass1 it only accesses or executes the constructor in the subclass which it extends. Can I access the constructor in super class with parameters directly in SubClass1?
You cannot skip levels of the constructor: if the class in the middle (i.e. subclass) does not expose a constructor that calls a particular constructor of superclass, subclasses of subclass no longer have an ability to access these constructors.
The super keyword lets you jump exactly one level up; jumping through multiple levels is not allowed.
This rule makes perfect sense, though: to subclass1 the fact that subclass extends superClass is an implementation detail. Letting subclass1 call through to a constructor of superClass over the head of its own superclass would break encapsulation of superclass.
So I've come across a bit of a snag in some code that I'm working with. Essentially I have the following three tidbits of code:
Abstract class:
public abstract class TestParent {
int size;
public TestParent(int i){
size = i;
}
}
Child Class:
public class TestChild extends TestParent{
public void mult(){
System.out.println(this.size * 5);
}
}
Implementation:
public class TestTest {
public static void main(String args[]) {
TestChild Test = new TestChild(2);
Test.mult();
}
}
Consider the following case of abstract class and extends implementation.
https://stackoverflow.com/a/260755/1071979
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return muliplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a default constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.
NOTE: As there is no default (or no-arg) constructor in the parent abstract class the constructor used in subclasses must be specified.
Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.
public class TestChild extends TestParent{
public TestChild(int i){
super(i); // Call to the parent's constructor.
}
public void mult(){
System.out.println(super.size * 5);
}
}
Use super to call parent (TestParent.TestParent(int)) constructor:
public class TestChild extends TestParent{
public TestChild(int i) {
super(i);
}
//...
}
or if you want to use some constant:
public TestChild() {
super(42);
}
Note that there is no such thing as abstract constructor in Java. Essentially there is only one constructor in TestParent which must be called before calling TestChild constructor.
Also note that super() must always be the first statement.
When you have explicit constructor defined in super class and no constructor without arguments defined, your child class should explicitly call the super class constructor.
public class TestChild extends TestParent{
TestChild ()
{
super(5);
}
}
or, if you don't want call super class constructor with parameters, you need to add constructor with no arguments in super class.
public abstract class TestParent {
int size;
public TestParent(){
}
public TestParent(int i){
size = i;
}
}
You code wont compile because your base class does not have a default constructor. Either you need to provide it in base class or you need to provide parameterized constructor in derived class and invoke super.
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i * 2);
}
}
This code would use the double of i. This is an overriding, though i'm not sure what you want to ask.
Other solution:
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i);
this.size = 105;
}
}
For this solution, size must be protected or public.
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.