I am doing a project based around the concepts of inheritance and have created a super constructor which has two variables within itself (String, int), this super constructor is then called within a sub constructor that inherited the super constructors class. I then use two methods to return the properties of those variables within the constructors. The age property is outputting fine but the String property is returning null. Here's the code:
Animal super-class
abstract public class Animal
{
int age;
String name;
Animal(String name, int age)
{
this.age = age;
this.name = name;
}
Animal()
{
this("newborn", 0);
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
}
Wolf sub-class
public class Wolf extends Carnivore
{
String name;
int age;
Wolf(String name, int age)
{
this.name = name;
this.age = age;
}
Wolf()
{
super();
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
Main method class
public class Main {
public static void main(String[] args)
{
Wolf newWolf = new Wolf();
System.out.println("Name = " + newWolf.getName());
System.out.println("Age = " + newWolf.getAge());
}
}
Age is returning as 0 which is correct but System.out.println("Name = " + newWolf.getName()); seems to be returning null instead of "newborn". Any help on resolving this issue is appreciated thanks.
Update - I need the getName() method for another constructor that I haven't included in this example so is there a way to have them both exist?
The issue here is that you are defining your fields in the sub-class, you don't need to as they are inherited from the parent.
Your class has two sets of fields, one from the super (these are the ones set by your constructor, which is calling super() and the other from the child class (these are the ones returned by your getters, which are not initialized. the zero is int's default, not set either).
So simply remove the fields definition from the child class
Related
This is my parent class
abstract public class Person {
private String name;
private Date birthday;
private double difficulty;
protected abstract String personType();
protected abstract Person clone();
Person(String name, Date birthday, double difficulty) {
this.name = name;
this.birthday = birthday;
this.difficulty = difficulty;
}
Person(Person copy) {
this.name = copy.name;
this.birthday = copy.birthday;
this.difficulty = copy.difficulty;
}
Person(){
this.name = "";
this.birthday = new Date();
this.difficulty = 0;
}
public String getName() {
return this.name;
}
public Date getBirthday() {
return this.birthday;
}
public double getDifficulty() {
return this.difficulty;
}
And I want to make a subclass called Singer with the same constructor variables. My question is, how do I initialize the variables "name", "birthday", and "difficulty" in the Singer subclass by calling onto the parent class Person?
public class Singer extends Person{
String debutAlbum;
Date debutAlbumReleaseDate;
Singer(String name, Date birthday, double difficulty, String debutAlbum, Date debutAlbumReleaseDate){
this.debutAlbum = debutAlbum;
this.debutAlbumReleaseDate = debutAlbumReleaseDate;
//im not sure what to put here for name, birthday, and difficulty
}
}
You can use 1 of these 3:
Using super() method (recommended):
Add in the first line on the constructor this line super(name, birthday, difficult).
This line will call the constructor of Person class for your object.
Notice: super method can be used only in the first line of the constructor
Add set() method:
In the Person class, add set method for each variable and then call them in the constructor.
Change access modifications:
Change the access modifications of each variable in Person class to protected or public and then use this.name = name;.
I can't set the the values directly in Setter Method of my User bean class using reflection
I can only access those getter method but i can't set the value in the
Setter method of User Bean Class.
how to invoke setter method by reflection in java
method-by-reflection-in-java
//------->This My UserClass
public class User {
private String name;
private int age;
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
private int getAge() {
return age;
}
private void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
//------> Then My Main Method
public static void main(String args[])
{
try {
User user = new User();
Method method = User.class.getDeclaredMethod("setName", String.class);
method.setAccessible(true);
method.invoke(user, "Some name");
System.out.println("user.getName() = " + user.getName());
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
I want call the Setter method directly in and set the value in Setter that changes can reflected in User Bean setter method. Please let me Know is that possible.
It is because your setName() method is set to private. You can not access any private methods of a class, outside that class itself.
Change it to..
public void setName(String name) {
this.name = name;
}
And you will be good to go.
I executed your code and its working fine. Using Reflection api you can invoke the private methods by setAccessible as true.
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.
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
Why i am getting error in the starting of Employee constructor that cannot find symbol
constuctor Person?
class Person {
String name = "noname";
Person(String nm) {
name = nm;
}
}
class Employee extends Person {
String empID = "0000";
Employee(String eid) {// error
empID = eid;
}
}
public class EmployeeTest {
public static void main(String args[]) {
Employee e1 = new Employee("4321");
System.out.println(e1.empID);
}
}
You need to call
super(name);
as the first statement of the constuctor Employee as the compiler will otherwise implicitly call the no-argument constructor for Person which doesnt exist
where name is an added argument to Employee
Employee(String eid, String name) {
super(name);
empID = eid;
}
Take a look at example 8.2-1 from the JLS which shows how a similar example fails in the absence of an explicit super method call.
When you create an employee, you'll need to specify both a name and an employee id - since every employee is a person, and every person needs a name. The constructor for Employee should probably look like this.
public Employee(String eid, String name) {
super(name);
empID=eid;
}
The super line specifies how to call the superclass's constructor. It needs to be in there because there's no constructor for the superclass without parameters. A superclass constructor must be called, there's only one available constructor, and that constructor needs the name argument to be specified.
You should do something like this to get your program to work:
class Person {
String name = "noname";
Person(String name) {
this.name = name;
}
}
class Employee extends Person {
String empID = "0000";
Employee(String empID , String name) {
super(name);
this.empID = empID;
}
}
public class EmployeeTest {
public static void main(String args[]) {
Employee e1 = new Employee("4321" , "Ramesh");
System.out.println(e1.empID);
System.out.println(e1.name);
}
}
I have a couple of points to add.
It is always a good habit to make your data member private. If you want to access those members outside the class, use getters and setters. ( getName(), setName() etc. )
Your constructors ( Person() and Employee() ) HAVE to be defined if you want to creating an object without using parameterized constructor. NO default contstructor will be provided for you if you want to instantiate using a non-parameterized constructor. So do THIS whenever you are using a parameterized constructor as a good habit:
class Person {
private String name = "noname";
Person() {}
Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
class Employee extends Person {
private String empID = "0000";
Employee() {}
Employee(String empID,String name) {
this.empID = empID;
}
public String getEmpID() {
return this.empID;
}
public void setName(String empID) {
this.empID = empID;
}
}