Polymorphic behavior not being implemented - java

The last two lines of this code illustrate the problem: the compiler works when I use the reference to the object, but not when I assign the reference to an array element. The rest of the code is in the same package in separate files. BioStudent and ChemStudent are separate classes, as well as Student.
package pkgPoly;
public class Poly {
public static void main(String[] arg) {
Student[] stud = new Student[3];
// create a biology student
BioStudent s1 = new BioStudent("Tom");
// create a chemistry student
ChemStudent s2 = new ChemStudent("Dick");
// fill the student body with studs
stud[0] = s1;
stud[1] = s2;
// compiler complains that it can't find symbol getMajor on next line
System.out.println("major: " + stud[0].getMajor() ); // doesn't compile;
System.out.println("major: " + s0.getMajor() ); // works: compiles and runs correctly
}
}

There's a lot of missing info, such as what is s0, or if BioStudent and ChemStudent extend Student, however I'll just assume all of this is true and s0 is either a BioStudent or ChemStudent.
If so, I'm not entirely sure about the proper terminology, but when you use a reference variable of the parent type and point it to a Child object, you can only access the child methods if these override the parent methods.
In other words, you need to have the getMajor() method defined in your parent class Student, then overriden in your child class BioStudent and/or ChemStudent.

stud is an object of class Student.
I am assuming few things -
BioStudent and ChemStudent extends Student class.
BioStudent has a method getMajor()
Student Class does not!
That is the reason stud[0].getMajor() is giving you a compile time error.
You have to typecast it to the subclass of Student.
System.out.println("major: " + ((BioStudent) stud[0]).getMajor() );

According to the information given I am assuming couple of things.
Student is a super class
BioStudent and ChemStudent extends Student
stud[0] = s1
stud[1] = s2
The error that you are getting is because Student class doesnt have getMajor() but the BioStudent and ChemStudent has that method.
You have created a Student array. For the compiler stud[0] is Student class, not the BioStudent nor ChemStudent. Only during the runtime jre would know that stud[0] has BioStudent and stud[1] has ChemStudent. That is why you are getting the compilation error.
Solution 1:
Either add getMajor() method to Student class and the other 2 class overrides it.
OR
Solution 2:
Typecast by adding this to your print statement (BioStudent stud[0]).getMajor() - which explicitly means this is BioStudent object and the compiler would know BioStudent has getMajor().

Related

What is the difference between those kind of instantiation?

it's maybe a newbie question but I think it will be helpful for some beginners.
My question is :
public abstract class Person {
code goes here ....
}
public class Employee extends Person {
code goes here ....
}
What is the difference between those kind of instantiation ?
Person student = new Employee("Dove","Female",0);
and
Employee student = new Employee("Dove","Female",0);
They are essentially the same, but the compiler treats Person student as a Person without any type information from the concrete class Employee
It's basically the same thing, but the difference is that:
1- In the first declaration:
Person student = new Employee("Dove","Female",0);
Here student can't access Employee class specific methods or attributes as it's a Person object which contains an Employee instance.
2- But in the second one:
Employee student = new Employee("Dove","Female",0);
Here student can benefit from both Employee and Person attributes and methods.
Please check Polymorphism Oracle Docs for further reading about polymorphism in Java.
Example:
We can see that in this example, where we use Integer and Object classes:
Integer i1= new Integer(0);
//This will run and execute perfectly
System.out.println(i1.intValue());
Object i2= new Integer(0);
//This will throw an error as `Object` class doesn't have `intValue()` method.
System.out.println(i2.intValue());
This is a live working Demo so you can see that.
Following is difference in both instantiation.
(1)
Person student = new Employee("Dove","Female",0);
In this instantiation student is object of Person class so it can't access Employee class specific methods or attributes.
(2)
Employee student = new Employee("Dove","Female",0);
Here, in second instantiation student can access Employee class specific methods and attributes as well as Person class because it is extending in Employee class.
This is basic difference in this two statements.

Referencing objects to arraylist [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
Hi I'm unsure how I go about referencing objects to my arraylist.
The class where im declaring the arraylist:
Any help would be much appreciated
First of all name is not static so you can not access it as Student.name only instance of student can access it if it's public.Now, you want to construct the Student than you should pass the name of student in constructor.You can declare getter and setter methods for your Student attributes.
Moreover ArrayList.add can be used to add your Students to your list and you better not add students in constructor use different method to write this scenario.
FOR EXAMPLE :
Student student = new Student("NewStudent");
System.out.println("Name of student :" +student.getName());
studentList.add(student);
Regarding:
public TutorGroup() {
super();
Student student = new Student(Student.name); // this makes no sense
studentList.add(student.Student(name, tmaMark));
}
I'm not sure what you're trying to do with new Student(Student.name) since it isn't clear what this code is trying to do, but regardless, the compiler is right -- it shouldn't exist, and so get rid of it.
Delete this TutorGroup constructor and re-do it. How you re-do it will depend on where your TutorGroup is to get the Student objects. If they're going to be packed into an ArrayList and then passed in, then give TutorGroup's constructor an ArrayList<Student> parameter, and when calling the class, pass in the list. If you will add Students one at a time, then make the constructor simple (or get rid of it), and give the TutorGroup class an addStudent method:
public void addStudent(Student s) {
studentList.add(s);
}
In your TutorGroup constructor your trying to pass the value in the name variable in the Student class which you cant access because 1. The name variable is private so only members of the class have access to it. and 2. It doesn't hold a value yet since that's what your trying to pass into the Student constructor.
What you should do is pass a string literal into your Student constructor like: new Student("Jamie") then it will be saved in the name variable in your Student class, and if you need to access the name later add a public method in your Student class that returns the value in your name variable.
Your code has several issues.
Firstly the Student class should have some getter methods, so that you can access the data from a student object:
public String getName() {
return this.name;
}
public int getTmaMark() {
return this.tmaMark;
}
For creating a student object with the correct data, you have 2 options:
Option A) Create a constructor for Student that takes both values:
public Student(String aName, int aMark)
{
super();
this.name = aName;
this.tmaMark = aMark;
}
Option B) Create setters for your Student class
public void setName(String aName) {
this.name = aName;
}
public void setTmaMark(int aMark) {
this.tmaMark = aMark;
}
You can, of course, implement both options in Student, giving you extra flexibility.
Then, to add a new Student to your ArrayList, you can simply create a student and use the array's add method:
Examples:
ArrayList<Student> studentList = new ArrayList<Student>();
// Create student using constructor
Student studentA = new Student("Alice", 15);
// Create student using setters
Student studentB = new Student();
studentB.setName("Bob");
studentB.setTmaMark(10);
// Add both students to the ArrayList
studentList.add(studentA);
studentList.add(studentB);
Please remeber that for the studentB example, if you added a constructor with arguments to your Student class (Option A) you also need to create an explicit default constructor (without arguments).
Im not sure exactly what you are trying to do. I am going to assume you want to add a student into the ArrayList called student list. The line Student student = new Student(Student.name); is creating a new object of type Student called student but you are not passing into any parameters into the constructor for the student class, but it requires a String which is used as the name. What you want to do (i think) is add a student to your array list. As your ArrayList has type student the method to add student x should be
public void addStudent(Student x)
{
studentList.add(x);
}
Where Student x is passed as a paramater to the addStudent method. To Create a new student with the object name newstu and the name nameOfStu you could do this.
Student newstu = new Student(nameOfStu);
addStudent(newstu);
I hope this helps.

Java: cannot find symbol error

I'm taking an intro Computer Science class at university and on our second assaignment I've been getting an error of "Cannot find symbol" when i try changing the stuudent3's name. If I take the statement out it will get up to 75% but then read the error "compile error: changeName method not called properly." Though maybe you guys could help me out and explain to me what is wrong. Thanks in advance!
student3 = student3.changeName(Bill);
(This is where I get the error, Bill is underlined in red and it stats that it cannot find the symbol.)
I'm currently using netbeans if that changes anything.
import ProvidedClasses.Student; // Necessary! Do Not Remove!
public class Question1
{
/*
1) Declare 3 Student object references (variables) with the identifiers student1, student2, and student3
2)
Use the default constructor method of the Student class to instantiate an Student object and assign it to
the student1 object reference (variable)
3) Use the alternate constructor method of the Student class to instantiate a Student object by passing the followin arguments:
First, the String literal "Richard Rosby"
Then, a non-negative integer literal of your choosing
Assign that object to the object reference student2
4) Assign the object reference student3 the value of the object reference Student2
5) Declare 2 String objects oldName and newName
6) Assign oldName the value returned by a method call to the getName method for the student2 object
7) Call the changeName method on the student3 object and pass your own choice of a new name as an argument
8) Assign newName the value returned by a method call to the getName method for the student3 object
*/
public static Object[] question1()
{
// Your Code Goes Here
Student student1 = new Student();
Student student2 = new Student("Richard Rosby", 23);
Student student3 = student2;
student3 = student3.changeName(Bill);
String oldName = student2.getName();
String newName = student3.getName();
// Necessary for Unit Test. Do not remove or modify!
return new Object[] {student1, student2, student3, oldName, newName};
}
Student's constructor accepts a java.lang.String. Assuming you intended to use the literal "Bill", you should surround it with quotes (") - otherwise java interprets it as a variable name, which was of course never declared:
student3 = student3.changeName("Bill");
Perhaps it should be student3.changeName("Bill"); with the double quotes.
Without the double quotes, Java thinks you are using an object or class.
EDIT:
By taking into account the new error you get (Regarding Incompatible types), the problem seems like the method changeName is not returning any thing.
So simply remove student3 = from the statement student3 = student3.changeName("Bill");, that should solve the problem.

I am getting unusual object reference codes and null values when I initialise a constructor

I have a couple of questions about how class instances are set up. If I have an object constructor as follows:
Object(String newName, ArrayList<Person> newPersonList){
name=newName;
personList=newPersonList;
System.out.println(personList);}
which is then assigned to a person as a method in the Object class:
matchPersonToObject(Person person){
this.matchedPerson=person;
person.addToObjects(this); //do I need to add the full project.domain address in here?
//Because if so it will only let me put the class `Person` in rather than an instance `person`
}
//in the person class:
addToObjects(Object obj){
this.objectList.add(obj);
System.out.println(objectList);
}
when I then initialise this as follows:
Person chris=new Person("Chris");
Object obj1=new Object("thing",new ArrayList<Person>(Arrays.asList(chris)))
it gives an output of:
[project.domain.Person#1a40fff] //personList in object constructor
[Object - null] //objectList once person has been matched to it
My two questions are
a) what is that hexidecimal code that is being give to my person instance? Why does it not just display [project.domain.chris]?
b)When I add the object to the objectList, why is this registering as null? Have I initialised the ArrayList correctly?
First: Never name your classes with reserved words of languague you are using, e.g. avoid create classes with names like Vector, Long, etc... generates confuse in your code.
Second: he hexidecimal code you are looking at is the hash code of your class Person, overwrite the method toString() os Person class.
public String toString() {
return <anything_you_want> + name;
}
it's possible a bad package importation because you have a class with Name object and compiler doesn't recognize your class, java.lang.Object is different of your Object class.

Referencing subclasses from superclasses in java

Suppose I have an abstract class Person. There is another class Student which extends Person. But the Student class has a member variable, say college of type String, which is not there in Person class.
We know that we can reference a subclass from a superclass, for example,
Person p = new Student();
Will the object p have the member college?
You won't be able to do p.college. However, you can cast it to Student and in this case it will have:
((Student) p).college;
In your sample, Person object IS a Student and hence will have the college member.
Since you cast the Student to a Person, any public routines or data not present in Person will be hidden by the cast assignment though.

Categories