I'm currently working on a program, and in my subclass, I need to have a no argument constructor that initializes the object with empty strings.
I've tried using super, I have setter and getter methods, but I keep getting "the field Person.name is not visible". I get this for address and phoneNumber as well.
How do I make it so it is visible, and I can initialize the objects without giving the constructor arguments? Please let me know if I'm doing anything wrong and need to fix something (:
// Create a class named Person
public class Person {
// Fields: name, address, and phone number. (2 points)
private String name;
private String address;
private String phoneNumber;
// No argument constructor that initializes the object with empty strings for name, address, and phone. (2 points)
public Person () {
super();
this.name = "";
this.address = "";
this.phoneNumber = "";
}
// 3 argument constructor that initializes the object with a name, address, and a phone number. (2 points)
public Person2 (String name, String address, String phoneNumber) {
this.name = name;
this.address = address;
this.phoneNumber = phoneNumber;
}
// Getter/setter methods for each of the fields. (3 points)
// set/get name
public void setName (String name) {
this.name = name;
}
public String getName () {
return this.name;
}
// set/get address
public void setAddress (String address) {
this.address = address;
}
public String getAddress () {
return this.address;
}
// set/get phone number
public void setPhoneNumber (String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber () {
return this.phoneNumber;
}
// toString method that returns a string for the name, address, and phone number (2 points)
// (you can override the toString method as part of a class which is pretty swag)
public String toString() {
return "Name: " name "\n" "Address: " address "\n" "Phone: " phoneNumber;
}
}
// Create a subclass of Person named Customer
class Customer extends Person {
// A field for a customer number. (1 point)
private String customerNumber;
public Customer () {
// A no argument constructor that initializes the object with an empty string for the name, address, phone, and customer number. (2 points)
super(name, address, phoneNumber);
}
// A 4 argument constructor that initializes the object with a name, address, a phone number, and a customer number. (2 points)
public Customer2 (String name, String address, String phoneNumber, String customerNumber) {
this.name = name;
this.address = address;
this.phoneNumber = phoneNumber;
this.customerNumber = customerNumber;
}
// Getter/setter method for the customer number field. (1 point)
public void setCustomerNumber (String customerNumber) {
this.customerNumber = customerNumber;
}
// toString method that prints the information from the Person toString as well as the customer number (2 points)
public String toString() {
return "Name: " name "\n" "Address: " address "\n" "Phone: " phoneNumber "\n" "Customer Number: " customerNumber;
}
}
CodePudding user response:
If a field is marked with private access then it can only be accessed from inside that class or instances of it. You should use the get methods. Or, you can get the result of toString
and build on that.
Also, all constructors should have the same name as the class (no "2" added).
public class Person {
private String name;
private String address;
private String phoneNumber;
public Person() {
this("", "", "");
}
public Person(String name, String address, String phoneNumber) {
this.name = name;
this.address = address;
this.phoneNumber = phoneNumber;
}
public void setName (String name) {
this.name = name;
}
public String getName () {
return this.name;
}
public void setAddress (String address) {
this.address = address;
}
public String getAddress () {
return this.address;
}
public void setPhoneNumber (String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber () {
return this.phoneNumber;
}
@Override
public String toString() {
return "Name: " name "\n" "Address: " address "\n" "Phone: " phoneNumber;
}
}
// Create a subclass of Person named Customer
class Customer extends Person {
private String customerNumber;
public Customer () {
this("", "", "", "");
}
public Customer (String name, String address, String phoneNumber, String customerNumber) {
super(name, address, phoneNumber);
this.customerNumber = customerNumber;
}
public String getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber (String customerNumber) {
this.customerNumber = customerNumber;
}
@Override
public String toString() {
return super.toString() "\n" "Customer Number: " customerNumber;
}
}
CodePudding user response:
You cannot access or assign to a
private
field in any other class than the one that it is declared in.You cannot declare a constructor with any name other than the name of the class. Thus
Person2
andCustomer2
are not neither valid constructors or valid methods. (A method requires a return type!)A constructor must explicitly (via a
super
call) or implicitly chain a no-args constructor in its superclass.
Basically, your choices for initializing a private field in a superclass are either use a super(...)
call to chain the a superclass constructor passing the value OR call a superclass setter method within the subclass constructor.
For example, the 4 arg constructor in Customer
could be:
public Customer (String name, String address,
String phoneNumber, String customerNumber) {
super(name, address, phoneNumber);
this.customerNumber = customerNumber;
}
or
public Customer (String name, String address,
String phoneNumber, String customerNumber) {
super();
setName(name);
setAddress(address);
setPhoneNumber(phoneNumber);
this.customerNumber = customerNumber;
}
IMO, the former is better. It is more concise and more readable.
The toString()
method in Customer
cannot refer directly to the private fields of the Person
. It could use the fields' getters.
CodePudding user response:
I don't think there is any actual need to call the super constructor in the person class. However, in the constructor for the costumer class, you should just call the super constructor with no arguments.
Edit: or you could initiate the values directly upon declaration, like the guy above me said.
PS. kinda unrelated, but, you could have one constructor but give the arguments default values. So you can call it with and without arguments with no need to override it.
CodePudding user response:
There are a few issues in the snippet that you provided:
There is no need to define different names for constructors of the same class. The fact that their signature (i.e. set of input parameters) is different suffices.
Regarding your question, the error is that you're trying to access Person's private fields in the Customer's constructors directly. There are two ways to fix this issue:
- Change the Person fields' scope from private to protected. This will allow any class that inherits the Person class to access the aforementioned fields directly.
- When in Customer class, use the getter/setter methods to access the private fields.
CodePudding user response:
something like this will work if i understand your question correctly:
private String name = "";