Beginner Q: optional arguments in Java - java

I'm totally new to Java, as in, I started yesterday.
I've got a class that I'd like to have two constructors for: one without arguments, and one with.
Supposedly this should be simple: overload the constructor by writing two methods:
public class sortList {
public int ncell, npart, cell_n, index, Xref;
// constructor(s):
public void sortList() {
initLists( 1, 1 );
}
public void sortList( int ncell_in, int npart_in ) {
initLists( ncell_in, npart_in );
}
private void initLists( int ncell_in, int npart_in ) {
/* DO STUFF */
}
}
When I call this from my main() though:
sortList mySL = new sortList( 5, 6 );
... java complains:
myDSMC.java:5: error: constructor sortList in class sortList cannot be applied to given types;
sortList mySL = new sortList( 5, 6 );
^ required: no arguments
found: int,int
reason: actual and formal argument lists differ in length
1 error
(For the curious, I am just translating a super-simple DSMC code from C++...).
What silly thing am I missing?
Thanks.
-Peter

This are not constructors, they are regular methods :
public void sortList() {...}
public void sortList( int ncell_in, int npart_in ) {...}
Change them to constructors by removing the return type :
public sortList() {...}
public sortList( int ncell_in, int npart_in ) {...}
Since you didn't declare any constructors in your sortList class (you just declared two regular methods having the same name as the class), only the default parameter-less constructor was available.

Constructors in Java have no return type and have name the same as the name of the class.
The all methods in java have return type (void - if nothing to return).
You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor.
Example of constructor and methods:
// for this class default no-args constructor implicitly created
public class Test1 {
int id;
// regular method
public int getId() {
return id;
}
// regular method
public int test1() {
return 1;
}
}
public class Test2 {
int id;
// no-args constructor
public Test2() {
}
// overloaded constructor
public Test2(int id) {
this.id = id;
}
// regular method
public int getId() {
return id;
}
// regular method
public void test2() {
System.out.println("1");
}
}
All defined constructors implicitly call super();. So Test2 constructor actually looks like this:
public Test2(int id) {
super();
this.id = id;
}

Related

Java Reflection: Why getConstructors() for class A returns an empty array? [duplicate]

I can't seem to use getConstructor for constructors with no parameters.
I keep getting the following exception:
java.lang.NoSuchMethodException: classname.<init>()
Here is the code:
interface InfoInterface {
String getClassName();
String getMethodName();
String getArgument();
}
class asa implements InfoInterface {
#Override
public String getClassName() {
return ("jeden");
}
#Override
public String getMethodName() {
return ("metoda");
}
#Override
public String getArgument() {
return ("krzyk");
}
}
class Jeden {
Jeden() {
System.out.println("konstruktor");
}
public void Metoda(String s) {
System.out.println(s);
}
}
class Start {
public static void main(String[] argv) {
if (argv.length == 0) {
System.err.println("Uzycie programu: java Start nazwa_klasy nazwa_klasy2...");
return;
}
try {
for (int x = 0; x < argv.length; x++) {
Class<?> c = Class.forName(argv[x]);
InfoInterface d = (InfoInterface) c.newInstance();
String klasa = d.getClassName();
String metoda = d.getMethodName();
String argument = d.getArgument();
Class<?> o = Class.forName(klasa);
// o.newInstance();
Constructor<?> oCon = o.getConstructor();
System.out.println("ASD");
Class<?> p = (Class<?>) oCon.newInstance();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
o.newInstance(); prints "konstruktor" without problems.
The problem is clear when you read the javadoc of .getConstructor():
Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.
Emphasis mine.
In your code, the constructor is not public!
Example:
// Note: class is NOT public -- its default constructor won't be either
final class Test
{
public static void main(final String... args)
throws NoSuchMethodException
{
// throws NoSuchMethodException
Test.class.getConstructor();
}
}
Obligatory link to an SO answer which also gives the JLS reference. In particular, note that the default constructor has the same access modifier as the class.
It seems as if your class provides a constructor that is NOT a default constructor. The call to getConstructor() without parameters requires the class to have a default constructor. The following test illustrates this.
import org.junit.Test;
public class ConstructorTest {
public static class ClassWithParameterizedConstructor {
public ClassWithParameterizedConstructor(final String param) {
// A parameterized constructor, no default constructor exists
}
}
#Test
public void testFoo() throws NoSuchMethodException {
// Parameterized constructor lookup works fine
ClassWithParameterizedConstructor.class.getConstructor(String.class);
// This doesn't work since there is no default constructor
ClassWithParameterizedConstructor.class.getConstructor();
}
}
So, a possible solution is to either change the call to getConstructor() to include the correct type or to provide a default constructor on the object itself (but why would you do that?).
Read this: http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html
It seems that both classes Class and Constructor have the method newInstance the difference is that in the Class class you can only call newInstance with no arguments, so the called constructor must have an no arguments (this also brings a problem when you have more that one constructor).
The methoe newInstance in the Constructor class allows you to call the constructor with arguments also, notice that you can also use the method getConstructors instead of getConstructor that returns you all the class constructors and allows you to call the constructor method you want.
In this case, since you only have one constructor only and with no arguments, Class.newInstance works fine. To use the getConstructor to have the same result you'll need to add in the end oCon.newInstance();
You can use getDeclaredConstructors() which returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object
class SomeClass{
{
System.out.println("I'am here!");
}
}
public class Main {
public static void main(String[] args) throws Exception{
System.out.println(Arrays.toString(SomeClass.class.getDeclaredConstructors()));
// returns public, protected, default (package) access, and private constructors
// System.out.println(SomeClass.class.getConstructor());
// in that case you got:
// NoSuchMethodException: reflection.SomeClass.<init>()
// because SomeClass don't have public constructor
for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
constructor.newInstance();
}
}
}
And if you have private constructor like this:
class SomeClass{
private SomeClass(String val){
System.out.println(val);
}
}
You have to set accessible for constructor:
constructor.setAccessible(true);
And get something like this:
class SomeClass{
private SomeClass(String val){
System.out.println(val);
}
}
public class Main {
public static void main(String[] args) throws Exception{
for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
// constructor.newInstance("some arg"); // java.lang.IllegalAccessException
constructor.setAccessible(true);
constructor.newInstance("some arg");
}
}
}
Note: if your class declared as private his default constructor must be private too.
And be careful with nonstatic-inner classes, which receives an outer class instance
In this (somewhat convoluted) scenario, it's actually possible to get hold of the (non-public) constructor by replacing:
Constructor<?> oCon = o.getConstructor();
with
Constructor<?> oCon = o.getDeclaredConstructor();
The "default" visibility of the Jeden class (and its constructor) makes it accessible to the Start class, since it's defined in the same package.

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.
}
}

Use constructor overload from within class constructor [duplicate]

Is it possible to call a constructor from another (within the same class, not from a subclass)? If yes how? And what could be the best way to call another constructor (if there are several ways to do it)?
Yes, it is possible:
public class Foo {
private int x;
public Foo() {
this(1);
}
public Foo(int x) {
this.x = x;
}
}
To chain to a particular superclass constructor instead of one in the same class, use super instead of this. Note that you can only chain to one constructor, and it has to be the first statement in your constructor body.
See also this related question, which is about C# but where the same principles apply.
Using this(args). The preferred pattern is to work from the smallest constructor to the largest.
public class Cons {
public Cons() {
// A no arguments constructor that sends default values to the largest
this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
}
public Cons(int arg1, int arg2) {
// An example of a partial constructor that uses the passed in arguments
// and sends a hidden default value to the largest
this(arg1,arg2, madeUpArg3Value);
}
// Largest constructor that does the work
public Cons(int arg1, int arg2, int arg3) {
this.arg1 = arg1;
this.arg2 = arg2;
this.arg3 = arg3;
}
}
You can also use a more recently advocated approach of valueOf or just "of":
public class Cons {
public static Cons newCons(int arg1,...) {
// This function is commonly called valueOf, like Integer.valueOf(..)
// More recently called "of", like EnumSet.of(..)
Cons c = new Cons(...);
c.setArg1(....);
return c;
}
}
To call a super class, use super(someValue). The call to super must be the first call in the constructor or you will get a compiler error.
[Note: I just want to add one aspect, which I did not see in the other answers: how to overcome limitations of the requirement that this() has to be on the first line).]
In Java another constructor of the same class can be called from a constructor via this(). Note however that this has to be on the first line.
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, 0.0);
}
public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
}
That this has to appear on the first line looks like a big limitation, but you can construct the arguments of other constructors via static methods. For example:
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, getDefaultArg3(argument1, argument2));
}
public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
private static double getDefaultArg3(double argument1, double argument2) {
double argument3 = 0;
// Calculate argument3 here if you like.
return argument3;
}
}
When I need to call another constructor from inside the code (not on the first line), I usually use a helper method like this:
class MyClass {
int field;
MyClass() {
init(0);
}
MyClass(int value) {
if (value<0) {
init(0);
}
else {
init(value);
}
}
void init(int x) {
field = x;
}
}
But most often I try to do it the other way around by calling the more complex constructors from the simpler ones on the first line, to the extent possible. For the above example
class MyClass {
int field;
MyClass(int value) {
if (value<0)
field = 0;
else
field = value;
}
MyClass() {
this(0);
}
}
Within a constructor, you can use the this keyword to invoke another constructor in the same class. Doing so is called an explicit constructor invocation.
Here's another Rectangle class, with a different implementation from the one in the Objects section.
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(1, 1);
}
public Rectangle(int width, int height) {
this( 0,0,width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
This class contains a set of constructors. Each constructor initializes some or all of the rectangle's member variables.
As everybody already have said, you use this(…), which is called an explicit constructor invocation.
However, keep in mind that within such an explicit constructor invocation statement you may not refer to
any instance variables or
any instance methods or
any inner classes declared in this class or any superclass, or
this or
super.
As stated in JLS (§8.8.7.1).
Yes, any number of constructors can be present in a class and they can be called by another constructor using this() [Please do not confuse this() constructor call with this keyword]. this() or this(args) should be the first line in the constructor.
Example:
Class Test {
Test() {
this(10); // calls the constructor with integer args, Test(int a)
}
Test(int a) {
this(10.5); // call the constructor with double arg, Test(double a)
}
Test(double a) {
System.out.println("I am a double arg constructor");
}
}
This is known as constructor overloading.
Please note that for constructor, only overloading concept is applicable and not inheritance or overriding.
Using this keyword we can call one constructor in another constructor within same class.
Example :-
public class Example {
private String name;
public Example() {
this("Mahesh");
}
public Example(String name) {
this.name = name;
}
}
Yes it is possible to call one constructor from another. But there is a rule to it. If a call is made from one constructor to another, then
that new constructor call must be the first statement in the current constructor
public class Product {
private int productId;
private String productName;
private double productPrice;
private String category;
public Product(int id, String name) {
this(id,name,1.0);
}
public Product(int id, String name, double price) {
this(id,name,price,"DEFAULT");
}
public Product(int id,String name,double price, String category){
this.productId=id;
this.productName=name;
this.productPrice=price;
this.category=category;
}
}
So, something like below will not work.
public Product(int id, String name, double price) {
System.out.println("Calling constructor with price");
this(id,name,price,"DEFAULT");
}
Also, in the case of inheritance, when sub-class's object is created, the super class constructor is first called.
public class SuperClass {
public SuperClass() {
System.out.println("Inside super class constructor");
}
}
public class SubClass extends SuperClass {
public SubClass () {
//Even if we do not add, Java adds the call to super class's constructor like
// super();
System.out.println("Inside sub class constructor");
}
}
Thus, in this case also another constructor call is first declared before any other statements.
I will tell you an easy way
There are two types of constructors:
Default constructor
Parameterized constructor
I will explain in one Example
class ConstructorDemo
{
ConstructorDemo()//Default Constructor
{
System.out.println("D.constructor ");
}
ConstructorDemo(int k)//Parameterized constructor
{
this();//-------------(1)
System.out.println("P.Constructor ="+k);
}
public static void main(String[] args)
{
//this(); error because "must be first statement in constructor
new ConstructorDemo();//-------(2)
ConstructorDemo g=new ConstructorDemo(3);---(3)
}
}
In the above example I showed 3 types of calling
this() call to this must be first statement in constructor
This is Name less Object. this automatically calls the default constructor.
3.This calls the Parameterized constructor.
Note:
this must be the first statement in the constructor.
You can a constructor from another constructor of same class by using "this" keyword.
Example -
class This1
{
This1()
{
this("Hello");
System.out.println("Default constructor..");
}
This1(int a)
{
this();
System.out.println("int as arg constructor..");
}
This1(String s)
{
System.out.println("string as arg constructor..");
}
public static void main(String args[])
{
new This1(100);
}
}
Output -
string as arg constructor..
Default constructor..
int as arg constructor..
Calling constructor from another constructor
class MyConstructorDemo extends ConstructorDemo
{
MyConstructorDemo()
{
this("calling another constructor");
}
MyConstructorDemo(String arg)
{
System.out.print("This is passed String by another constructor :"+arg);
}
}
Also you can call parent constructor by using super() call
There are design patterns that cover the need for complex construction - if it can't be done succinctly, create a factory method or a factory class.
With the latest java and the addition of lambdas, it is easy to create a constructor which can accept any initialization code you desire.
class LambdaInitedClass {
public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
init.accept(this);
}
}
Call it with...
new LambdaInitedClass(l -> { // init l any way you want });
Pretty simple
public class SomeClass{
private int number;
private String someString;
public SomeClass(){
number = 0;
someString = new String();
}
public SomeClass(int number){
this(); //set the class to 0
this.setNumber(number);
}
public SomeClass(int number, String someString){
this(number); //call public SomeClass( int number )
this.setString(someString);
}
public void setNumber(int number){
this.number = number;
}
public void setString(String someString){
this.someString = someString;
}
//.... add some accessors
}
now here is some small extra credit:
public SomeOtherClass extends SomeClass {
public SomeOtherClass(int number, String someString){
super(number, someString); //calls public SomeClass(int number, String someString)
}
//.... Some other code.
}
Hope this helps.
Yes it is possible to call one constructor from another with use of this()
class Example{
private int a = 1;
Example(){
this(5); //here another constructor called based on constructor argument
System.out.println("number a is "+a);
}
Example(int b){
System.out.println("number b is "+b);
}
You can call another constructor via the this(...) keyword (when you need to call a constructor from the same class) or the super(...) keyword
(when you need to call a constructor from a superclass).
However, such a call must be the first statement of your constructor. To overcome this limitation, use this answer.
The keyword this can be used to call a constructor from a constructor, when writing several constructor for a class, there are times when you'd like to call one constructor from another to avoid duplicate code.
Bellow is a link that I explain other topic about constructor and getters() and setters() and I used a class with two constructors. I hope the explanations and examples help you.
Setter methods or constructors
I know there are so many examples of this question but what I found I am putting here to share my Idea. there are two ways to chain constructor. In Same class you can use this keyword. in Inheritance, you need to use super keyword.
import java.util.*;
import java.lang.*;
class Test
{
public static void main(String args[])
{
Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
// You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
System.out.println("------------------------------");
Cat c = new Cat();
Cat caty = new Cat("10");
System.out.println("------------------------------");
// Self s = new Self();
Self ss = new Self("self");
}
}
class Animal
{
String i;
public Animal()
{
i = "10";
System.out.println("Animal Constructor :" +i);
}
public Animal(String h)
{
i = "20";
System.out.println("Animal Constructor Habit :"+ i);
}
}
class Dog extends Animal
{
public Dog()
{
System.out.println("Dog Constructor");
}
public Dog(String h)
{
System.out.println("Dog Constructor with habit");
}
}
class Cat extends Animal
{
public Cat()
{
System.out.println("Cat Constructor");
}
public Cat(String i)
{
super(i); // Calling Super Class Paremetrize Constructor.
System.out.println("Cat Constructor with habit");
}
}
class Self
{
public Self()
{
System.out.println("Self Constructor");
}
public Self(String h)
{
this(); // Explicitly calling 0 args constructor.
System.out.println("Slef Constructor with value");
}
}
It is called Telescoping Constructor anti-pattern or constructor chaining. Yes, you can definitely do. I see many examples above and I want to add by saying that if you know that you need only two or three constructor, it might be ok. But if you need more, please try to use different design pattern like Builder pattern. As for example:
public Omar(){};
public Omar(a){};
public Omar(a,b){};
public Omar(a,b,c){};
public Omar(a,b,c,d){};
...
You may need more. Builder pattern would be a great solution in this case. Here is an article, it might be helpful
https://medium.com/#modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e
Yes, you can call constructors from another constructor. For example:
public class Animal {
private int animalType;
public Animal() {
this(1); //here this(1) internally make call to Animal(1);
}
public Animal(int animalType) {
this.animalType = animalType;
}
}
you can also read in details from
Constructor Chaining in Java
Originally from an anser by Mirko Klemm, slightly modified to address the question:
Just for completeness: There is also the Instance initialization block that gets executed always and before any other constructor is called. It consists simply of a block of statements "{ ... }" somewhere in the body of your class definition. You can even have more than one. You can't call them, but they're like "shared constructor" code if you want to reuse some code across constructors, similar to calling methods.
So in your case
{
System.out.println("this is shared constructor code executed before the constructor");
field1 = 3;
}
There is also a "static" version of this to initialize static members: "static { ... }"
I prefer this way:
class User {
private long id;
private String username;
private int imageRes;
public User() {
init(defaultID,defaultUsername,defaultRes);
}
public User(String username) {
init(defaultID,username, defaultRes());
}
public User(String username, int imageRes) {
init(defaultID,username, imageRes);
}
public User(long id, String username, int imageRes) {
init(id,username, imageRes);
}
private void init(long id, String username, int imageRes) {
this.id=id;
this.username = username;
this.imageRes = imageRes;
}
}

Java constructor order of calling [duplicate]

I ended up the following scenario in code earlier today (which I admit is kinda weird and I have since refactored). When I ran my unit test I found that a field initialization was not set by the time that the superclass constructor has run. I realized that I do not fully understand the order of constructor / field initialization, so I am posting in the hopes that someone explain to me the order in which these occur.
class Foo extends FooBase {
String foo = "foobar";
#Override
public void setup() {
if (foo == null) {
throw new RuntimeException("foo is null");
}
super.setup();
}
}
class FooBase {
public FooBase() {
setup();
}
public void setup() {
}
}
#Test
public void testFoo() {
new Foo();
}
The abbreviated backtrace from JUnit is as follows, I guess I expected $Foo.<init> to set foo.
$Foo.setup
$FooBase.<init>
$Foo.<init>
.testFoo
Yes, in Java (unlike C#, for example) field initializers are called after the superclass constructor. Which means that any overridden method calls from the constructor will be called before the field initializers are executed.
The ordering is:
Initialize superclass (recursively invoke these steps)
Execute field initializers
Execute constructor body (after any constructor chaining, which has already taken place in step 1)
Basically, it's a bad idea to call non-final methods in constructors. If you're going to do so, document it very clearly so that anyone overriding the method knows that the method will be called before the field initializers (or constructor body) are executed.
See JLS section 12.5 for more details.
A constructor's first operation is always the invocation of the superclass constructor. Having no constructor explicitely defined in a class is equivalent to having
public Foo() {
super();
}
The constructor of the base class is thus called before any field of the subclass has been initialized. And your base class does something which should be avoided: call an overridable method.
Since this method is overridden in the subclass, it's invoked on an object that is not fully constructed yet, and thus sees the subclass field as null.
Here's an example of polymorphism in pseudo-C#/Java:
class Animal
{
abstract string MakeNoise ();
}
class Cat : Animal {
string MakeNoise () {
return "Meow";
}
}
class Dog : Animal {
string MakeNoise () {
return "Bark";
}
}
Main () {
Animal animal = Zoo.GetAnimal ();
Console.WriteLine (animal.MakeNoise ());
}
The Main function doesn't know the type of the animal and depends on a particular implementation's behavior of the MakeNoise() method.
class A
{
A(int number)
{
System.out.println("A's" + " "+ number);
}
}
class B
{
A aObject = new A(1);
B(int number)
{
System.out.println("B's" + " "+ number);
}
A aObject2 = new A(2);
}
public class myFirstProject {
public static void main(String[] args) {
B bObj = new B(5);
}
}
out:
A's 1
A's 2
B's 5
My rules:
1. Don't initialize with the default values in declaration (null, false, 0, 0.0...).
2. Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
3. If the value of the field changes because of a constructor parameter put the initialization in the constructors.
4. Be consistent in your practice. (the most important rule)
public class Dice
{
private int topFace = 1;
private Random myRand = new Random();
public void Roll()
{
// ......
}
}
or
public class Dice
{
private int topFace;
private Random myRand;
public Dice()
{
topFace = 1;
myRand = new Random();
}
public void Roll()
{
// .....
}
}

Java: Inherited class constructor is calling Super class

While creating a java program i encountered a problem,
A subclass constructor is throwing an Error by calling the Superclass's method
The code is similar to this :
class Manage
{
public static void main(String[] args)
{
Manager m1 = new Manager ( 35 );
}
}
class Employee
{
int emp_id;
public Employee(int id)
{
this.emp_id = id;
}
public int get_id()
{
return emp_id;
}
}
class Manager extends Employee
{
public Manager(int id )
{
this.emp_id = id ;
}
}
class Engineer extends Employee
{
public Engineer(int id)
{
this.emp_id = id ;
}
}
And the error is something like this :
$ javac app.java
app.java:25: cannot find symbol
symbol : constructor Employee()
location: class Employee
{
^
app.java:33: cannot find symbol
symbol : constructor Employee()
location: class Employee
{
^
2 errors
Why does this happen ?
The superclass doesn't have a default constructor. So you need to pass the appropriate constructor arguments to the superclass:
super(id);
(Put this as the top line in both the Manager and Engineer constructors.) You should also remove the this.emp_id = id line, in both cases.
In general, if your constructor doesn't start with a super(...) or this(...) statement (and you can only have one of these, not both), then it defaults to using super() (with no arguments).
Since you have specified a constructor with arguments, Java does not provide with a default constructor without arguments. You should create one yourself, or explicitly call the constructor you have created, by using super(id) as first line in the extended classes constructors.
The error is generated since you didn't define a default constructor (no arguments) in Employee
class Employee {
private int emp_id;
public Employee() {
}
public Employee(int id) {
this.emp_id = id;
}
public int get_id() {
return emp_id;
}
}
but there are a couple of points to consider: you are setting emp_id via the constructor and defined a getter to read it. It seems that the field was meant to be private. Otherwise you can just access directly.
You already have a constructor in Employee setting the ID no need to define the same constructor in the same class. Just use the constructor of the superclass.
class Manager extends Employee {
public Manager(int id ) {
super(id); // calls the superclass constructor
}
}
In this case you don't need the default constructor.
In java, a sub class constructor always calls one of its parent class's constructor. This is neccessary for the class to be initialized properly. Even when it is subclassed, the fields and state must be setup and this is how its done in java. If none is explicitly specified, it is calling the default no-arg constructor.

Categories

Resources