I'm working on a class that inherits from another class, but I'm getting a compiler error saying "Cannot find symbol constructor Account()". Basically what I'm trying to do is make a class InvestmentAccount which extends from Account - Account is meant to hold a balance with methods for withdrawing/depositing money and InvestmentAccount is similar, but the balance is stored in shares with a share price determining how many shares are deposited or withdrawn given a particular amount of money. Here's the first few lines (around where the compiler pointed out the problem) of the subclass InvestmentAccount:
public class InvestmentAccount extends Account
{
protected int sharePrice;
protected int numShares;
private Person customer;
public InvestmentAccount(Person customer, int sharePrice)
{
this.customer = customer;
sharePrice = sharePrice;
}
// etc...
The Person class is held in another file (Person.java). Now here's the first few lines of the superclass Account:
public class Account
{
private Person customer;
protected int balanceInPence;
public Account(Person customer)
{
this.customer = customer;
balanceInPence = 0;
}
// etc...
Is there any reason why the compiler isn't just reading the symbol constructor for Account from the Account class? Or do I need to define a new constructor for Account within InvestmentAccount, which tells it to inherit everything?
Thanks
use super(customer) in InvestmentAccounts constructor.
Java can not know how to call the only constructor Account has, because it's not an empty constructor. You can omit super() only if your base class has an empty constuctor.
Change
public InvestmentAccount(Person customer, int sharePrice)
{
this.customer = customer;
sharePrice = sharePrice;
}
to
public InvestmentAccount(Person customer, int sharePrice)
{
super(customer);
sharePrice = sharePrice;
}
that will work.
You have to invoke the superclass constructor, otherwise Java won't know what constructor you are calling to build the superclass on the subclass.
public class InvestmentAccount extends Account {
protected int sharePrice;
protected int numShares;
private Person customer;
public InvestmentAccount(Person customer, int sharePrice) {
super(customer);
this.customer = customer;
sharePrice = sharePrice;
}
}
Call the super() method. If you want to call the Account(Person) constructor, use the statement super(customer); Also this should be the first statment in your InvestmentAccount
constructor
You have to call the constructor of the base class explicitly if the base class doesn't have a default constructor (one with no arguments).
In your case, the constructor should be:
public InvestmentAccount(Person customer, int sharePrice) {
super(customer);
sharePrice = sharePrice;
}
And don't redefine customer as an instance variable of the subclass!
Either define a default constructor in the Account class:
public Account() {}
Or call super(customer) in the InvestmentAccount constructor.
Related
I have 2 subclasses: Staff, Student
they belong to superclass Person.
Here is the code(tasks) which is given by my teacher:
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
}
class Student extends Person
{
private String SID; // student ID number
/**
* Create a student with no parameters.
*/
Student()
{
//task.
}
}
public class Staff extends Person
{
private String roomNumber;
/**
* Construct a staff member with field values and no pamaeters.
*/
public Staff()
{
//task
}
}
I don't know what can I type in order to create an object without parameter.
It always appears an error like: constructor Person in class Person cannot be applied to given types; required: java.lang.String,int;
I have checked online that there are 2 ways to solve the problem:
add a default value in the superclass: Person()//without parameter.
In the subclass Student:
Student()
{
Person astudent = new Student() //I guess.
}
add a super() in the subclass:
Student()
{
super("xxx")//I guess.
}
I don't know what to do. I an a starter in learning BlueJ.
Hope anyone can help me. Thank you very much.
Since your superclass Person doesn't have a default constructor, in your subclasses (Student and Staff), you must call the superclass constructor as the first statement.
You should define your sub-class constructors like this:
Student() {
super("a_string_value", an_int_value);// You have to pass String and int values to superclass
}
Staff() {
super("a_string_value", an_int_value); // You have to pass String and int values to super class
}
the first thing a constructor will do, is call the constructor (with same arguments) of the super class.
Person does not have a no-argument constructor, so, you must change your code in one of next two ways:
Student(String name, int yearOfBirth)
{
//task.
}
or
Student()
{
super("", 0);
//task.
}
and the same goes for Staff
Add super(NAME_IN_STRING_TYPE,YEAR_OF_BIRTH_IN_INT_TYPE); as a first statement in your subclasse's constructor like
Student constructor
Student()
{
super("name", 1970); // String,int arguments passed
//task.
}
Staff constructor
Staff()
{
super("name", 1970); // String,int arguments passed
//task.
}
This is needed since there is no default no-arg constructor in the base class. You have to explicitly define a no-arg constructor in base class or you need to instruct the compiler to call the custom constructor of the base class.
Note : Compiler will not add default no-arg constructor in a class if it has a user defined constructor. It will add the default no-arg constructor only when there is no constructor defined in the class.
Try this:
Student(String name, int yearOfBirth) {
super(name, yearOfBirth);
// task...
}
Reason: you dont have a default constructor at your superclass. So you have to call super() at the first position in your subclass constructor.
To construct instance of Student you need to do actions neccesary to construct Person first. There is only one way to construct Person - two-arg constructor. That means you have to change Student like:
public Student() {
super("someName", 1950); //first values came to my mind
}
Although you should be aware that Student should behave exactly like Person if treated as Person, i.e. have age and name. So actually I'd recommend to change Student constructor to include name and age there.
If you want to create an object of child class (ie Staff and Student) without passing parameters then you can create an additional constructor without parameters in the parent class (ie Person class) as below.
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
// additional constructor without parameter
Person(){
// add your code here
}
}
now below code will work without any error.
Staff stf = new Staff();
Student std = new Student();
for constructor no param you should have two constructors like
public class Student {
Student(String name , int dateOfBirth)
{
super(name,dateOfBirth)
}
Student()
{
//task.
}
}
also same for other class
student should not extend person.
bcoz, if we create obj for student, person’s constructor will be called automatically.
I have been studying explicit and implicit casting in Java.
I created a Customer class that has two subclasses like RetailCustomer and CorporateCustomer. Also, I created a Bill class that has Customer property.
I want to create a Bill object according to user selection. If the user selects "1", the Bill object will be created for the retail customer, or if the user selects "2", the Bill object will be created for the corporate customer.
I'm very confused. How can I use explicit and implicit casting?
public class Customer {
private int CustomerID;
private String CustomerName;
private String CustomerLastName;
}
public class RetailCostumer extends Customer {
private int CitizenShipID;
private int CustomerNo
}
public class CorporateCustomer extends Customer {
private int TaxNumber;
private int CustomerNo
}
public class Bill {
private int BillID;
private Customer customer;
}
public class BillManagement {
public static void main(String[] args) {
}
}
You don't have to explicit casting when creating and assigning subclass to superclass.
For example:
// You can assign RetailCustomer(subclass) instance to a Customer(superclass),
// Because RetailCustomer is Customer.
Customer customer = new RetailCustomer();
But, when you want to access subclasses variable such as CitizenShipID, TaxNumber, then you need to use explicit type casting.
For example:
Customer customer = new RetailCustomer();
// Customer could not be RetailCustomer (e,g. could be CorporateCustomer) ,
// so, you have to inform that 'customer is actually RetailCustomer'
RetailCustomer retailCustomer = (RetailCustomer) customer;
retailCustomer.CitizenShipID;
In practice, actual customer instance could not be a RetailCustomer instance(could be CorporateCustomer), then ClassCastingException will be occurred.
So, it will be good practice to check actual instance type by instanceof before casting like below.
Customer customer = new RetailCustomer();
RetailCustomer retailCustomer;
if (customer instanceof RetailCustomer) {
retailCustomer = (RetailCustomer) customer;
} else {
// handle otherwise
}
retailCustomer.CitizenShipID;
Suppose I have the following Abstract class.
public abstract class Account {
protected String Id;
protected double balance;
public Account(String Id, double balance) {
this.Id = Id;
this.balance = balance;
}
}
And the following subclass
public class CheckingAccount {
public CheckingAccount(String Id, double balance) {
super(Id, balance)
if(super.balance > 10_000) this.balance += 200;
}
}
Both 'this' and 'super' are allowed in the context of the subclass when accessing a protected member. Is it better to use one over the other? 'super' makes it explicit where that field comes from. I understand I can just use balance without specifying the implicit parameter but I was just curious in terms of how this is utilized in practice if one wanted to specify the implicit parameter.
Since CheckingAccount inherits protected field balance from Account so it DOES NOT matter using super or this keyword to access the field balance in CheckingAccount class. However, I prefer 'this'.
If there is a protected method in Account class (base class) and there is a its overridden method in CheckingAccount class, you will have to carefully use super or this in this case because they are not the same body implementation!
I'd argue you shouldn't use any protected fields, to enforce encapsulation. Provide a protected void addToBalance(double value) method would be the cleaner way.
I was just curious in terms of how this is utilized in practice if one wanted to specify the implicit parameter
For somewhat academic reasons, here's where it makes a difference:
public abstract class Account {
protected String Id;
protected double balance;
public Account(String Id, double balance) {
this.Id = Id;
this.balance = balance;
}
}
public class CheckingAccount {
// overwrite existing field
protected double balance;
public CheckingAccount(String Id, double balance) {
super(Id, balance);
this.balance = balance;
if(super.balance > 10_000) this.balance += 200;
}
}
I have 2 subclasses: Staff, Student
they belong to superclass Person.
Here is the code(tasks) which is given by my teacher:
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
}
class Student extends Person
{
private String SID; // student ID number
/**
* Create a student with no parameters.
*/
Student()
{
//task.
}
}
public class Staff extends Person
{
private String roomNumber;
/**
* Construct a staff member with field values and no pamaeters.
*/
public Staff()
{
//task
}
}
I don't know what can I type in order to create an object without parameter.
It always appears an error like: constructor Person in class Person cannot be applied to given types; required: java.lang.String,int;
I have checked online that there are 2 ways to solve the problem:
add a default value in the superclass: Person()//without parameter.
In the subclass Student:
Student()
{
Person astudent = new Student() //I guess.
}
add a super() in the subclass:
Student()
{
super("xxx")//I guess.
}
I don't know what to do. I an a starter in learning BlueJ.
Hope anyone can help me. Thank you very much.
Since your superclass Person doesn't have a default constructor, in your subclasses (Student and Staff), you must call the superclass constructor as the first statement.
You should define your sub-class constructors like this:
Student() {
super("a_string_value", an_int_value);// You have to pass String and int values to superclass
}
Staff() {
super("a_string_value", an_int_value); // You have to pass String and int values to super class
}
the first thing a constructor will do, is call the constructor (with same arguments) of the super class.
Person does not have a no-argument constructor, so, you must change your code in one of next two ways:
Student(String name, int yearOfBirth)
{
//task.
}
or
Student()
{
super("", 0);
//task.
}
and the same goes for Staff
Add super(NAME_IN_STRING_TYPE,YEAR_OF_BIRTH_IN_INT_TYPE); as a first statement in your subclasse's constructor like
Student constructor
Student()
{
super("name", 1970); // String,int arguments passed
//task.
}
Staff constructor
Staff()
{
super("name", 1970); // String,int arguments passed
//task.
}
This is needed since there is no default no-arg constructor in the base class. You have to explicitly define a no-arg constructor in base class or you need to instruct the compiler to call the custom constructor of the base class.
Note : Compiler will not add default no-arg constructor in a class if it has a user defined constructor. It will add the default no-arg constructor only when there is no constructor defined in the class.
Try this:
Student(String name, int yearOfBirth) {
super(name, yearOfBirth);
// task...
}
Reason: you dont have a default constructor at your superclass. So you have to call super() at the first position in your subclass constructor.
To construct instance of Student you need to do actions neccesary to construct Person first. There is only one way to construct Person - two-arg constructor. That means you have to change Student like:
public Student() {
super("someName", 1950); //first values came to my mind
}
Although you should be aware that Student should behave exactly like Person if treated as Person, i.e. have age and name. So actually I'd recommend to change Student constructor to include name and age there.
If you want to create an object of child class (ie Staff and Student) without passing parameters then you can create an additional constructor without parameters in the parent class (ie Person class) as below.
public class Person
{
private String name;
private int yearOfBirth;
/**
* Create a person with given name and age.
*/
Person(String name, int yearOfBirth)
{
this.name = name;
this.yearOfBirth = yearOfBirth;
}
// additional constructor without parameter
Person(){
// add your code here
}
}
now below code will work without any error.
Staff stf = new Staff();
Student std = new Student();
for constructor no param you should have two constructors like
public class Student {
Student(String name , int dateOfBirth)
{
super(name,dateOfBirth)
}
Student()
{
//task.
}
}
also same for other class
student should not extend person.
bcoz, if we create obj for student, person’s constructor will be called automatically.
When I use super() to use a superclass method, what is the proper way to return?
Let's say I have a class Hourly. It contains a constructor also called Hourly that has parameters "String name" and "double rate. The UML version looks like:
+Hourly(name:String, rate:double)
However, the "name" variable is a private attribute of the Employee class, of which the class hourly is related to via inheritance. By this I mean that the UML show a clear arrow (not a diamond) going from the class Hourly and pointing to the class Employee.
How would I write the constructor Hourly???
I have a basic skeleton of:
public Hourly(String name, double rate){
}
Please help me fill it in.
On a separate note, let's say that there was a return in a method. Say I wanted to return the double rate. What would be the proper syntax to return some that uses super() as I know I couldn't simply use:
return this.rate;
Your Employee surely has a name.
private String name;
public Employee(String name) {
this.name = name;
}
Following that, your Hourly must also have a name. Since an Hourly is-an Employee, you must set the name on it as well. That is accomplished like so.
public Hourly(String name, double rate) {
super(name);
this.rate = rate;
}
According to your comments, name is stored by the superclass; rate is not. So you should store rate in the Hourly class you're defining, while passing name to the super constructor, as follows:
public class Hourly {
private double rate;
public Hourly(String name, double rate) {
super(name);
this.rate = rate;
}
public double getRate() {
return rate;
}
}
If Hourly is sub class of Employee and if you want to parse the name to super class (Employee) then in your Hourly constructor call super(name);
public Hourly(String name, double rate){
super(name);
}
Since Hourly extends Employee:
class Hourly extends Employee {
private int rate;
public Hourly(String name, int rate) {
super(name); //assuming Employee has this constructor
this.rate = rate;
}
//this make sense if name is protected and doesn't have getter in base class
//ideally you would have this in base class itself
public String getName() {
return super.name; //for rate there is no sense in using super as it is not known to super class
}
}