Initializing parent variables in Child Class - java

This is my parent class
abstract public class Person {
private String name;
private Date birthday;
private double difficulty;
protected abstract String personType();
protected abstract Person clone();
Person(String name, Date birthday, double difficulty) {
this.name = name;
this.birthday = birthday;
this.difficulty = difficulty;
}
Person(Person copy) {
this.name = copy.name;
this.birthday = copy.birthday;
this.difficulty = copy.difficulty;
}
Person(){
this.name = "";
this.birthday = new Date();
this.difficulty = 0;
}
public String getName() {
return this.name;
}
public Date getBirthday() {
return this.birthday;
}
public double getDifficulty() {
return this.difficulty;
}
And I want to make a subclass called Singer with the same constructor variables. My question is, how do I initialize the variables "name", "birthday", and "difficulty" in the Singer subclass by calling onto the parent class Person?
public class Singer extends Person{
String debutAlbum;
Date debutAlbumReleaseDate;
Singer(String name, Date birthday, double difficulty, String debutAlbum, Date debutAlbumReleaseDate){
this.debutAlbum = debutAlbum;
this.debutAlbumReleaseDate = debutAlbumReleaseDate;
//im not sure what to put here for name, birthday, and difficulty
}
}

You can use 1 of these 3:
Using super() method (recommended):
Add in the first line on the constructor this line super(name, birthday, difficult).
This line will call the constructor of Person class for your object.
Notice: super method can be used only in the first line of the constructor
Add set() method:
In the Person class, add set method for each variable and then call them in the constructor.
Change access modifications:
Change the access modifications of each variable in Person class to protected or public and then use this.name = name;.

Related

Variable within constructor is returning null?

I am doing a project based around the concepts of inheritance and have created a super constructor which has two variables within itself (String, int), this super constructor is then called within a sub constructor that inherited the super constructors class. I then use two methods to return the properties of those variables within the constructors. The age property is outputting fine but the String property is returning null. Here's the code:
Animal super-class
abstract public class Animal
{
int age;
String name;
Animal(String name, int age)
{
this.age = age;
this.name = name;
}
Animal()
{
this("newborn", 0);
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
}
Wolf sub-class
public class Wolf extends Carnivore
{
String name;
int age;
Wolf(String name, int age)
{
this.name = name;
this.age = age;
}
Wolf()
{
super();
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
Main method class
public class Main {
public static void main(String[] args)
{
Wolf newWolf = new Wolf();
System.out.println("Name = " + newWolf.getName());
System.out.println("Age = " + newWolf.getAge());
}
}
Age is returning as 0 which is correct but System.out.println("Name = " + newWolf.getName()); seems to be returning null instead of "newborn". Any help on resolving this issue is appreciated thanks.
Update - I need the getName() method for another constructor that I haven't included in this example so is there a way to have them both exist?
The issue here is that you are defining your fields in the sub-class, you don't need to as they are inherited from the parent.
Your class has two sets of fields, one from the super (these are the ones set by your constructor, which is calling super() and the other from the child class (these are the ones returned by your getters, which are not initialized. the zero is int's default, not set either).
So simply remove the fields definition from the child class

How to correctly configure multiple constructors?

I'm doing an assignment based around inheritance and I have created 2 constructors that are suppose to do different things. One constructor does not have any parameters and should produce a pre-defined value, the other constructor has 2 parameters which consist of a name and an age of types String and int. I have somehow reconfigured the two constructors so that they both do not produce what they should be. Here is the classes that these constructors are invoked in:
Animal (super class)
abstract public class Animal implements Comparable<Animal>
{
int age;
String name;
Animal(String name, int age)
{
this.age = age;
this.name = name;
}
Animal()
{
this("newborn", 0);
}
public int getAge()
{
return age;
}
public void setName(String newName)
{
name = newName;
}
String getName()
{
return name;
}
}
Carnivore
public class Carnivore extends Animal
{
Carnivore(String name, int age)
{
this.age = age;
this.name = name;
}
Carnivore()
{
super();
}
#Override
public int compareTo(Animal o)
{
//To change body of generated methods, choose Tools | Templates.
throw new UnsupportedOperationException("Not supported yet.");
}
}
Wolf
public class Wolf extends Carnivore
{
String name;
int age;
Wolf(String name, int age)
{
this.name = name;
this.age = age;
}
Wolf()
{
super();
}
String getName()
{
return name;
}
}
Main method
System.out.println("************1st constructor of Wolf************");
Wolf wolfExample = new Wolf("Bob", 2) {};
System.out.println("Name = " + wolfExample.getName());
System.out.println("Age = " + wolfExample.getAge());
System.out.println("************2nd constructor of Wolf************");
Wolf newWolf = new Wolf();
System.out.println("Name = " + newWolf.getName());
System.out.println("Age = " + newWolf.getAge());
Actual Output
************1st constructor of Wolf************
Name = Bob
Age = 0
************2nd constructor of Wolf************
Name = null
Age = 0
Expected Output
************1st constructor of Wolf************
Name = Bob
Age = 2
************2nd constructor of Wolf************
Name = newborn
Age = 0
The ages are returning their default value and the name for the second constructor is also returning null but I'm not too sure why. This is my first time working with multiple constructors so I'm a little confused as to ow it works so any help would be much appreciated, thanks.
Your base class seems correct, but you need to change your implementations.
Your Wolf and Carnivore constructors should be:
Wolf(String name, int age)
{
super(name, age);
}
Reason being, you are setting the local instance variables for each type, but calling getAge() method of the super class - this is getting the super's value of age, whose's value has not actually been assigned anywhere, and is given a default value of 0. This goes the same for name, which defaults to null.
You need to call super with the passed variables, and do not need to redefine them for each extended object.

Polymorphism issue

I have been reading on how to program Java 8 Polymorphism.
I have this code:
public class Person
{
// instance variables - replace the example below with your own
private String lastname;
private String firstname;
private int age;
private boolean married;
private float salary;
/**
* Constructor for objects of class Person
*/
public Person(String lastname, String firstname, int age, boolean married, float salary)
{
// initialise instance variables
this.lastname = new String(lastname);
this.firstname = new String(firstname);
this.age = age;
this.married = married;
this.salary = salary;
}
public String getLastName() {return lastname;}
public String getFirstName() {return firstname;}
public int getAge() {return age;}
public boolean isMarried() {return married;}
public float getSalary() {return salary;}
}
public class MarriedPerson extends Person
{
// instance variables - replace the example below with your own
private int children;
/**
* Constructor for objects of class MarriedPerson
*/
public MarriedPerson(String lastname, String firstname, int age, float salary, int children)
{
// initialise instance variables
super(lastname, firstname, age, true, salary);
this.children = children;
}
public int getNoOfChildren()
{
// put your code here
return children;
}
}
abstract class MyTester
{
public static void main(String[] args) {
Person p1 = new Person("Kings", "Paul", 22, true, 1200f);
MarriedPerson mp1 = new MarriedPerson("Tront", "Betty", 31, 980.5f, 3);
System.out.print(p1.getFirstName()+" "+p1.getLastName()+" is "
+p1.getAge()+" years old, gets a "+p1.getSalary()
+" Euros salary and is");
if (p1.isMarried() == false)
System.out.print(" not");
System.out.println(" married.");
System.out.print(mp1.getFirstName()+" "+mp1.getLastName()
+" is " +mp1.getAge()+ " years old, gets a " + mp1.getSalary()
+" Euros salary and is" + " married with ");
if (mp1.getNoOfChildren() > 0)
System.out.print(mp1.getNoOfChildren());
else System.out.print("no");
System.out.println(" children.");
}
}
Reading from a book, I have not seen an abstract class that contains the main function so I am a bit confused.
Why have we declared MyTester class as abstract? Is this necessary?
I have now created a printInfo method in class Person. See following code:
public class Person
{
// instance variables - replace the example below with your own
private String lastname;
private String firstname;
private int age;
private boolean married;
private float salary;
/**
* Constructor for objects of class Person
*/
public Person(String lastname, String firstname, int age, boolean married, float salary)
{
// initialise instance variables
this.lastname = new String(lastname);
this.firstname = new String(firstname);
this.age = age;
this.married = married;
this.salary = salary;
}
public String getLastName() {return lastname;}
public String getFirstName() {return firstname;}
public int getAge() {return age;}
public boolean isMarried() {return married;}
public float getSalary() {return salary;}
public void printInfo(){
System.out.print(p1.getFirstName()+" "+p1.getLastName()+" is "
+p1.getAge()+" years old, gets a "+p1.getSalary()
+" Euros salary and is");
if (p1.isMarried() == false)
System.out.print(" not");
System.out.println(" married.");
}
}
abstract class MyTester
{
public static void main(String[] args) {
Person p1 = new Person("Kings", "Paul", 22, true, 1200f);
MarriedPerson mp1 = new MarriedPerson("Tront", "Betty", 31, 980.5f, 3);
p1.printInfo();
mp1.printInfo();
}
}
When I compile the modified code it give me the error: cannot find symbol - variable p1. Why is that? What do I need to do in order to fix that?
What advantages second code has over first one?
It does not make sense MyTester to be abstract since it does not have any abstract method. The only reason might be to prevent the instantiation of MyTester class because it might not make sense for an instance to exist.
MyTester is declared abstract so you can't create any instances of it (there is no reason you would want to). See this link, it says:
An abstract class is a class that is declared abstract—it may or may
not include abstract methods. Abstract classes cannot be instantiated,
but they can be subclassed.
When I compile the modified code it give me the error: cannot find symbol - variable p1. Why is that? What do I need to do in order to fix that?
For future reference: You should create a new question and not edit your existing one. Also, if someone solved your first problem you should allways be so nice as to accept their answer. ;)
Anyway: You are getting that error because your object is only "known" as p1 in your main class.
In your "printInfo()" method you are trying to have the objects do calls on itself. So either just remove the "p1." part and just call the methods like "getFirstName()", or explicitly call "this.getFirstName()".
("this" is a java keyword refering to the current object instance.)
A tipp for you: Get a good JAVA IDE like Eclipse (https://eclipse.org/) and you will see simple errors like those even before compiling.
No. It makes no difference, as the class is never extended or used except as an entrypoint.

how to call superclass parameterized constructor by subclass?

Why i am getting error in the starting of Employee constructor that cannot find symbol
constuctor Person?
class Person {
String name = "noname";
Person(String nm) {
name = nm;
}
}
class Employee extends Person {
String empID = "0000";
Employee(String eid) {// error
empID = eid;
}
}
public class EmployeeTest {
public static void main(String args[]) {
Employee e1 = new Employee("4321");
System.out.println(e1.empID);
}
}
You need to call
super(name);
as the first statement of the constuctor Employee as the compiler will otherwise implicitly call the no-argument constructor for Person which doesnt exist
where name is an added argument to Employee
Employee(String eid, String name) {
super(name);
empID = eid;
}
Take a look at example 8.2-1 from the JLS which shows how a similar example fails in the absence of an explicit super method call.
When you create an employee, you'll need to specify both a name and an employee id - since every employee is a person, and every person needs a name. The constructor for Employee should probably look like this.
public Employee(String eid, String name) {
super(name);
empID=eid;
}
The super line specifies how to call the superclass's constructor. It needs to be in there because there's no constructor for the superclass without parameters. A superclass constructor must be called, there's only one available constructor, and that constructor needs the name argument to be specified.
You should do something like this to get your program to work:
class Person {
String name = "noname";
Person(String name) {
this.name = name;
}
}
class Employee extends Person {
String empID = "0000";
Employee(String empID , String name) {
super(name);
this.empID = empID;
}
}
public class EmployeeTest {
public static void main(String args[]) {
Employee e1 = new Employee("4321" , "Ramesh");
System.out.println(e1.empID);
System.out.println(e1.name);
}
}
I have a couple of points to add.
It is always a good habit to make your data member private. If you want to access those members outside the class, use getters and setters. ( getName(), setName() etc. )
Your constructors ( Person() and Employee() ) HAVE to be defined if you want to creating an object without using parameterized constructor. NO default contstructor will be provided for you if you want to instantiate using a non-parameterized constructor. So do THIS whenever you are using a parameterized constructor as a good habit:
class Person {
private String name = "noname";
Person() {}
Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
class Employee extends Person {
private String empID = "0000";
Employee() {}
Employee(String empID,String name) {
this.empID = empID;
}
public String getEmpID() {
return this.empID;
}
public void setName(String empID) {
this.empID = empID;
}
}

Display class objects from a class method

I've created class Person, which is extended by classes Student and Employee (which is extended by other Employee type classes). The person class looks like:
String name;
int ssn;
int age;
String gender;
String address;
String PNumber;
static int count;
//empty constructor
public Person(){
count++;
}
//print count
public static void printCount(){
System.out.println("The number of people is: "+ count);
}
//constructor with name
public Person(String name){
this.name = name;
count++;
}
/*constructor to create default person object*/
public Person(String name, int ssn, int age, String gender, String address, String PNumber)
{
this.name = name;
this.ssn = ssn;
this.age = age;
this.gender = gender;
this.address = address;
this.PNumber = PNumber;
count++;
}
I'm currently trying to create a method that will display all Persons if they're gender = "Male". I have:
//display Males
public void print(String gender){
if(this.gender.contentEquals(gender)){
//print out person objects that meet this if statement
}
}
I'm not sure how to refer to the objects (students and employees that are all persons) within the method to return them. And I also don't know how to refer to this method in the main method. I can't use Person.print, but if I use
Person james = new Person();
and then use
james.print("Males");
I'm only returning james (and the method doesn't make sense in that context).
Any help appreciated.
First, the print method should be made into a static method. It is independent of each individual Person object, so making it static will allow you to call it in the main method as
Person.print("Male");
To refer to Person objects in the print method, you will need to pass it a collection of Person objects as a parameter. You should keep all instances of Person in an array and pass that into the print method when you call it. Then the print method can be
public static void print(String gender, Person[] people) {
for(Person x : people)
if (x.gender.equals(gender))
//print the person
}
With this modification you should call it from the main method as
Person.print("Male", people);
where people is the array you keep all Person objects in.

Categories