Java Object set attribute default - java

class AStudent {
private String name;
public int age;
public void setName(String inName) {
name = inName;
}
public String getName() {
return name;
}
}
public class TestStudent2 {
public static void main(String s[]) {
AStudent stud1 = new AStudent();
AStudent stud2 = new AStudent();
stud1.setName("Chan Tai Man");
stud1.age = 19;
stud2.setName("Ng Hing");
stud2.age = -23;
System.out.println("Student: name="+stud1.getName()+
", age=" + stud1.age);
System.out.println("Student: name="+stud2.getName()+
", age=" + stud2.age);
}
}
How can I enhance the class AStudent by adding data encapsulation to the age attribute. If the inputted age is invalid, I want to print an error message and set the age to 18.

First, modify age so that it isn't public. Then add accessor and mutator methods (in the mutator, check for an invalid value - and set it to 18). Something like,
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 0) {
System.err.println("Invalid age. Defaulting to 18");
age = 18;
}
this.age = age;
}
Then you could use it with something like setName
stud1.setAge(19);
and
stud2.setAge(-23);
And you could make it easier to display by overriding toString in AStudent like
#Override
public String toString() {
return String.format("Student: name=%s, age=%d", name, age);
}
Then you can print yor AStudent instances like
System.out.println(stud1); // <-- implicitly calls stud1.toString()
System.out.println(stud2);

You are using encapsulation for the name attribute. You could do the same for age.
class AStudent {
// ...
private int age;
public void setAge(int age) {
this.age = age;
if (age < 1) {
this.age = age;
}
}
}
The above code changes the age attribute to private so that access is restricted to the getter and setter. So you will also have to add a getter method and change TestStudent2 to use the new getter and setter.
What makes an age invalid? The above code assumes any value less than 1 is invalid.

Related

I'm having problems with understanding Object Orientation - java

I have been asked to create a class which simply prints "You have been registered".
In the second part, I am to create a test class. The test class should create two student instances (also called objects). Then to print their names and call the registered method of both of them. I keep getting errors saying 'the assignment to variable yearOfBirth has no effect' and in the test class 'The constructor String is undefined'.
Can you help with understanding the errors in my code.
public class Student{
//Attributes
private String name;
private String gender;
private int yearOfBirth;
//Constructors
public Student (String name, String gender, int yearOfBirth){
this.name = name;
this.gender = gender;
this.yearOfBirth = yearOfBirth; // Default age of new student
}
public Student (String name, String gender){
this.name = name;
this.gender = gender;
this.yearOfBirth = 0;
}
//Getters & Setters
public String getName() {
return name; }
public void setName (String name) {
this.name = name;
}
public String getGender () {
return gender;
}
public void setGender (String gender) {
this.gender = gender;
}
public int getYearOfBirth() {
return yearOfBirth;
}
public void setYearOfBirth() {
if(yearOfBirth >= 0 && yearOfBirth <= 100) {
this.yearOfBirth = yearOfBirth;
}else {
System.out.println("Age not valid");
}
}
// Other Methods
public void Registered() {
System.out.println(name + "You have been registered");
}
}
public class StudentTest {
public static void main(String[] args) {
Student student1 =new Student("Kevin Sanches", "male", "1972");
Student student2 = new Student("Cameron Young", "male", "1993");
student1.Registered();
student2.Registered();
System.out.println(student1);
System.out.println(student1);
}
}
There are two issues in your code:
The assignment to variable yearOfBirth has no effect. You are invoking a setter method on a property but you are not passing any value, hence the warning. You should provide a value as a parameter and set that to the corresponding object property.
The constructor problem is that the age parameter is of type int instead when you construct the objects you are passing the age as string.
Your constructor expects two strings and an integer as parameters. You are passing three strings.
Correct way:
Student student1 =new Student("Kevin Sanches", "male", 1972);
Student student2 = new Student("Cameron Young", "male", 1993);
Also, in your method setYearOfBirth you forgot to pass the yearOfBirth as parameter.
public void setYearOfBirth(int yearOfBirth) {
if(yearOfBirth >= 0 && yearOfBirth <= 100) {
this.yearOfBirth = yearOfBirth;
}else {
System.out.println("Age not valid");
}
}
You are trying to send 3 Strings which none of your constructors are ready to take. You have a constructor with 2 Strings and an int, so the correct way of creating the object would be,
Student student1 = new Student("Kevin Sanches", "male", 1972);
Without the double quotes 1972 would be an int.
You are assigning this.yearOfBirth to this.yearOfbirth in the setter. Even though code is just this.yearOfBirth = yearOfBirth; technically both are this.yearOfBirth variables.
This needs to change by accepting the value and assigning it like:
public void setYearOfBirth(int yearOfBirth) {
if(yearOfBirth >= 0 && yearOfBirth <= 100) {
this.yearOfBirth = yearOfBirth;
}else {
System.out.println("Age not valid");
}
}
You are trying to pass a String value to the constructor that accepts int for the yearOfBirth value, change it like:
Student student1 =new Student("Kevin Sanches", "male", 1972);
Student student2 = new Student("Cameron Young", "male", 1993);

How to correctly configure multiple constructors?

I'm doing an assignment based around inheritance and I have created 2 constructors that are suppose to do different things. One constructor does not have any parameters and should produce a pre-defined value, the other constructor has 2 parameters which consist of a name and an age of types String and int. I have somehow reconfigured the two constructors so that they both do not produce what they should be. Here is the classes that these constructors are invoked in:
Animal (super class)
abstract public class Animal implements Comparable<Animal>
{
int age;
String name;
Animal(String name, int age)
{
this.age = age;
this.name = name;
}
Animal()
{
this("newborn", 0);
}
public int getAge()
{
return age;
}
public void setName(String newName)
{
name = newName;
}
String getName()
{
return name;
}
}
Carnivore
public class Carnivore extends Animal
{
Carnivore(String name, int age)
{
this.age = age;
this.name = name;
}
Carnivore()
{
super();
}
#Override
public int compareTo(Animal o)
{
//To change body of generated methods, choose Tools | Templates.
throw new UnsupportedOperationException("Not supported yet.");
}
}
Wolf
public class Wolf extends Carnivore
{
String name;
int age;
Wolf(String name, int age)
{
this.name = name;
this.age = age;
}
Wolf()
{
super();
}
String getName()
{
return name;
}
}
Main method
System.out.println("************1st constructor of Wolf************");
Wolf wolfExample = new Wolf("Bob", 2) {};
System.out.println("Name = " + wolfExample.getName());
System.out.println("Age = " + wolfExample.getAge());
System.out.println("************2nd constructor of Wolf************");
Wolf newWolf = new Wolf();
System.out.println("Name = " + newWolf.getName());
System.out.println("Age = " + newWolf.getAge());
Actual Output
************1st constructor of Wolf************
Name = Bob
Age = 0
************2nd constructor of Wolf************
Name = null
Age = 0
Expected Output
************1st constructor of Wolf************
Name = Bob
Age = 2
************2nd constructor of Wolf************
Name = newborn
Age = 0
The ages are returning their default value and the name for the second constructor is also returning null but I'm not too sure why. This is my first time working with multiple constructors so I'm a little confused as to ow it works so any help would be much appreciated, thanks.
Your base class seems correct, but you need to change your implementations.
Your Wolf and Carnivore constructors should be:
Wolf(String name, int age)
{
super(name, age);
}
Reason being, you are setting the local instance variables for each type, but calling getAge() method of the super class - this is getting the super's value of age, whose's value has not actually been assigned anywhere, and is given a default value of 0. This goes the same for name, which defaults to null.
You need to call super with the passed variables, and do not need to redefine them for each extended object.

Java class setter not setting correct value to class field.

I have a simple java program I and I cannot figure out why the setter for a class will not set the correct value.
I have a class Employee, a class Department, a class Company. Once I am able to set correct values to the fields of an Employee instance I will then store that employee in a arraylist of employees in an instance of Department(arrayList field).
The class called Employee. It has four fields, String fName, String lName, int age, String department. I am able to set fName and lName though age is always set to 0 and department is always set to null.
Here is the code for the employee class:
public class Employee {
private String fName;
private String lName;
private String department;
private int age;
//getters and setters for the private fields of the Employee class
public void setAge(int num){
num = age;
}
public int getAge(){
return age;
}
public void setDepartment(String dep){
dep = department;
}
public String getDepartment(){
return department;
}
public void setfName(String afName){
fName = afName;
}
public String getfName(){
return fName;
}
public void setlName(String alName){
lName = alName;
}
public String getlName(){
return lName;
}
}
Here is the code for a method called addEmployee:
public void AddEmployee(Department depInstance){
String firstName = JOptionPane.showInputDialog("Enter employee First name");
String lastName = JOptionPane.showInputDialog("Enter employee last name");
int empAge = Integer.parseInt(JOptionPane.showInputDialog("Enter employee age"));
String empDep = JOptionPane.showInputDialog("Enter employee department");
Employee employeeToAdd = new Employee();
employeeToAdd.setfName(firstName);
employeeToAdd.setlName(lastName);
employeeToAdd.setAge(empAge);
employeeToAdd.setDepartment(empDep);
//test input and variable setting
System.out.println("--------Inputs------");
varTester(firstName,lastName,empAge,empDep);
System.out.println("--------Recorded Vals------");
varTester(employeeToAdd.getfName(), employeeToAdd.getlName(),employeeToAdd.getAge(),employeeToAdd.getDepartment());
public static void varTester(String empfName, String emplName, int empAge, String empDep){
System.out.println(empfName);
System.out.println(emplName);
System.out.println(empAge);
System.out.println(empDep);
}
}
This is the output from the test method varTester():
--------Inputs------
Somefirstname
Somelastname
32
Accounting
--------Recorded Vals------
Somefirstname
Somelastname
0
null
I test the values received from the showInputDialog's and it is the correct values I want to store int the class instance fields of employeeToAdd though only the first and last name values are set and not the age or department. Can someone point me in the right direction. Thank you.
You got the setter backwards. It should be :
public void setAge(int num){
age = num;
}
You have the same error in setDepartment.
You are supposed to assign to the member variable, not to the argument of the setter method.
Your setter sets the argument not the private field.
public void setAge(int num){
num = age;
}
public void setDepartment(String dep){
dep = department;
}
Change it to:
public void setAge(int num){
age = num;
}
public void setDepartment(String dep){
department = dep;
}
It should be:
public void setAge(int num){
age = num;
}
public void setDepartment(String dep){
department = dep;
}

java - can't create a constructor

class Human{
// declared instance variables
String name;
int age;
// instance method
void speak(){
System.out.println("My name is: " + name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return age;
}
String getName(){
return name;
}
// so when I create an instance, i can't have constructor?
// error here
Human(int age){
age = this.age;
}
}
}
public class GettersAndReturnValue {
public static void main(String[] args) {
// error here because I created a constructor Human(int a)
Human human1 = new Human();
human1.name = "Joe";
human1.age = 25;
human1.speak();
int years = human1.calculateYearsToRetirement();
System.out.println("Years till retirements " + years);
int age = human1.getAge();
System.out.println(age);
}
}
I tried to create a constructor Human(int age) to practice 'this' keyword and to change the age from 25 to something else but I get an error because I have one Human class and one Human constructor. When I try to create an instance of Human Type in my main method, eclipse is asking me to remove the constructor
You've swapped the order in your assignment,
Human(int age){
age = this.age;
}
should be something like (don't forget to initialize name too)
Human(int age){
this.age = age;
this.name = "Unknown";
}
You're assigning the default value 0 to the passed in parameter. If you provide a constructor then the compiler will no longer insert the default constructor,
Human() {
this.age = 0;
this.name = "Unknown";
}
and you might as well add a constructor that takes the name,
Human(int age, String name) {
this.age = age;
this.name = name;
}
then you could call it (in main) like
Human human1 = new Human(25, "Joe");
// human1.name = "Joe";
// human1.age = 25;
You have to create a no parameter constructor, because when you are calling Human h = new Human();, you are calling a no parameter constructor.
Try doing this instead:
Human h = new Human(age);
When you create a non-empty constructor, the empty constructor will not be available anymore. You do can have more than one constructor, but if you want the no-argument constructor along with other, you will have to recreate it.
//Please, make it public for constructors
public Human(int age){
this.age = age; //this.age first, to receive the parameter age
}
public Human() {} //Empty constructor. It doesn't has to be a content.
So you call:
Human humanOne = new Human(); //Using no-argument constructor
Human humanTwo = new Human(25); //Using constructor with int to set age
When you create a constructor in the class, it will no longer use the default constructor. In your code, you've created a public Human(int) constructor, so there is no default constructor. Because of that, you cannot create human object like this:
Human a = new Human();
To do that, you have to manually implement a no-argument Human constructor.
Here is a solution:
class Human{
String name;
int age;
//default constructor
public Human (){
}
//paramete constructor
public Human(int a){
this.age=a;
}
void speak(){
System.out.println("My name is: " + this.name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return this.age;
}
String getName(){
return this.name;
}
}
Here's the working code :
Create a class GettersAndReturnValue and add this. You need a empty constructor.
class Human{
// declared instance variables
String name;
int age;
// instance method
void speak(){
System.out.println("My name is: " + name);
}
int calculateYearsToRetirement(){
int yearsLeft = 65 - age;
return yearsLeft;
}
int getAge(){
return age;
}
String getName(){
return name;
}
// so when I create an instance, i can't have constructor?
// error here
Human(int age){
this.age = age;
}
public Human() {
// TODO Auto-generated constructor stub
}
}
public class GettersAndReturnValue {
public static void main(String[] args) {
// error here because I created a constructor Human(int a)
Human human1 = new Human();
human1.name = "Joe";
human1.age = 25;
human1.speak();
int years = human1.calculateYearsToRetirement();
System.out.println("Years till retirements " + years);
int age = human1.getAge();
System.out.println(age);
}
}
Output :
My name is: Joe
Years till retirements 40
25

How to get the methods that return the class members? [duplicate]

This question already has answers here:
Java Reflection: How can I get the all getter methods of a java class and invoke them
(7 answers)
Closed 8 years ago.
I want to know if I can get the methods that returns class members.
For example I have a class called Person inside this class there is two members that are name and age and inside this class I have 4 methods as follow :
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
so if I use the method Person.class.getDeclaredMethods(); it returns all the methods that are declared inside this class and also Person.class.getDeclaredMethods()[0].getReturnType(); returns the return type of the method.
But what I need is to get the methods that returns the two variables name and age In this case the methods are public String getName() and public int getAge().
What can I do?
In your class name and age are not global. They would need to have a static before them to be global. In order to access your fields with an instance and reflection you could do something like
public static void main(String args[]) {
Person p = new Person("Elliott", 37);
Field[] fields = p.getClass().getDeclaredFields();
for (Field f : fields) {
try {
f.setAccessible(true);
String name = f.getName();
String val = f.get(p).toString();
System.out.printf("%s = %s%n", name, val);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output is (as I would expect)
name = Elliott
age = 37

Categories