first time I've tried this. I need to be able to replace an email for subclass Student and sublass Teacher after an email has been inputted, I have a parent class and superclass which is where I believe I need to add my changeEmail method. I may be a way off here but can I use stringBuilder or is there an easier way? Real noob when it comes to this.
SUBCLASS -
public class Teacher extends Member
{
private String qualifications;
public Teacher(String name, String email, String qualifications)
{
super(name, email);
this.qualifications = qualifications;
}
public String getQualifications()
{
return qualifications;
}
public String toString()
{
StringBuffer details = new StringBuffer();
details.append(super.getName());
details.append(' ');
if(qualifications != null && qualifications.trim().length() > 0) {
details.append("(" + qualifications + ")");
details.append(' ');
}
details.append(super.getEmail());
return details.toString();
}
}
SUBCLASS -
public class Student extends Member
{
private int attendance;
public Student(String name, String email)
{
super(name, email);
this.attendance = 0;
}
public int getAttendance()
{
return attendance;
}
public void markAttendance(int attendance)
{
this.attendance += attendance;
}
public void print()
{
System.out.println(super.getName() + " (" + attendance + ")");
}
}
SUPERCLASS -
public class Member
{
private String email;
private String name;
public Member(String name, String email)
{
this.name = name;
this.email = email;
}
public String getEmail()
{
return email;
}
public String getName()
{
return name;
}
public String changeEmail()
{
//..........
}
}
Since changeEmail is a public method in the superclass, the subclasses can access it too. Student (as well as Teacher) is a Member.
public String changeEmail(String newEmailAddress) {
String old = email;
this.email = newEmailAddress;
return old;
}
What I changed was adding a parameter (String newEmailAddress) and then set the new value to the email instance field.
(EDIT: I updated the answer to return the old email address. I don't know why a method like this would return anything but anyways..)
That is called inheritance, basically if you have some shared variables, you can use some parent class and with the keyword extends create some subclasses.
All subclasses, which inherits the parent class, can have their own class variables, but also are having the parent variables.
In your case you can image the diagram like that- obvious, doesnt?
So...
Parent class member is having these class variables:
- String : mail
- String : name
You have two subclasses- Student and Teacher:
Teacher class variables:
qualifications
mail, name (inherited from parent!)
Student class variables:
attendance
mail, name (inherited from parent!)
Notice- with the keyword super you are calling the constructor (or simply "class" other methods) from the parent, so in Teacher and Student class, you will call exactly following:
public Member(String name, String email) {
this.name = name;
this.email = email;
}
To be able change the email, you need following
1) implement methods in parent class
2) optional- add call to child classes, and for usage outside the class also add some external method (without this you can still use public parent class methods)
Eg.
in parent
public void changeEmail(String newEmail) {
this.email = newEmail;
}
public String changeEmailWithReturnOld(String newEmail) {
String oldMail = this.email;
changeEmail(newEmail); //calling above
return oldMail;
}
In childs
public String changeTheMailWithReturnOld(String newMail) {
return super.changeEmailWithReturnOld(newMail); //super means super class, parent
}
Clear? :)
Then you can call following:
Teacher teacher1 = new Teacher("foo", "foo#foo.foo", "whateverFoo");
teacher1.changeEmail("someNewFoo#foo.foo"); //parent method
teacher1.changeEmailWithReturnOld("someNewFoo#foo.foo"); //Child method
Related
I am supposed to refactor duplicated attributes in Student class. I have Student and Professor classes as below. I am really confused about how to do refactoring with attributes. Should I add a new class, or made modifications in one of the classes. If so, how? I could not understand how to proceed with this to-do.
private final String matrNr;
private final String name;
private final int age;
private int semester;
private final String email;
public Student(String name, int age, String email, String matrNr, int semester) {
this.matrNr = matrNr;
this.name = name;
this.age = age;
this.semester = semester;
this.email = email;
}
public String getEmail() {
return email;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getSemester() {
return semester;
}
public String getMatrNr() {
return matrNr;
}
public void increaseSemester(){
semester = semester + 1;
}
}
And the professor is a like:
private final String persNr;
private final String name;
private final int age;
private final String email;
public Professor(String name, int age, String email, String persNr) {
this.persNr = persNr;
this.name = name;
this.age = age;
this.email = email;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public String getPersNr() {
return persNr;
}
}
Thanks for any kind of helps!
Your goal is to refactor duplicated attributes in the Student and Professor classes. The way to do this is to create a parent class which defines the common attributes (like "name"), and modify Student and Professor classes to extend the common parent class. In this way, both Students and Professors can have a "name", even though you have defined "name" only once in the common parent.
Below shows how you could do this with a common "Human" parent class, how the constructors would work, and how you could define a Student-only attribute (semester).
Here is a simple version a common Human class:
common "Human" class
each Human has a "name"
the name is set in the constructor (so when you're creating an object) and cannot be changed later ("name" is final; also no "setHuman()")
class Human {
private final String name;
public Human(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Here's a simple Professor class:
by definition, a Professor is a Human (Professor extends Human)
when creating a Professor, you must specify the "name" (which is then passed to the Human constructor)
once you have a Professor, you can call getName() (which is defined on the Human class)
class Professor extends Human {
public Professor(String name) {
super(name);
}
}
Here's a simple Student class:
Student is a little different - in addition to a name, it also has a "semester"
when creating a Student, the constructor requires a name and semester, and the Student class itself keeps track of "semester" – so it's fine to have semester defined on Student, and name defined on Human.
you can call getName() (defined on Human)
you can call getSemester() (defined on Student)
class Student extends Human {
private final int semester;
public Student(String name, int semester) {
super(name);
this.semester = semester;
}
public int getSemester() {
return semester;
}
}
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;
}
}
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;
}
}
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 and Customer2 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(); // you could leave this out - it is implied
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.
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.
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.
I'm a JAVA beginner.
I am trying to create a java phonebook which as three main classes
Contacts.java
Phonebook.java
Showphonebook.java
Contacts has two variables that are non-static, name and phone, which hold name and phone numbers of a person.
Then Phonebook is a class which holds the Phonebook objects and has a variable owner which is a string. So basically, the Phonebook object holds a owner and makes references to Contacts object to add contacts to it.
Then the final class Showphonebook is the class that makes a new Phonebook with owner and adds contacts to it.
Here is my code for above:
Contact.java
public class Contact {
private String name;
private String phone;
public Contact(String name, String phone) {
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String toString() {
return name + ": " + phone;
}
}
Phonebook.java
import java.util.*;
public class Phonebook
{
private String owner;
public ArrayList<Contact> contacts = new ArrayList<Contact>();
public Phonebook(String owner) {
this.owner = owner;
}
public void addContact(Contact name) {
contacts.add(name);
}
public void show() {
System.out.println(owner + "'s phonebook");
for (Contact name : contacts) {
System.out.println(name);
}
}
/*public String findContactByName(String contactToSearch) {
for (Contact name : contacts) {
if (this.getName().equals(contactToSearch)) {
}
}
}*/
}
ShowPhonebook.java
public class ShowPhonebook
{
public static void main(String[] args) {
Phonebook phonebook1 = new Phonebook("Sam Johnson");
phonebook1.addContact(new Contact("Kelly Wong", "(02) 12345678"));
phonebook1.addContact(new Contact("Richard Jackson", "(02) 87654321"));
phonebook1.show();
}
}
I wanted to make a method in Phonebook.java which can SEARCH the phonebook to see if a contact exists , else return null.
How can I do this? I was thinking if I will use getName() method in Contact to pull out the NAME of each contact in the contacts ArrayList and compare it to the contactToSearch variable, but since getName() is non-static, how do I do it? I am confused because Contact holds the getName, but to reference that, I need an object, but my only object phonebook1 is in ShowPhonebook class, which I feel has to go through two classes to get there. Not sure how to do it.
Looking for guidance here!
First of all, welcome to stack overflow!
Now I'm assuming you are new to java hence confused about how references and this work in java. To get what you are asking, I would suggest following modification in the commented method-
public String findContactByName(String contactToSearch) {
for (Contact contact : this.contacts) { // changed "name" to "contact"; variable name should be aptly chosen
if (contact.getName().equals(contactToSearch)) {
// TODO: do your thing with "contact" variable
}
}
}
this refers to the current instance of the class. In your case, this will refer to the phonebook1 instance.
I have parent class Person and a subclass SubPerson
//Parent class
public class Person {
protected String Name;
protected String Email;
public Person(String name, String email) {
Name = name;
Email = email;
}
//Child Class
public class SubPerson extends Person {
private String Id;
private String Telephone;
public SubPerson(){
}
public SubPerson(String name, String email, String id, String tel) {
super(nombre, email, String Id, String );
Id = id;
Telephone = tel;
}
How should I invoke the constructor of the child class in another block of code?
My attempt is the following
// ... Other Methods
// This method stores the value in a database
public String RegisterSubClass(String name, String email, String id, String tel){
super(name, email); //This error says that super expected 0 parameters
}
How can I call the constructor in a way that allows me to assign the parameters that belong to the parent and the parameters that belong to the child?
Thanks
I don't think you can invoke the parent class constructor from another method in child, it has to be the first call in the child class constructor. However you can call other methods in the base class that set the values for variables.
Begging java programming recently, run into an error. please help
Have two classes , PersonTest.java:
public class PersonTest {
public static void main(String[] args) {
Person person1=new Person("dummy","sdymmt","20","male","washington");
System.out.println("Name: "+person1.getName());
System.out.println("Surname: "+person1.getSurname());
System.out.println("Age: "+person1.getAge());
System.out.println("Gender:" +person1.getGender());
System.out.println("Birthplace: "+person1.getBirthplace());
Person person2= new Person(400);
System.out.println("Income:"+person2.getX()+" mije leke");
System.out.println("Tax:"+person2.Taksat()+" mije leke");
Student student1= new Student("adsd","zedsdsadza");
System.out.println("emri"+student1.getEmer());
}
}
and also Person.java :
public class Person {
private String Name;
private String Surname;
private String Age;
private String Gender;
private String Birthplace;
private double x;
public Person()
{
}
public Person(String Name, String Surname, String Age, String Gender, String Birthplace) {
this.Name = Name;
this.Surname = Surname;
this.Age = Age;
this.Gender = Gender;
this.Birthplace = Birthplace;
}
public String getName() {
return Name;
}
public String getSurname() {
return Surname;
}
public String getAge() {
return Age;
}
public String getGender() {
return Gender;
}
public String getBirthplace() {
return Birthplace;
}
public Person(double x) {
this.x = x;
}
public double getX() {
return x;
}
double Taksat() {
return (0.1 * x);
}
public class Student extends Person {
private String University;
private String Faculty;
public Student(String Universiteti, String Fakulteti) {
super(Name, Surname, Age, Gender, Birthplace);
this.Faculty = Fakulteti;
this.University = Universiteti;
}
public String getFaculty() {
return Faculty;
}
public String getUniversity() {
return University;
}
}
}
Two classes are in the same default package. How to fix the fact that the test class doesn't recognize the inner class student as a class.
Nested non static class are called Inner Classes those classes cannot live without the Outer class (which wrapped them).
Java docs
An instance of InnerClass can exist only within an instance of
OuterClass and has direct access to the methods and fields of its
enclosing instance.
To instantiate an inner class, you must first instantiate the outer
class. Then, create the inner object within the outer object with this
syntax:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Try using:
Person.Student student = person1.new Student(PARAMETERS);
Important Mark:
Of course, you should highly consider that this is not a good design, because you may want this classes to be visible outside of the Person class but also because Person.Student inherits from Person, which it's already contains the Student class, which usually looks like a loop or a circle relationship, which usually not a good idea for the first place.
Because there is no Student class. Since it nested, it's Person.Student