How to use getters and setters in an Abstract Class - java

I have an abstract class Customer. It's a very simple class, only setting 5 string variables as well as 5 static int variables. Better to show what I mean by this:
As a disclaimer I made the code as simple as possible, I have more logic involved in my abstract class that doesn't pertain to the question.
Abstract Class
public abstract class Customer {
private String Name, Address, Phone, Email, Company;
public static final int NAME = 0, ADDRESS = 1, PHONE = 2, EMAIL = 3, COMPANY = 4;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
setValues(Name, Address, Phone, Email, Company);
}
private void setValues(String Name, String Address, String Phone, String Email, String Company) {
setName(Name);
setAddress(Address);
setPhone(Phone);
setEmail(Email);
setCompany(Company);
}
//declare public getters and setters methods below
}
My question is as follows:
I have a class that extends this abstract class called Customer (different package). If I set up the constructor in this class as such:
Object Class
public class Customer extends Main.Customer {
private String Name, Address, Phone, Email, Company;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
super(Name, Address, Phone, Email, Company);
}
}
Does this set my String variables as to whatever I pass through the constructor? As in when I instantiate this class as an object, how would I be able to 'get' a variable from it?
For example: (Assume String1 -String5 are strings of some sort)
public class Random {
private Customer customer = new Customer(String1, String2, String3, String4, String5);
}
How would I then call the object later on in the class to return a string (of any single variable). As in if my abstract class wasn't abstract but the main class I was using to instantiate as an object, I'd get the variable like so: String name = customer.getName();
TL;DR:
Just unsure how to get variables from an object extending an abstract class.

Drop the variables from your subclass so they don't shadow the variables with the same name in the parent class.
//sub class
public class Customer extends Main.Customer {
//DROP THESE private String Name, Address, Phone, Email, Company;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
super(Name, Address, Phone, Email, Company);
}
}
And add getters to your parent class:
//parent class
public abstract class Customer {
private String Name, Address, Phone, Email, Company;
public static final int NAME = 0, ADDRESS = 1, PHONE = 2, EMAIL = 3, COMPANY = 4;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
setValues(Name, Address, Phone, Email, Company);
}
private void setValues(String Name, String Address, String Phone, String Email, String Company) {
setName(Name);
setAddress(Address);
setPhone(Phone);
setEmail(Email);
setCompany(Company);
}
public String getName() {
return Name;
}
public String getAddress() {
return Address;
}
//etc....
}
Also, I really recommend using different names for your parent and subclass to avoid confusion.

Some considerations before start:
In java by code-convention variables starts with lower-case. It will help code readability for people including you.
Don't have two classes with the same name, is very confusing. You can call it for example ACustomer or AbstractCustomer and the other one Customer or SomethingCustomer
It isn't Object class it's Concrete Class a class that you can have instances of it.
As Customer inherits ACustomer you don't have to define again the ACustomer fields, Customer already has them. If you do you are hiding those from parent.
public class Customer extends ACustomer {
public Customer(String name, String address, String phone, String email, String company) {
super(name, address, phone, email, company);
}
}
You are calling an overrideable method inside the constructor take care about that, cause if setXXX is override then perhaps you could have a NullPointerException.
For your question in how to get member you can define getters.
public abstract class ACostumer{
private String name;
public String getName() {
return name;
}
}
Then in client code:
ACustomer customer = new Customer(...);
customer.getName();

Your subclass is overshadowing the private properties of the abstract class.
public abstract class Customer {
private String Name, Address, Phone, Email, Company;
public class Customer extends Main.Customer {
private String Name, Address, Phone, Email, Company;
so any get methods in your abstract class of the form
public String getName() {
return Name;
}
would return the never initialized variable name in the subclass. Whereas, when you call super(...), the set functions there would set the variables of the abstract class.
So you are setting one set of variables, but reading another set of variables that were never initialized.

Related

Accessing variables from an object of array in Java

Interface Price:
interface Price {
void printPrice(); }
AbstractTest class:
abstract class AbstractTest implements Price {
private String name, surname;
AbstractTest (String name, String surname){
this.name=name;
this.surname=surname; }
public String getName() {
return this.name; }
public String getSurname() {
return this.surname; } }
TestAbstractTest class:
class TestAbstractTest extends AbstractTest{
int price;
TestAbstractTest(int price, String name, String surname){
super(name, surname);
this.price=price; }
void printPrice() {
System.out.println("price:"+ price)// HOW CAN I ACCESS TO NAME AND SURNAME FROM AbstractTest CLASS }
Main class:
class Main {
public static void main(String args[]) {
AbstractTest[] abstracttest= new AbstractTest[2];
abstracttest[0]=new TestAbstractTest(5, xxx, yyy);
abstracttest[1]=new TestAbstractTest(10, aaa, zzz); }
I want to access the name and the surname from subclasses method printPrice.
I cant create an abstract method. I have to use printPrice from the interface Price. I've rearranged the constructor of TestAbstractTest like this (price, name, surname, AbstractTest abstracttest) and i've tried this.
abstracttest[0]= new AbstractTest(5, "xxx", "00yy", abstracttest[0])
But its obviously wrong. How can I access name and surname and print it from printPrice method?
When declaring or requesting a variable's value you can use get() or set() methods.
abstracttest[0]= new AbstractTest(5, this.getName(), this.getSurname(), abstracttest[0]);
System.out.println("price:"+ this.getPrice() );
You need to implement getPrice() of course.

To define an object in a constructor in Serializable class

I have a JSON response like below image, and I have made a serializable class named as Project
In the image, I have two objects (emergency_contact, and secondary_owner) inside my an array of one object. I'm trying to figure out whether what to do in order to define the object, since I want that details to be present inside my constructor.
I have done this so far:
public class Project implements Serializable {
public int id;
public String name;
public String additional_information;
//Now what to do Emergency contact
public Project(int id, String name, String additional_information){
}
}
I have thought of doing this, public EmergencyContact emergency = new EmergencyContact(param1, param2).
And make a new class named as EmergencyContact, and do a getter and setter for the params. But after doing this, I'm still confused, how would I define it my constructor?
I know I'm close, but I need some help on that.
Sure. You need to have a:
public class EmergencyContact implements Serializable {
public String name;
public String number;
public EmergencyContact(String name, String number){
// assign fields
}
}
and one for the owner:
public class EmergencyOwner implements Serializable {
public String name;
public String number;
public EmergencyOwner(String name, String number){
// assign the fields
}
}
then in your Project class you can add fields of these classes:
public class Project implements Serializable {
public int id;
public String name;
public String additional_information;
public EmergencyContact emergency_contact;
public EmergencyOwner emergency_owner;
public Project(int id, String name, String additional_information, EmergencyContact emergency_contact, EmergencyOwner emergency_owner){
// assign the fields here as well
}
}
that's it. If that's an answer to the question consider to delete this question as it is a duplicated on a 100% :)
As a note, to be correctly from the point of clean code parameters, the fields should be private in a class, and use setters / getters to set/retrieve values from/to those fields.
public class Project implements Serializable {
private int id;
private String name;
private String additional_information;
private EmergencyContact emergency_contact;
private SecondaryOwner secondary_owner;
public Project(int id, String name, String additional_information, EmergencyContact emergencyContact, SecondaryOwner secondaryOwner){
this.id = id;
this.name = name;
this.additional_information = additional_information;
this.emergency_contact = emergencyContact;
this.secondary_owner = secondaryOwner;
}
}
You will define the other two classes the same way. Now, you are probably confused about the constructor of EmergencyContact & SecondaryOwner classes.. You can device both default constructors (without parameters) and a custom one(with parameters to it, just as the one above). If you use the default constructor, make sure to set values to the fields in the object, as following :
EmergencyContact emergencyContact = new EmergencyContact();
emergencyContact.setName("the name");
emergencyContact.setNumber("a number");
then you can use this object in the constructor of Project class
I hope it was clear enough, for any other clarifications feel free to ask.
Happy coding <3

How the code is working here in the subclass?

package practice;
class person{
private String firstname;
private String lastname;
public person(String firstname,String lastname){
set_first(firstname);
set_last(lastname);
}
public String get_first() {
return firstname;
}
public void set_first(String firstname) {
this.firstname=firstname;
}
public void set_last(String lastname) {
this.lastname=lastname;
}
public String get_last() {
return lastname;
}
}
class employee extends person {
private int empid;
public employee(String firstname, String lastname, int empid) {
super(firstname,lastname);
set_empid(empid);
}
public void set_empid(int empid) {
this.empid=empid;
}
public int get_empid() {
return empid;
}
}
class testing_super_keyword {
public static void main(String args[]) {
employee emp=new employee("Paul","Anderson",1234);
System.out.println(emp.get_first()+" "+emp.get_last());
System.out.println(emp.get_empid());
}
}
I got two classes here person superclass and employee subclass. So i just wanted to know this code isn't supposed to work as the firstname and lastname variable is private in superclass? But how the subclass i.e employee is inheriting those members and using it??
I thought private variable of superclass cant be inherited so how come it works fine here?
I am totally confused please help......
Although, the private variables of parent class are not inherited by child class i.e employee but there are public functions that are called getter and setter that allows to access the private members of class from its sub-class.
public String get_first() {
return firstname;
}
public void set_first(String firstname) {
this.firstname=firstname;
}
public void set_last(String lastname) {
this.lastname=lastname;
}
public String get_last() {
return lastname;
}
You see when you want to access firstname from parent, you'll call get_first() from employee object to get the firstname. If you want to set the firstname you'll call set_first("name") to set the name. Hope it might help.
private variable of superclass cant be inherited
Yes, you are absolutely right, they won't be inheriting. But in your code, you are not accessing those fields directly right?
public employee(String firstname,String lastname,int empid){
super(firstname,lastname);
set_empid(empid);
}
Here you are passing parameters (from the main method) to your employee constructor, the names of parameters are similar to the fields in person, but they are not the same. You can change parameters names like this and it will still work fine.
public employee(String fName, String lName,int empid){
super(fName,lName);
set_empid(empid);
}
Here the parameter values are taken into super class constructor and its private fields are initialized and then empid of employee is initialized.
System.out.println(emp.get_first()+" "+emp.get_last());
System.out.println(emp.get_empid());
Here also you are not accessing the private fields directly, you are calling the public methods which will be inherited to the employee and can be called on its reference.
Keeping members of a class as private and their behaviours (methods) as public is a part of encapsulation, so that you cannot directly access then but can set and get its value using public methods.
PS : Try to make the getters and setters using the IDE, if it gives the option and try to follow naming conventions for classes and methods.
lets review how firstname and lastname are being initialized here:
in subclass constructor firstname, lastname has been taken
then in the body of constructor by super(firstname,lastname), firstname and lastname pass to the parent (i.e. Person) to be taken care of.
so assume we are now in the parent constructor (Person) so, By calling set_first(firstname) and set_last(lastname) , parameters firstname and lastname is being set in parent class itself with the values which passed from the child constructor (i.e. Employee)
Regarding this description there is no violation.
The violation happens if you want to initialize private variable directly in Employee class as :
public employee(String firstname,String lastname,int empid){
this.firstname=firstname; //Violation
this.lastname=lastname; //Violation
set_empid(empid);
}

Java trouble serializing a field of an object

I'm trying to learn about serialization and encountered the following problem:
I have an implementation of a customer that looks somewhat like this.
private static customerCount = 0;
private String customerID;
private String name;
private String street;
private String city;
private String postcode;
private String type;
I'm trying to serialize / deserialize an Arraylist
In the constructor, the ID will be created like this:
private Customer(...){
this.customerID = "ID" + customerCount;
customerCount++;
}
The serialization process works, however, all the IDs are set to ID0 when I deserialize.
Can anyone help resolve this problem?
Update: Alright, I just found out that static fields wont be serialized. How can I "model" the ID of a customer so I can serialize it? I need to have a unique value to create IDs for customers.
Here's a solution that combines the factory with the list that keeps track of customer count.
The customer class has a protected constructor, forcing you to build them through another means within the same package.
public class Customer implements Serializable {
private String customerID;
private String name;
private String street;
private String city;
private String postcode;
private String type;
protected Customer(String customerID,
String name,
String street,
String city,
String postcode,
String type) {
this.customerID = customerID;
this.name = name;
this.street = street;
this.city = city;
this.postcode = postcode;
this.type = type;
}
}
Now within the package, create a list wrapper like this:
public class CustomerList {
private int customerCount = 0;
private List<Customer> customers = new ArrayList<>();
public boolean addCustomer(String name,
String street,
String city,
String postcode,
String type) {
Customer customer = new Customer("ID" + customerCount++,
name,
street,
city,
postcode,
type);
return customers.add(customer);
}
}
This class then takes care of constructing the new customer, and provides a unique ID.
Edit: Just noticed that you now also have the upside of making the CustomerList class serializable as well. Then you can load it and still have an accurate customer count for adding additional uniquely ID-ed customers.
Usually, you would like to serialize only attributes and their values, not the logic from the class. Logic should happen before serialization or after deserialization.

Cannot find symbol - constructor JAVA

I'm getting the error cannot find symbol - constructor Customer whilst trying to set up this class.
public class PersonalCustomer extends Customer
{
public PersonalCustomer(String accountNumber, Address address, Name name)
{
super(accountNumber, address);
name = name;
}
}
Below is the class Customer.
public abstract class Customer
{
private String accountNumber;
private Address address;
private int balance;
private char customerType;
public Customer(String accountNumber, Address address, char customerType)
{
accountNumber = "";
address = address;
balance = 0;
customerType = ' ';
}
Can anyone help as too where I'm going wrong?
Customer constructor is declared with three arguments:
public Customer(String accountNumber, Address address, char customerType)
while call from child class only provides two:
super(accountNumber, address);
super(accountNumber, address, CustomerType);
Java compiler is trying to find the super() constructor with 2 arguments, which unfortunately does not exist. Bails out with an error!
Pay attention to Customer's constructor signature, it has 3 parameters.
Now, you're calling it from PersonalCustomer's constructor providing only 2.

Categories