Here is my base class:
#Service
public class BasicUserManagerService implements UserManager {
#Autowired
private UserRepository UserRepository;
private Logger logger = LoggerFactory.getLogger(UserManagerPasswordController.class);
#Override
public void createUser(User User) {
if (UserRepository.findByEmail(User.getEmail()) != null)
throw new InvalidDataException("User already registered with this email address");
UserRepository.save(User);
logger.info("Created user: {}", User.getEmail());
}
}
I am trying to extend this class as follows:
#Service
public class UserManagerService extends BasicUserManagerService implements UserManager {
#Override
public void createUser(User User) {
super().createUser(User);
}
}
But I keep getting the error that the call to super() must be the first statement in the constructor body.
As you can see I don't have a constructor and even when I add it, I get the same error. Why is this happening and how can I avoid it?
Change this super usage. super() is parent's constructor. super is a reference to the parent class.
#Service
public class UserManagerService extends BasicUserManagerService implements UserManager {
#Override
public void createUser(ProxyCircuitUser proxyCircuitUser) {
super.createUser(proxyCircuitUser);
}
}
super() is a call to the parent class constructor;
which is not at all what you want.
Instead, you want to call the parent class implementation of the createUser method.
The code for that is: super.createUser(user)
Here are various uses of Super Keyword in Java:
Use of super with variables
This scenario occurs when a derived class and base class has same data members. In that case there is a possibility of ambiguity for the JVM.
/* Base class vehicle */
class Vehicle
{
int maxSpeed = 120;
}
/* sub class Car extending vehicle */
class Car extends Vehicle
{
int maxSpeed = 180;
void display()
{
/* print maxSpeed of base class (vehicle) */
System.out.println("Maximum Speed: " + super.maxSpeed);
}
}
/* Driver program to test */
class Test
{
public static void main(String[] args)
{
Car small = new Car();
small.display();
}
}
Output:
Maximum Speed: 120
Use of super with methods
This is used when we want to call parent class method. So whenever a parent and child class have same named methods then to resolve ambiguity we use super keyword.
/* Base class Person */
class Person
{
void message()
{
System.out.println("This is person class");
}
}
/* Subclass Student */
class Student extends Person
{
void message()
{
System.out.println("This is student class");
}
// Note that display() is only in Student class
void display()
{
// will invoke or call current class message() method
message();
// will invoke or call parent class message() method
super.message();
}
}
/* Driver program to test */
class Test
{
public static void main(String args[])
{
Student s = new Student();
// calling display() of Student
s.display();
}
}
Output:
This is student class
This is person class
Use of super with constructors
super keyword can also be used to access the parent class constructor. One more important thing is that, ‘’super’ can call both parametric as well as non parametric constructors depending upon the situation.
/* superclass Person */
class Person
{
Person()
{
System.out.println("Person class Constructor");
}
}
/* subclass Student extending the Person class */
class Student extends Person
{
Student()
{
// invoke or call parent class constructor
super();
System.out.println("Student class Constructor");
}
}
/* Driver program to test*/
class Test
{
public static void main(String[] args)
{
Student s = new Student();
}
}
Output:
Person class Constructor
Student class Constructor
As super() will call the constructor of parent class, it should be the first statement to be executed in child class's constructor. If you want to call a method of parent class use super instead of super().
For More Info please read: super in java
Related
Here is the code:
class Food {
Food() { printFlavor(); }
void printFlavor() { System.out.println("bland"); }
}
class Pepper extends Food {
void printFlavor() { System.out.println("spicy"); }
}
public class Lunch {
public static void main(String[] args) {
Food lunch = new Pepper();
}
}
When I ensure to run its own method of its own class with this keyword, it still runs base method.
class Food {
Food() { this.printFlavor(); }
void printFlavor() { System.out.println("bland"); }
}
class Pepper extends Food {
void printFlavor() { System.out.println("spicy"); }
}
public class Lunch {
public static void main(String[] args) {
Food lunch = new Pepper();
}
}
My question is not how to resolve this issue.
My question is why parent constructor chooses to call base method instead of parent method?
The reason is whenever you create an object of child class ,the constructor of parent class gets called first(by default) followed by the child class constructor.
To run the parent class method , you need to create parent class object
Food obj = new Food.
The object type that you are creating is not of Food Class , it is of Pepper Class.
If we have for example :
class Person {
// public void printInfos(){ }
}
class Student extends Person {
public void printInfos(){
System.out.println("studentInfos");
}
}
class Teacher extends Person(){
public void printInfos(){
System.out.println("teacherInfos");
}
}
main:
Person p1 = new Student();
Person p2 = new Teacher();
I want to write : p1.printInfos() and p2.printInfos() and print "studentInfos" & "teacherInfos" but I can't find a solution other than declaring an empty method inside the class Person (since we can't declare it as abstract and override it otherwise there will be no instanciation possible).
I feel that the declaration of an empty method is wrong even if it works.
You should exactly declare Person as interface. Logically, Person shouldn't be instantiated. Defining new class and empty-bodied method are superfluous in this case.
If you insist on the gobbledygook approach, there is no sane way to do that other than defining new class.
interface Person {
public void printInfos();
}
class Student implements Person {
#Override
public void printInfos(){
System.out.println("studentInfos");
}
}
class Teacher implements Person {
#Override
public void printInfos(){
System.out.println("teacherInfos");
}
}
main:
Person p1 = new Student();
Person p2 = new Teacher();
Please tell me more about your needs for this class. Is there any good reason why you would want to create Person instance?
If not it is clearly an abstract class for me and I think you should make it abstract.
You will still have option to declare constructor, some method that are "default" for the subclasses (an provide them an implementation) and make printInfos an abstract method.
abstract class Person {
abstract void printInfos();
}
class Student extends Person {
public void printInfos(){
System.out.println("studentInfos");
}
}
class Teacher extends Person{
public void printInfos(){
System.out.println("teacherInfos");
}
}
public abstract class Human{
public String name;
public int number
public void getInfo(){
Name = JOptionPane.showInputDialog("Please enter your name: ");
money = Double.parseDouble(JOptionPane.showInputDialog("Please enter amount of money .00: "));
}
public void displayInfo(){
JOptionPane.showMessageDialog(null,"Name: "+name+"\n"+
"Number: "+number);
}
}
public class Student extends Human {
}
public class Teacher extends Human{
}
public class Janitor extends Human{
{
I need help if calling the methods getInfo() and displayInfo() in all 3 classes below. I have tried:
public class Student extends Human{
public Student(){
getInfo();
displayInfo();
}
it works, but it generates a warning saying "problematic call in constructor" I guess it is not the best way to do it.
I also tried:
#Override
public void getInfo() {
}
but if I leave it empty nothing happens. Basically I am trying to call the method in the abstract class in a simple way without needing to type it up in every class.
As already mentioned, you shouldn't call overridable methods in constructors, because if another class overrides this method and invokes the constructor of the superclass, it may try to use values that are not initialized yet, since the overriden method will be invoked. Example:
public class Superclass {
protected int id;
protected void foo() {
System.out.println("Foo in superclass");
}
public Superclass() {
foo();
}
}
public class Subclass extends Superclass {
public Subclass(int id) {
super();
this.id = id;
}
#Override
protected void foo() {
System.out.println("Id is " + id);
}
}
This will print the unitialized value of id, since you first call the constructor of the superclass which invokes the foo method of the subclass.
You can fix this by making your methods final if this suits your case.
You get the warning because it's a good practice not to call overridables in the constructor; since these overridables could try to access member variables that are not initialized yet (== null) .
You shouldn't call overridable functions inside a constructor. check this link
public class Faculty extends Employee {
public static void main(String[] args) {
new Faculty();
}
public Faculty() {
super(“faculty”);
}
}
class Employee extends Person {
private String name;
public Employee() {
name = “no name”;
System.out.println("(3) Employee's no-arg constructor is invoked");
}
public Employee(String s) {
name = s;
System.out.println(s);
}
}
class Person {
//What if there was a parameterized constructor here
// e.g. public Person(String s){
// ... code ...
// }
}
In the above Java code, if i leave the Person class blank, and call super constructor in Faculty class' no-arg constructor, Employee's constructor would be called. But what if there is a parameterized constructor in the Person class. Which super constructor will be called? Employee one or Person one?
And is super constructor still invoked if i don't invoke a super constructor in subclass?
Your Employee class won't compile if you add a parametrized constructor to Person, as the default, no-args constructor will not be implied anymore, but your Employee constructors would need to invoke it.
Now, if your Person class featured both a no-args and a String-parametrized constructor (with the same Employee implementation), your code would compile, and either invocation of Employee's constructors would still invoke Person's no-args constructor first.
But what if there is a parameterized constructor in the Person class.
If you do that, you get a nice compilation error.
If your super class constructor has a parameter, your subclass shall invoke super(arguments) where arguments matches the parameter.
If the super class constructor does not have any parameters, your child class will implicitly invoke super(). Hence we don't have to explicitly invoke super() again.
Example:
class GrandParent
{
public GrandParent(String s){
System.out.println("Calling my grandpa");
}
}
class Parent extends GrandParent
{
public Parent(){
super("");
System.out.println("Calling my pa");
}
}
class Child extends Parent
{
public Child(){
//super() implicitly invoked
System.out.println("Calling my child");
}
}
Upon running the following:
class Test
{
public static void main(String[] args){
new Child();
}
}
You get:
Calling my grandpa
Calling my pa
Calling my child
The above output answers your subsequent questions:
Employee one or Person one?
And is super constructor still invoked if i don't invoke a super constructor in subclass?
In the following code:
import java.io.*;
public class MyClass1
{
MyClass1()
{
System.out.println("base class");
}
public void print()
{
System.out.println("base print");
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
System.out.println("child class");
}
public void print()
{
System.out.println("child print");
}
}
Why is it that when I create an instance of type ChildClass the constructor of the base class is also executed??
Because your child class extends the base class - it's an instance of the base class and has all of the same fields and variables, etc. Thus the base class must also be instantiated.
For a concrete example, imagine your base class had the following in:
public class Base
{
final private int id;
public Base()
{
this(-1);
}
public Base(int id)
{
this.id = id;
}
public getId()
{
return id;
}
}
A final variable is guaranteed to be instantiated when the class is constructed. Your child class will have an id field (even if it cannot access it directly with child methods), and since this field is private you cannot possible instantiate it with the child constructor - so a base class constructor must be called.
Bear in mind that this isn't solely an issue with final variables, nor is it unique to any particular features you may use - since your child class is a base class, it needs to be properly instantiated as one.
Because that's what's supposed to happen :-)
Your derived class uses the base class as a foundation. In OO speak it is-a base class. That base class also needs to initialise itself, and consequently its constructor must be called.
It's not obvious from your example, but it will make more sense if you give your base class some (protected) members. Initialise them in the base constructor, and consequently they will have the expected values when viewed from your derived class upon construction.
See below. The field value is visible in the child class. What would you expect as the initialised value ?
public class MyClass1
{
protected int value;
MyClass1()
{
System.out.println("base class");
this.value = 42;
}
}
class ChildClass extends MyClass1
{
public ChildClass()
{
// what would you expect 'value' to be here ?
System.out.println("child class " + value);
}
}
Because compiler by default add super() constructor in the child class constructor if it is not specified . Every Constructor Should have either this() in case of without inheritance or super() method when ever there is an inheritance . To illustrate it i have taken this example .
public class Vehicle {
protected int wheels;
protected int lights;
Vehicle(){
System.out.println("Vehicle Class Constructor");
this.wheels=4;
this.lights=2;
}
}
Vehicle is the parent class
class Car extends Vehicle {
public Car(){
#Compiler add the super() constructor by default
System.out.println("Car class constructor");
}
}
Car is the Child class
public class TestCar {
public static void main(String args[]){
Car c = new Car();
System.out.println("Wheels" + c.wheels);
System.out.println("Lights" + c.lights);
}
}
In above code snippet When i compile the TestCar.java file during the Compile time the compiler looks for the Car constructor and checks whether Car class has any parent as soon as it checks that Car class extends the parent class Vehicle , it checks whether user had provided super() in inheritance tree . if not it adds one .
Hope this helps !