I am a beginner using Java and I don't find the solution for this:
public class Company{
private String name;
private int age;
public Company(String n, int a){
name = n;
age = a;
}
/*get and set*/
public static void main(String[] args) {
ArrayList<Company> comp = new ArrayList<Company>();
comp.add(new Company("Tom", 23));
comp.add(new Company("John", 43));
comp.add(new Company("Charles", 25));
}
}
I would like to add parameters in a for, like email, address, etc. But .add is for new elements, no parameters.
Extend the Company class with the email, address fields (1), update the constructor (2), and pass the arguments you want (3).
public class Company {
...
private final String address; // 1
private final String email;
public Company(String n, int a, String address, String email) { // 2
...
this.address = address;
this.email = email;
}
public static void main(String[] args) {
...
comp.add(new Company("Charles", 25, "street", "charles#gmail.com")); // 3
}
}
If you already have an array filled with information for a specific field, you can use a for:
final List<String> emails = Arrays.asList("first#gmail.com", "second#gmail.com");
for (final String email : emails) {
comp.add(new Company(..., ..., ..., email));
}
You need to read about class members.
public class Company{
private String name;
private int age;
private String email;
private String address;
public Company(String n, int a, String e, String addr){
name = n;
age = a;
email = e;
address = addr;
}
First, you need to add variables to your class (that is the place where it will be stored per each class instance, as well as name or age are at the moment
Than you have to modify constructor (or create another one) to be able take these parameters, and also it is good idea to make getters and setters to get or set these parameters individually, so it can looks like this
public class Company{
private String name;
private int age;
private String email;
private String address;
public Company(String n, int a){
name = n;
age = a;
}
public Company(String n, int a,String email, String address){
name = n;
age = a;
this.email = email; //class instance object email is set to email from method parameter
this.address = address;
}
/*get and set*/
public void setEmail(String email){
this.email=email; //explicit setter
}
public String getEmail(){
return this.email;
}
public static void main(String[] args) {
ArrayList<Company> comp = new ArrayList<Company>();
comp.add(new Company("Tom", 23)); //will work, because I let your constructor
comp.add(new Company("John", 43));
comp.add(new Company("Charles", 25));
Company compToAdd= new Company("preparedFoo",22);
compToAdd.setEmail("fooomail"); //will work because setter
comp.add(compToAdd);
comp.add(new Company("FooName", 30,"fooMail","FooAddress")); //will work because new constructor
}
}
Related
I have created a Person, class and a Professor class that both use the Builder Pattern to create objects. The Professor class takes a Person object as an argument in its constructor. I am trying to use both classes together, but when I attempt to print out a professor, get the following output: null null (instead of Bob Smith).
Here's what I tried so far:
Person:
public class Person {
private String firstname;
private String lastname;
private int age;
private String phoneNumber;
private String emailAddress;
private char gender;
public Person(){}
// builder pattern chosen due to number of instance fields
public static class PersonBuilder {
// required parameters
private final String firstname;
private final String lastname;
// optional parameters
private int age;
private String phoneNumber;
private String emailAddress;
private char gender;
public PersonBuilder(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
public PersonBuilder age(int age) {
this.age = age;
return this;
}
public PersonBuilder phoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
return this;
}
public PersonBuilder emailAddress(String emailAddress) {
this.emailAddress = emailAddress;
return this;
}
public PersonBuilder gender(char gender) {
this.gender = gender;
return this;
}
public Person build() {
return new Person(this);
}
}
// person constructor
private Person(PersonBuilder builder) {
this.firstname = builder.firstname;
this.lastname = builder.lastname;
this.age = builder.age;
this.phoneNumber = builder.phoneNumber;
this.emailAddress = builder.emailAddress;
this.gender = builder.gender;
}
#Override
public String toString() {
return this.firstname + " " + this.lastname;
}
}
Here's the Professor class:
package com.example.hardcodedloginform;
import java.util.List;
public class Professor extends Person{
private Person professor;
private double salary;
private String courseTaught;
private List<Student> students;
private int professorID;
public static class ProfessorBuilder {
// required fields
private Person professor;
private int professorID;
// optional fields
private double salary;
private String courseTaught;
private List<Student> students;
public ProfessorBuilder(Person professor, int professorID) {
this.professor = professor;
this.professorID = professorID;
}
public ProfessorBuilder salary(double salary) {
this.salary = salary;
return this;
}
public ProfessorBuilder courseTaught(String courseTaught) {
this.courseTaught = courseTaught;
return this;
}
public ProfessorBuilder students(List<Student> students) {
this.students = students;
return this;
}
public Professor build() {
return new Professor(this);
}
}
private Professor(ProfessorBuilder builder) {
this.salary = builder.salary;
this.courseTaught = builder.courseTaught;
this.students = builder.students;
}
#Override
public String toString() {
return "" + super.toString();
}
}
And here is the Main class where I try to print out a professor object:
public class Main {
public static void main(String[] args) {
Person profBobs = new Person.PersonBuilder("Bob", "Smith")
.age(35)
.emailAddress("bob.smith#SNHU.edu")
.gender('M')
.phoneNumber("818-987-6574")
.build();
Professor profBob = new Professor.ProfessorBuilder(profBobs, 12345)
.courseTaught("MAT101")
.salary(15230.01)
.build();
System.out.println(profBob);
}
}
I would like the printout in the console to be "Bob Smith", but what I am seeing is: null null. I checked and found that the Person object profBobs is, in fact, created properly and does print out the name "Bob Smith" when I attempt to print it the same way. I don't know why my Professor prints: null null.
Your Professor constructor fails to initialise any member fields of its base class.
There are multiple ways to solve this. One solution has ProfessorBuilder extend PersonBuilder:
public class Professor extends Person {
// Remove the `person` field! A professor *is-a* person, it does not *contain* it.
private double salary;
private String courseTaught;
private List<Student> students;
private int professorID;
public static class ProfessorBuilder extends Person.PersonBuilder {
// required fields
private int professorID;
// optional fields
private double salary;
private String courseTaught;
private List<Student> students;
public ProfessorBuilder(Person professor, int professorID) {
super(professor);
this.professorID = professorID;
}
// …
}
private Professor(ProfessorBuilder builder) {
super(builder);
this.salary = builder.salary;
this.courseTaught = builder.courseTaught;
this.students = builder.students;
}
}
For this to work you also need to mark the Person constructor as protected rather than private.
Furthermore, your Professor.toString method implementation made no sense: it essentially just called the base class method, so there’s no need to override it. And prepending the empty string does nothing.
I created the class Person and the class Address.
As i'm trying to Instantiate an instance variable p1 in the class MyApp i get an error
'Address(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)' in Address' cannot be applied to '(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)'
public class Person {
private String firstname;
private String lastname;
private Address address;
private String dateOfBirth;
private String[] hobbies;
public Person(String firstname, String lastname, Address address, String dateOfBirth, String[] hobbies) {
this.firstname = firstname;
this.lastname = lastname;
this.address = address;
this.dateOfBirth = dateOfBirth;
this.hobbies = hobbies;
}
}
public class Address {
private int houseNumber;
private String street;
private String city;
public Address( int housenum,String street, String city) {
this.houseNumber = housenum;
this.street = street;
this.city = city;
}
}
public class myApp{
public static void main(String[] args) {
Person p1= new Person("Rares","Maria", new Address(84,"hiw RD","London"),csv_row1[2],"10/04/2000","swimming");
}
}
3 Things:
1.) Don't begin a class name lowercase cause it is a type and types start always upcase by convention.
2.) what is csv_row[2] it is not defined in your code and there is also no field in the constructor that matches.
3.) In Person the last member is String array and not string.
Change your code to of myApp to:
public class myApp {
public static void main(String[] args) {
Person p1= new Person("Rares","Maria", new Address(84,"hiw RD","London"),"10/04/2000", new String[]{"swimming"});
System.out.println("p1:" + p1);
}
}
So you tried to call a constructor you have not defined. You also can make passing a sting array as last parameter more convenient:
public class Person {
private String firstname;
private String lastname;
private Address address;
private String dateOfBirth;
private String[] hobbies;
public Person(String firstname, String lastname, Address address, String dateOfBirth, String ... hobbies) {
this.firstname = firstname;
this.lastname = lastname;
this.address = address;
this.dateOfBirth = dateOfBirth;
this.hobbies = hobbies;
}
}
then this constructor call would be correct:
public class myApp {
public static void main(String[] args) {
Person p1= new Person("Rares","Maria", new Address(84,"hiw RD","London"),"10/04/2000", "swimming");
System.out.println("p1:" + p1);
}
}
The error message itself makes no sense to me. Did you clean before compilation? It looks like outdated .class-Files. Remove all .class-Files and re-compile.
Hope this helps.
I think that you're giving wrong parameters for the Address constructor :
Address (String, String, int, String, String);
While you have defined it as follows :
Address ( String, String, String, String);
But your your code is correct, so it's not making any sense.
Something else, what is csv_row1[2] for ? It's not defined, remove it or define it in your code
Something else, The hobbies parameter is defined as String[] not String and you've to match it.
So your person instancing would be :
String[] hobbies = {"swimming"};
Person p1= new Person("Rares","Maria", new Address(84,"hiw RD","London"),"10/04/2000", hobbies);
Or
Person p1= new Person("Rares","Maria", new Address(84,"hiw RD","London"),"10/04/2000", new String[]{"swimming"});
Question before editing: How can I delegate the initialization process of too many member variable of class A inside class B and C and still use the value inside class A?
Note: (class B and C is present inside class A)
The main objective is to reduce too many member variables present in class A.
I am following whats it is said in this post [1]: https://stackoverflow.com/a/16994754/2018343
code would be like is
UPDATED:
public class A{ // start of class A
public int a;
int b;
public int c;
int d;
int x;
int g;
B bObject; //instance of class B
C cObject; //instance of class B
A(){ /**Constructor*/
bObject = new B(3,4);
cObject = new C(5,6);
} /*
*There is an error in eclipse after this closing bracket
*"Syntax error on token "}", { expected after this token"
*/
/**
* My end goal: I need to Use the initialized variables after the constructor
*/
public void yui(){
if(true){ // variables a and c
// System.out.println("A is greater");
x=a;
g=c;
}
} /**
* Syntax error on token "}", { expected after this token */
if(x<g){ // variables x and g
System.out.println("A is greater");
}
class B{ //Note: This class is inside class A
B(int val1, int val2){
a=val1;
b=val2;
}
}
class C{ // //Note: This class is inside class A
C(int val3,int val4){
c= val3;
d= val4;
}
}
public static void main(String[] args){
A a = new A();
a.yui();
}
} // end of class A
I am really looking for delegating the initialization process of too many variables to other child class and main thing is use that initialized variable value in the subsequent lines of code in master class.
Seek your help!
You can use the Builder pattern to make the initialization more user friendly.
A nice example that was taken from here:
public class User {
private final String firstName; // required
private final String lastName; // required
private final int age; // optional
private final String phone; // optional
private final String address; // optional
private User(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
public static class UserBuilder {
private final String firstName;
private final String lastName;
private int age;
private String phone;
private String address;
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
public User build() {
return new User(this);
}
}
}
and how to use it:
public User getUser() {
return new
User.UserBuilder("Jhon", "Doe")
.age(30)
.phone("1234567")
.address("Fake address 1234")
.build();
}
I want to find students whose gender is female by using streams
Student class
public class Student {
private String first;
private String last;
private int ID;
private Gender gender;
int next=0;
List<Course> courses=new LinkedList<>();
List<Student> students=new LinkedList<>();
public Student(String first, String last, int iD, Gender gender) {
this.first = first;
this.last = last;
ID = iD;
//this.gender = gender;
}
public void enroll(Course c) {
courses.add(c);
}
public void isFemale(){
Student s;
return s.gender=Gender.F;
}
}
enum class for genders
public enum Gender {
M,F;
private Gender gender;
}
main class
public class Main {
public static void main(String[] args) {
List<Student> studentsOfClass=new LinkedList<>();
studentsOfClass.add(new Student("john","smith",01,Gender.M));
studentsOfClass.add(new Student("mick","tayson",05,Gender.M));
studentsOfClass.add(new Student("sara","conor",04,Gender.F));
studentsOfClass.add(new Student("Tana","smith",02,Gender.F));
Course c1=new Course("fiologiya","anna",0234);
Course c2=new Course("mathematics","maria",1134);
Course c3=new Course("phisics","luisa",0534);
studentsOfClass.stream().limit(3).forEach(s->s.enroll(c1));
Collection<Student> femaleStudents= studentsOfClass.stream().filter(Student::isFemale).collect(Collectors.toList());
}
}
You are using the Stream methods correctly, but your isFamele method is wrong. It should return boolean and check the gender of the current Student.
It should be :
public boolean isFemale()
{
return gender==Gender.F;
}
You should also unremark this constructor line - //this.gender = gender; - and probably remove private Gender gender; from the Gender enum.
In addition, you can change the type of femaleStudents from Collection to List<Student>, which is more accurate.
I'm writing a simple program in which I have a super class Person inherited by the sub-classes Customer and Employee (they inherit the variables ID, name and surname).
public class Person {
int id;
String name;
String surname;
public Person() {}
public Person(int i, String n, String s) {
id = i;
name = n;
surname = s;
}
}
public class Employee extends Person implements Serializable {
String username;
String password;
String date;
int hpw;
int recordSold;
float hourPay;
public Employee() {}
public Employee(String u, String n, String s, String p, int i, int h, String d, int rSold, float hPay) {
username = u;
super.name = n;
super.surname = s;
password = p;
super.id = i;
hpw = h;
date = d;
recordSold = rSold;
hourPay = hPay;
}
}
However the problem is here: when I try to get the variables ID, name and surname through my main class, they fail to return (0,null,null). Why is this? I have get-Methods in my sub-classes which should return the super variables, but they are not. Thanks for your time and patience.
public String getName() {
return super.name;
}
UPDATE:
ok so I sorted out the super(id,name,surname) in the Employee class constructor. I also removed all the getters and setters in the employee class since those are inherited from the Person superclass (correct me if I'm wrong?..)
Person superclass:
public class Person {
private int id;
private String name;
private String surname;
public Person () {
}
public Person(int i, String n, String s) {
this.id = i;
this.name = n;
this.surname = s;
}
public void setID(int i) {
this.id = i;
}
public void setName(String n) {
this.name = n;
}
public void setSurname(String s) {
this.surname = s;
}
public int getID() {
return id;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
}
Employee subclass:
import java.io.*;
public class Employee extends Person implements Serializable {
protected String username;
protected String password;
protected String date;
protected int hpw;
protected int recordSold;
protected float hourPay;
public Employee() {
super();
}
public Employee(int i, String u, String n, String s, String p, int h, String d, int r, float hP) {
super(i,n,s);
username = u;
password = p;
date = d;
hpw = h;
recordSold = r;
hourPay = hP;
}
public void setUser(String u) {
username = u;
}
public void setPassword(String p) {
password = p;
}
public void setHWeek (int h) {
hpw = h;
}
public void setDate (String d) {
date = d;
}
public void setRSold (int r) {
recordSold = r;
}
public void setHPay (float p) {
hourPay = p;
}
public String getUser() {
return username;
}
public String getPassword() {
return password;
}
public int getHWeek() {
return hpw;
}
public String getDate() {
return date;
}
public int getRSold() {
return recordSold;
}
public float getHPay() {
return hourPay;
}
however, when I run the main program the ID, name and surname variables are still null, they are not being returned by the superclass. Am I missing something please? Thanks
Inheritance only works for methods NOT for variables. It is also bad practice to implement methods in subclasses that access super class variables directly. You'd better implement access methods in your superclass. Due to inheritance, those methods will be available in the sub-classes ass well.
Another thing is the visibility of you instance varibles. You are using the default visibility which is "package-wide". So if your sub-classes are not in the same package, they can't access those variables. If you use "private" or "protected" visibility you are much safer accessing the variables.
Another point is that you are initializing the objects not correctly. Calling the sub-class constructor has to call the super-class constructor as well because your Employee object relies on the functionality that your Person object provides. A more scientific description of this principle exists:
Barbara Liskov - Liskov substitution principle
public class Person {
private int id;
private String name;
private String surname;
public Person() {}
public Person(int i, String n, String s) {
id = i;
name = n;
surname = s;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public int getSurname() {
return this.surname;
}
}
Add access methods for super class instance variables and set visibility to private.
public class Employee extends Person implements Serializable {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee() {}
public Employee(String u, String n, String s, String p, int i, int h, String d, int rSold, float hPay) {
super(id, name, surname);
this.username = u;
this.password = p;
this.hpw = h;
this.date = d;
this.recordSold = rSold;
this.hourPay = hPay;
}
}
Call the super class constructor for initialization of the super class.
Your code should look something like this:
public class Person {
private int id;
private String name;
private String surname;
public Person (int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public int getId() {
return id;
}
... //similarly for getName() and getSurname()
}
public class Employee extends Person {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee (int id, String name, String surname, String username, String password, String date, int hpw, int recordSold, float hourPay) {
super(id, name, surname);
this.username = username;
... //similarly for other parameters.
}
}
The important bit is super(id, name, surname).
EDIT
lionc claims that I did not answer the question, which is true. I did this because the original poster seems to be new to Java and, hence, might be asking the "wrong" question. I should have highlighted this in my original response. Given that my answer is currently marked as the best, I believe that I made the right decision.
You haven't initialized those variables, that's why it is returning default value for those variables. In java following are default values for variables.
int -> 0
String -> null (because String is Object in Java)
You define those attributes in both of your classes so you override them in the subclass. Moreover, your Employee constructor is not the way it should. You should call the adapted super-constructor as your first statement.
public class Person {
protected int id;
protected String name;
protected String surname;
public Person(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
}
public class Employee extends Person implements Serializable {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee(String username, String name, String surname, String pswd, int id,
int hpw, String date, int rSold, float hPay) {
super(id,name,surname);
this.username = username;
this.password = pswd;
this.hpw = hpw;
this.date = date;
this.recordSold = rSold;
this.hourPay = hPay;
}
}
In your constructors, I consider a best practice to give the same name to your parameters as the name of your attributes to initialize and differenciate them thanks to this. Some people also use the same names except that they add a _ at the beginning of all the members of the class. In any case, don't use such meaningless names as "s", "n" etc when the variables they represent have a special meaning (surname, name). Keep those names for example for local variables without any particular semantic (n would be an integer, s would be a String...).
In your example, you don't need tu use super to access the attributes defined in the super class since you are using package visibility for them (and both seems to be in the same package).
However, this is NOT the proper way to write Java code.
You should define a visibility for your attributes. In most case, it is recommended to use private visibility and to define getter and setter methods to access them:
public class Person {
private int id;
private String name;
private String surname;
public Person() {}
public Person(int id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// And so on...
}
In sub-classes, you just have to call getId() or setId(...) to access the Id attribute. No need to call super.getId(). Since Employee extends Person, it has access to all of its public, protected (and package if they are in the same package) attributes and method.
This means that in your current code, you can simply write name = n instead of super.name = n.
public class Employee extends Person implements Serializable {
private String username;
private String password;
private String date;
private int hpw;
private int recordSold;
private float hourPay;
public Employee() {}
public Employee(String username, String name, String surname, String password, int id, int hpw, String date, int rSold, float hPay) {
super(id, name, surname);
this.username = username;
this.password = password;
this.hpw = hpw;
this.date = date;
this.recordSold = rSold;
this.hourPay = hPay;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
// And so on...
}
Now to use these classes, you can write code like:
Employee e = new Employee("user3149152", "Ulrich", "Ser", "passwd", 1234, 0, "2014/08/13", 0, 0);
System.out.println("Employee " + e.getName() + ' ' + e.getSurname() + " has for id " + e.getId() + '.');
For reference, this code works even with your current code.
It prints:
Employee Ulrich Ser has for id 1234.