I am new to Java. I have a problem to solve, but I don't quite understand how constructors work. I understand how to create a superclass and a subclass but I don't understand the constuctors within them (or how they actually work - I have done rediculous amounts of research on constructors, but it's just not making much sense).
I am trying to write a program that creates a superclass called Employees. This Employee class has instance variables employeeId (which is an integer) and employeeName (which is a String).
The subclass is called Manager. The Manager subclass has an instance variable called employeeTitle (which is a String). It also has a method with the name of managerDetails(). ManagerDetails() is supposed to display the employeeId, employeeName, and the employeeTitle.
This is what I have so far:
package tryingoutjava;
public class TryingOutJava {
class Employee {
int employeeId;
String employeeName;
void Employee() {
}
}
class Manager extends Employee {
String employeeTitle;
void managerDetails() {
}
}
public static void main(String[] args) {
}
}
I am very confused on how to set up the constructors for the superclass and the subclass, or even what a constructor really looks like. I've seen examples all over the internet, but no one actually highlights the actual part that is the constructor, or how everything is linked visually, which is what helps me learn.
I guess I'm also having issues with understanding how to set up a method that calls on an object. If anyone has the time to help, it would greatly be appreciated. Thanks!
I guess you want something like this. Be noted, that it is a good idea to separate classes one-per-file in this case, as they are separate entities here. It is a good idea to limit data access to entity fields, as such using encapsulation.
Employee.java:
package tryingoutjava;
public class Employee {
// Protected access because we want it in Manager
protected int employeeId;
protected String employeeName;
public Employee(int employeeId, String employeeName) {
this.employeeId = employeeId;
this.employeeName = employeeName;
}
}
Manager.java:
package tryingoutjava;
public class Manager extends Employee {
private String employeeTitle;
public Manager(String employeeTitle, int employeeId, String employeeName) {
// Use super to invoke Employee constructor
super(employeeId, employeeName);
this.employeeTitle = employeeTitle;
}
// Just create a simple string describing manager
#Override
public String toString() {
return "Manager{" +
"employeeTitle='" + employeeTitle +
"employeeId=" + employeeId +
", employeeName='" + employeeName + '\'' +
'}';
}
}
Application.java:
package tryingoutjava;
public class Application {
// Example of construction plus printing of Manager data
public static void main(String[] args) {
Employee davie = new Employee(1, "Dave The Cable Guy");
Manager tom = new Manager("CFO", 2, "Tomas");
System.out.println(tom.toString());
}
}
Constructors (most often than not) just delegate construction of parent through super invocation. While there are other techniques, like Builder pattern, this is the most basic and understandable approach. There are several other ways to do this, but this should get you started, hope it helps!
Purpose of Constructor
constructor is a method like other method but it is called when instantiate (or create a object from your class) for initialize your object for first use or later use. for example a class like Student must created (instantiated) when we give it name and family name for example. Without them, create a Student is not good because maybe we forget to give it proper name and use it incorrectly. constructor forces us to provide minimum things needed for instantiating objects from classes.
Constructor implementation in inheritance
About inheritance, it is different. When you want to create a Student which is a Human (extends Human) you must first create Human inside your Student and set special feature for your Student like ID which is not for Human (Human has name and etc). so when you create a Student with constructor, the super constructor (for Human) is called too.
What do we do in constructor
as I mentioned, we provide default value for our properties which must set them before creating and using object. (for using them properly) every subclass call super class constructor implicitly with super() but if super class doesn't have any default constructor (constructor with no argument) you must explicitly say super(...) at the first lien of subclass constructor (otherwise compile error)
What is the program steps when using constructor (Advanced)
super class static constructor and static variable (read by self if you want to know more about things I say here)
subclass class static constructor and static variable
super class variable and block constructor
super class constructors
sub class variable and block constructor
sub class constructors
I only mentioned 4 & 6.
I try to explain completely. My English is not good. I'm sorry.
If you know how a method works, then you know how a constructor works. The constructor is simply a special method that allows you to execute some code before the object is created.
Person p = new Person("Bob", 25); // Calls constructor Person(String name, int age)
Then in the constructor you can do things like assign initial values to any instance variables.
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
If the class is a subclass you need to call a constructor of the parent class before the object is created unless the parent class has a constructor with no parameter in which case java can call it for you if you don't specify anything. Here Worker extends Person.
private String occupation;
public Worker(String name, int age, String occupation) {
super(name, age) // Calls constructor Person(String name, int age)
this.occupation = occupation;
}
I guess you can achieve what you want in a single file via the code snippet below:
You can copy paste it in your code and it should work.
You can see how the constructor of parent class is being called by the help of super() and also the methods. Here I have used methods like getEmployeeTitle() which should help you get an overview on how to write methods. I have also overridden the toString() method so that you can understand how to override Object class' useful methods like toString().
Note : Although I have created all the classes in one code snippet for the sake of simplicity , but it is highly recommended that you create a separate file for each of these classes.
class Employee {
int employeeId;
String employeeName;
Employee(int employeeId, String employeeName) {
this.employeeId = employeeId;
this.employeeName = employeeName;
}
}
class Manager extends Employee {
private String employeeTitle;
Manager(int employeeId, String employeeName, String employeeTitle) {
super(employeeId, employeeName);
this.employeeTitle = employeeTitle;
}
public String getEmployeeTitle() {
return employeeTitle;
}
#Override
public String toString() {
return ("employeeId: " + employeeId + ", employeeName: " + employeeName + ", employeeTitle" + employeeTitle);
}
}
public class TryingOutJava {
public static void main(String[] args) {
Manager manager = new Manager(007, "John Doe", " Sr. Manager");
System.out.println(manager);
System.out.println(manager.getEmployeeTitle());
}
}
Related
I am trying to set specific values of objects in an Array with a method.
public class BankAccount
{
private String name;
//constructor
public BankAccount(String firstName, String LastName)
{
name = firstName + " " + lastName;
}
public String getName()
{
return name;
}
Above is my BankAccount class, and I have another class named BankAccountList:
public class BankAccountList {
public static void main(String args[]){
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1] = giveName("MR", "Travis");
}
public static void giveName (String firstName, lastName){
}
}
How do I set the object name in BankAccount[1] to "Mr Travis" with the following giveName() method? I don't know what to put in giveName with the given parameter. Any tips would be much appreciated.
Your giveName method should return the type BankAccount:
public static BankAccount giveName (String firstName, String lastName){
return new BankAccount(firstName, lastName);
}
Edit:
Simply declaring new BankAccount[] does not populate any entries in the array (which you might expect based on experiences with other languages). The array will initially be empty, and there are multiple ways to populate it:
Inside a loop you could:
Call the BankAccount constructor directly
Delegate to another method that returns a new .collect(Collectors.toSet()) (as the example above does)
This choice, like most programming decisions, is mostly personal preference. For a simple DTO with 2 string fields, delegating to another method might be overkill.
For a more complex DTO that requires validation, delegating to another method helps encapsulate that validation logic in a single place that is easily testable.
There are a few things worth mentioning here.
First of all, it seems like you do not have a complete understanding of the difference between static and dynamic. It is understandable, as I even now would have a hard time explaining it easily, even though I understand how it works. Your BankAccountList class has a main method, started from a static standard main method. your bankAccount array is defined within this main method, meaning it does not exist in the whole class, only inside the running main method.
Then you want to give name to a bank account in the list. Here you have created another static method, which knows nothing about what is inside your main method, and it does not contain any object which the parameters can be given to. In other words the empty function you have now, can't set any parameters to a bank account, because no bank account exists within the method.
I would recommend making the giveName method dynamic (which means just removing the static keyword), and move the method to the BankAccount class. Then you will efficiently have both a get and set method for name, which are dynamic, meaning it is valid per object instance of the class. After that, it is possible to first refer to an object in the array, and directly call the giveName() method on that particular object, which will set the name:
public class BankAccount
{
private String name;
//constructor
public BankAccount(String firstName, String LastName)
{
name = firstName + " " + lastName;
}
public String getName()
{
return name;
}
public void giveName (String firstName, String lastName){
name = firstName + " " + lastName;
}
and:
public class BankAccountList {
public static void main(String args[]){
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1].giveName("MR", "Travis");
}
}
UPDATE:
I noticed now another thing. The line where you create the array:
BankAccount bankAccount[] = new BankAccount[2];
This does not create a populated array, it creates an empty array. in other words, you have not created a list with bank accounts, you have created a list which can hold bank accounts. You will have to create a bank account first, before being able to give it a name.
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1] = new BankAccount("MR", "Travis");
Now, your constructor already has parameters for giving an account a name, when created. So now you don't really need the giveName method. Unless you want to change it later:
bankAccount[1].giveName("MRS", "Davis");
You don't really need to use giveName method, you could just do it like this:
bankAccount[1] = new BankAccount("MR", "Travis");
But, if you really need to do it using a giveName method, you could do it like this:
// change signature to return `BankAccount` object
public static BankAccount giveName (String firstName, String lastName){
return new BankAccount(firstName, lastName);
}
and call it like this: bankAccount[1] = giveName("MR", "Travis");
If you need giveName to have void as return type, then you need to pass the array in order to add the BankAccount inside the method and the position were it will be added. Like this:
// change in order to signature receive an array of `BankAccount`s and the position where it will be added
public static void giveName (String firstName, String lastName, BankAccount[] bankAccounts, int position) {
bankAccounts[position] = new BankAccount(firstName, lastName);
}
and then call it like this: giveName("MR", "Travis", bankAccount, 1);
Additional notes:
Remember array positions start at index 0, not 1, so you might want to consider adding bank account from 0, not 1, like this:
This is the case if giveName is in the BankAccountList class. Otherwise, go for KjetilNordin's answer.
bankAccount[0] = giveName("MR", "Travis");
You defined an array that will hold BankAccount objects, so to add elements into it with the function giveName() you need to modify that function as following :
public class BankAccountList {
public static void main(String args[]){
BankAccount bankAccount[] = new BankAccount[2];
bankAccount[1] = giveName("MR", "Travis");
}
public static BankAccount giveName (String p_firstName,String p_lastName){
return new BankAccount(p_firstName, p_lastName)
}
}
You need set methods!
Add this to class BankAccount:
public void setName(String firstName, String lastName) {
this.name = firstName + " " + lastName;
}
so you should call setName instead of giveName. Like this:
bankAccount[1].setName(String firstName, String lastName)
Another thing, I suggest you use the set method in the constructor of your object:
//constructor
public BankAccount(String firstName, String LastName)
{
setName(String firstName, String lastName);
}
public void setName (String n){}
public void setAfm (String a){}
These are the Superclass methods i need to call.
SalariedEmployee (){
name = super.setName(String n);
afm = super.setAfm(String a);
salary = payment();
And thats the constructor in the subclass. How can i call the methods properly. I don't want to use any parameters in SalariedEmployee, i want to set the name and afm with the superclass methods. But my methods are void. So i guess i have to change that right ? Or am I missing something else?
Thanks in advance!
EDIT : You can also use setters. The "super" keyword is mandatory only if you want to call a method from the superclass that you have overridden in the subclass.
You should use constructors to set initial values but using setters is a possible solution too :
class Employee {
String name;
String afm;
public Employee() {
}
public Employee(String name, String afm) {
super();
this.name = name;
this.afm = afm;
}
public void setName(String name) {
this.name = name;
}
public void setAfm(String afm) {
this.afm = afm;
}
}
class SalariedEmployee extends Employee {
//Using constructors
public SalariedEmployee(String name, String afm) {
super(name, afm);
salary = payment();
}
//using setters
public SalariedEmployee() {
setAfm("afm");
setName("name");
salary = payment();
}
}
Also a setter method like 'setName' should be void because you don't expect it to return anything unlike a getter method like 'getName' for example.
There are two cases when you want to call a super method. The first case is that the method was not overriden by the subclass. If that is the case, you can call those methods simply by calling
setName("Dick Aceman");
or
setAtf("Acebook");
It is more descriptive if you call them like this:
this.setName("Dick Aceman");
this.setAtf("Acebook");
The bulletproof way to call them is this:
super.setName("Dick Aceman");
super.setAtf("Acebook");
This last one works even if the methods were overriden, but in general it is considered to be too descriptive, so this kind of method call should be used only when there is no alternative. Note, that since your methods are public, they are inherited by subclasses.
The problems with your try were that:
you tried to assign the return value of the methods to variables, when the methods do not return values
you declared the type at method call, which is invalid
you used the undefined variables of a and n
You should watch a few tutorial videos, you will get the basics then. After you watch such a video or two, you should return to this answer.
My assignment:
Code a class called SeniorWorker which inherits from Employee class, in addition to name, salary, and overtimePay, it adds a double type data called meritPay which is calculated as 10% of the salary. It overrides earning() and toString methods to compute the total salary of SeniorWorker and return proper data of SeniorWorker, respectively.
Clarification: The assignment lets us use some example code from the book (Employee,RegularWorker,Manager, SeniorManager. java). My problem is that the SeniorWorker class inherits from the Employee class all those variable however the Employee class only includes the name variable and the rest of the variables except the meritPay are in the RegularWorker Class that why I'm wondering if I could inherit from both the Employee class and RegularWorker or do I need to do something else?
Code:
public class Employee {
private String name;
// Constructor
public Employee(String name ) {
this.name = name;
}
public String getName()
{ return name; }
public double earnings(){return 0.0;}
}
public class RegularWorker extends Employee {
protected double salary, overtimePay;
public RegularWorker( String name, double salary, double overtimePay) {
super( name ); // call superclass constructor
this.salary = salary;
this.overtimePay = overtimePay;
}
public double earnings() { return salary + overtimePay; } //override the method to return salary
public String toString() { //override the method to print the name
return "Regular worker: " + getName();
}
}
My Class:
So far i've just resorted to inheriting from the regularworker class(and it works) , however the assignment says i should inherit from employee class.
public class SeniorWorker extends RegularWorker {
public double meritPay;
public SeniorWorker(String name, double salary,double overtimePay, double meritPay)
{
super(name,salary,overtimePay);
this.meritPay = meritPay;
}
public double getMeritPay() {
return meritPay;
}
public void calculateMeritPay(){
meritPay = 0.10 * salary;
}
public double earnings() { return salary + overtimePay + meritPay; } //override the method to return salary
public String toString() { //override the method to print the name
return "Senior Worker: " + getName();
}
}
No, in java you can only inherit from one class. However, that class can inherit from another, and so on. You can extend multiple interfaces, which in java 8 could contain default method implementations (which could be default getters that return a predetermined value for the encapsulated attributes).
However, inheritance should only really be used for code sharing, and interfaces should only really be used for polymorphism.
Having said that, in your example, your RegularWorker is an Employee, so your SeniorWorker is a RegularWorker and is an Employee. Therefore, your SeniorWorker is inheriting (is extended from) Employee, as your assignment requests.
But, if you think about it, how can a senior worker also be a regular worker? They're not regular, they're senior. They may have been regular at one point in their career, but now they're senior, and not regular at all, despite having some stuff in common with regular employees. If you push the stuff from regularemployee up to employee, and have two descendants of employee, regular and senior, then you'll have sorted this mess out and probably earned extra points for being clever.
I am very new to Java. I know the basic concepts of constructors. I know that, if we don't create any constructor also compiler will create default constructor.
I have created a program to check how this toString() method is usable,
public class Vehicle{
int rollNo;
String name;
int age;
public Vehicle(int rollNo, String name, int age){
this.rollNo=rollNo;
this.name=name;
this.age=age;
}
public String toString(){
return rollNo+""+name+""+age;
}
public static void main(String[] args){
Vehicle v=new Vehicle(100, "XXX", 23);
Vehicle v2=new Vehicle(101, "XXXS", 24);
System.out.println(v);
System.out.println(v2);
}
}
And, I am getting output as :
100XXX23
101XXXS24
But, my doubt is why are we creating constructor and passing same variables as arguments to that?
Why can't we assign the values to variables like this and can't we get values without constructor?
public class Vehicle{
int rollNo=100;
String name="XXX";
int age=23;
// public Vehicle(int rollNo, String name, int age){
// this.rollNo=rollNo;
// this.name=name;
// this.age=age;
// }
//
public static void main(String[] args){
// Vehicle v=new Vehicle(100, "XXX", 23);
// Vehicle v2=new Vehicle(101, "XXXS", 24);
Vehicle v=new Vehicle(rollno,name,age);
// Vehicle v2=new Vehicle();
System.out.println(v);
// System.out.println(v2);
}
public String toString(){
return rollNo+""+name+""+age;
}
}
Firstly, it is possible to set the values of attributes or properties without a defined constructor in the class definition. This can be done through the use of setters on the attributes/properties within a Java class. So for example:
public class Vehicle{
int rollNo;
String name;
int age;
// Note no constructor, so the default no-arg constructor can be used.
// Now the setters
public void setRollNo(int anInt) {
this.rollNo = anInt;
}
public String setName(String aName) {
this.name = aName;
}
public void setAge(int anAge) {
this.age = anAge;
}
public static void main(String[] args){
Vehicle v=new Vehicle(); // note no-arg constructor being used.
v.setRollNo(3);
v.setName("Hello");
v.setAge(12);
System.out.println(v);
}
}
The use of setters is far better as you adhere to an important OOP principle; that of encapsulation, which in Java and Software is quite critical.
Please have a look at the following Java Tutorial from Oracle that goes through the use of getters and setters and the use of constructors.
The main method is declared static, which means that it doesn't belong to any particular copy of your class. If you want to create copies of the class to use for whatever purpose, you use new, which causes the constructor to build a copy for you, and in your case set the appropriate variables (which belong to particular copies of the class, like the copies that you're holding in the v and v2 variables).
The fact that the main method is part of the same class is essentially irrelevant; main could be attached to any class, even an otherwise empty one.
The reason why you have to use Constructor having arguments is that created instance is immutable objects which means that whose state cannot be modified after it is created. In other words object does not have setter it only has getter methods.
In java platform GC is the main part of JVM, and immutable objects makes GS less work to clean the unusable objects in heap memory.
Pls refer to link http://c2.com/cgi/wiki?ImmutableObjectsAndGarbageCollection
The default constructor from the compiler will be the following.
public Vehicle()
If you don't define
public Vehicle(int rollNo, String name, int age)
then it won't exist and you can't use it.
Java does not create default constructors with arguments.
I am confused on how to get parameters from new object instances to also flow into the super class to update the private fields in teh super class.
So I am in an advanced Java class and I have homework that requires a "Person" Super Class and a "Student" subclass that extends Person.
The Person class stores the student name BUT it is the Student class constructor that accepts the Person name.
assume no method in Person to make a variable method update...like subClassVar = setSuperClassVar();
EX:
public class Person
{
private String name; //holds the name of the person
private boolean mood; //holds the mood happy or sad for the person
private int dollars; //holds their bank account balance
}
class Student extends Person //I also have a tutor class that will extend Person as well
{
private String degreeMajor //holds the var for the student's major they have for their degree
Public Student(String startName, int startDollars, boolean startMood, String major)
{
degreeMajor = major; // easily passed to the Student class
name = startName; //can't pass cause private in super class?
mood = startMood; //can't pass cause private in super class?
dollars = startDollars; // see above comments
// or I can try to pass vars as below as alternate solution...
setName() = startName; // setName() would be a setter method in the superclass to...
// ...update the name var in the Person Superclass. Possible?
setMood() = startMood; // as above
// These methods do not yet exist and I am only semi confident on their "exact"...
// ...coding to make them work but I think I could manage.
}
}
The instructions for the homework were a bit vague in terms of how much changing to the superclass of Person I am allowed to make so if you all believe a good solid industry accepted solution involves changing the superclass I will do that.
Some possible examples I see would be to make the private vars in Person class "protected" or to add setMethods() in the person class and then call them in the sub class.
I am also open to general concept education on how to pass subclass contstructor parameters to a super class...and if possible do that right in the constructor portion of the code.
Lastly, I did search around but most of the similiar questions were really specific and complicated code....I couldnt find anything straight forward like my example above...also for some reason the forum post did not clump all of my code together so sorry for the confusing read above.
Thanks all.
First, you need to define a constructor for Person:
public Person(String startName, int startDollars, boolean startMood)
{
name = startName;
dollars = startDollars;
mood = startMood;
}
Then you can pass data up from the Student constructor using super(...):
public Student(String startName, int startDollars, boolean startMood, String major)
{
super(startName, startDollars, startMood);
. . .
}
Alternatively, you can define setters in the Person class and invoke them from the Student constructor.
public class Person
{
private String name; //holds the name of the person
private boolean mood; //holds the mood happy or sad for the person
private int dollars; //holds their bank account balance
public void setName(String name) {
this.name = name;
}
// etc.
}