I understand what is the reference leak and can deal with it, but I'm confused now when I had to write a copy constructor. Does the copy constructor cause leaks too?
public class Student {
private final int ID;
private final String studentName;
private double[] Grades = new double[5];
// constructor:
public Student(int ID, String Name, double[] quizGrades) {
this.ID = ID;
this.studentName = Name;
this.Grades = new double[quizGrades.length]; // use new to avoid REFERENCE LEAKS...
for (int k = 0; k < quizGrades.length; k++) //
this.Grades[k] = quizGrades[k]; //
}
// Copy constructor:
public Student(Student stu) {
this(stu.ID, stu.studentName, stu.Grades);
}
}
I made a copy of array quizGrades so there will not be a leak, but I am not sure whether the copy constructor is fine or not.
Related
I have two classes, my object class, and the ListObjectClass.
In my constructor of ListObjectClass I create an array of an object looking like this:
private ObjectClass[] name;
And I have to make an ID for each ObjectClass, but I don't know how can I do that, do I need to make a getID() and setID() on ObjectClass?
Constructor of ListObject Class:
private int id;
private float pes;
private int nRegistres;
private RellotgeObjecte[] rellotge;
public LlistaRegistreEsportiu(int n) {
this.nRegistres = 0;
rellotge = new RellotgeObjecte[n];
}
You can pass the ID as an argument of the constructor:
public LlistaRegistreEsportiu(int n, int id) {
this.nRegistres = 0;
rellotge = new RellotgeObjecte[n];
this.id = id;
}
I am using a copy constructor and Inheritance in a class called 'Department' to call the information from class 'Teacher' which is a sub-class of 'Person'. After creating my set/get methods, I get the above error. Anyone have any insight as to why this is occurring?
Code from 'Department' class:
public class Department {
private String deptName;
private int numMajors;
private Teacher[] listTeachers; //inherits from Person class
private Student[] listStudents; //inherits from Person class
// First constructor for Department
public Department(String dn, int nm, Teacher[] listTeachers, Student[] listStudents) {
this.deptName = dn;
this.numMajors = nm;
this.listTeachers = new Teacher[listTeachers.length];
for (int i = 0; i < this.listTeachers.length; i++)
{
this.listTeachers[i] = new Teacher (listTeachers[i]);
}
//set method for Teachers Array
public void setListTeachers (Teacher[] other) {
this.listTeachers = new Teacher[other.length];
for (int i = 0; i < listTeachers.length; i++) {
this.listTeachers[i] = new Teacher (other[i]);
}
}
//get method for Teachers Array
public Teacher[] getListTeachers() {
Teacher[] copyTeachers = new Teacher[listTeachers.length];
for (int i = 0; i < copyTeachers.length; i++) {
copyTeachers[i] = new Teacher(this.listTeachers[i]);
}
return copyTeachers;
}
Here are the lines giving me errors:
1) this.listTeachers[i] = new Teacher (listTeachers[i]);
2) this.listTeachers[i] = new Teacher (other[i]);
3) copyTeachers[i] = new Teacher(this.listTeachers[i]);
Code from 'Teacher' class:
public class Teacher extends Person {
private String id;
private int salary;
private int num_yr_prof;
//Constructor for use in Teacher main method.
public Teacher(String n, int a, String s, boolean al, String i, int sal, int numyr) {
super(n, a, s, al);
this.id = i;
this.salary = sal;
this.num_yr_prof = numyr;
}
//Copy constructor for use in Department class.
public Teacher (String n, int a, String s, boolean al, Teacher other) {
super(n, a, s, al);
if (other == null) {
System.out.println("Fatal Error!");
System.exit(0);
}
this.id = other.id;
this.salary = other.salary;
this.num_yr_prof = other.num_yr_prof;
}
Your copy constructor might look like this:
public Teacher(Teacher teacher) {
this( teacher.n, teacher.a, teacher.s, teacher.al,
teacher.id, teacher.salary, teacher.num_yr_prof );
}
Since you do not show the code for the Person class, I have used the variable names n, a, s, and al here. They should be replaced by whatever those variables are named in the Person class. This, of course, assumes that those variables are either public or protected. If they are private, you need to use the getters for those variables (preferred even if they are public or protected).
You need to to your Teacher class a constructor that accepts a Teacher:
public Teacher(Teacher teacher) {
// do something
}
I need to create an object array and read the values of the elements in the constructor from console. I am totally confused how to do it.Can anyone give a clarity about how to do it
public class Student {
int id;
String name;
double marks;
public Student(int id, String name, double marks) {
id = this.id;
name = this.name;
marks = this.marks;
}
}
public class Solution {
public static void main(String[],args)
{
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
Student[] arr=new Student[n];
for(int i=0;i<n;i++)
{
int x =sc.nextInt();
String y=sc.nextLine();
double z=sc.nextDouble();
arr[i]=arr.Student(x,y,z);
}
}
}
I am confused on how to call the constructor.
Can anyone help me?
You can do one of two things:
1.Create a temporary object by calling the constructor and then adding that object in the array:
Student temp= new Student(x,y,z);
arr[i]=temp;
2.Directly instantiate a new object and add it in the array like this:
arr[i]=new Student(x,y,z);
Both methods will work fine, but it is recommended to use method 2 because you should not allocate memory to a temp object when clearly you can achieve the goals without doing so
Instead of:
arr[i]=arr.Student(x,y,z);
Do:
arr[i]=new Student(x,y,z);
Why? Because, Each object in the array is an instance of Student class
Your constructor is declared wrongly. this is always used to refer to the instance variable. Change your constructor to this:
public class Student {
int id;
String name;
double marks;
public Student(int id, String name, double marks) {
this.id = id;
this.name = name;
this.marks = marks;
} }
public class Solution {
public static void main(String[],args)
{
Scanner sc = new Scanner(System.in);
int n=sc.nextInt();
Student[] arr=new Student[n];
for(int i=0;i<n;i++)
{
int x =sc.nextInt();
String y=sc.nextLine();
double z=sc.nextDouble();
arr[i]= new Student(x,y,z); //no need to create an object for arr
}
}
}
Because your constructor is wrong.
public class Student {
int id;
String name;
double marks;
public Student(int id, String name, double marks) {
this.id = id;
this.name = name;
this.marks = marks;
}
}
I have this super class called BasketBallPlayer
I have a child class called ProBasketBallPlayer
If I create an object
BasketBallPlayer bp1;
bp1=new BasketBallPlayer("Tim Duncan", "Center", "Spurs", 83, 220, 4, 5, 8);
public class BasketBallPlayer {
protected String name;
protected String position;
protected String team;
protected int height;
protected int weight;
protected int agility;
protected int speed;
protected int ballHandling;
public BasketBallPlayer() {
this.name = "unknown";
this.position = "unknown";
this.team = "unknown";
this.height = 0;
this.weight = 0;
this.agility = 0;
this.speed = 0;
this.ballHandling = 0;
}
public BasketBallPlayer( String name, String position, String team)
{
this.name = name;
this.position = position;
this.team = team;
this.height = 0;
this.weight = 0;
this.agility = 0;
this.speed = 0;
this.ballHandling = 0;
}
public BasketBallPlayer (String name, String position, String team, int height, int weight,
int agility, int speed, int ballHandling)
{
this.name = name;
this.position = position;
this.team = team;
this.height = height;
this.weight = weight;
this.agility = agility;
this.speed = speed;
this.ballHandling = ballHandling;
}
How can I typecast it to ProBasketballPlayer without getting ClassCastException
Here are the ProBasketballPlayer constructors
public class ProBasketballPlayer extends BasketBallPlayer {
protected int yearsInLeague;
protected String role;
public ProBasketballPlayer()
{
super();
yearsInLeague = 0;
role = "bench";
}
public ProBasketballPlayer( String name, String position, String team )
{
super(name, position, team);
this.name = name;
this.position = position;
this.team = team;
yearsInLeague = 0;
role = "bench";
}
public ProBasketballPlayer(String name, String position, String team, int height, int weight,
int agility, int speed, int ballHandling, int yearsInLeague, String role)
{
super(name, position, team, height, weight, agility, speed, ballHandling);
this.yearsInLeague = yearsInLeague;
this.role = role;
}
You cannot. Casting doesn't change anything about an object, it just tells the compiler that it can interpret the object as a class that is further up the class hierarchy, but not down. Once you instantiate an object, that's it - that object is definitely and irrevocably a member of the class you instantiated. It is a BasketballPlayer, and never will be a ProBasketballPlayer. If you want a Pro, instantiate one - you'll be able to use the Pro as a normal Basketball player, but not vice versa.
As an example:
class Foo
{
int a;
}
class Bar extends Foo
{
int b;
}
Foo obj = new Foo();
obj.a = 0; // our obj has an "a" field because it is a Foo.
obj.b = 0; // but no "b" field, because it is not a Bar.
// It therefore makes no sense to do this:
((Bar)obj).b = 0; // because that's the same as trying to do "obj.b"
// in either case, "obj" is not a "Bar", and cannot have a "b" field. "obj" will always be a "Foo", never a "Bar".
//
// If however we make a Bar:
Bar obj2 = new Bar();
// we can access both fields, since Bar has both of them
obj2.a = 0;
obj2.b = 0;
// and, since Bar is a SUPERSET of Foo (all Bar are Foo, not all Foo are Bar),
// we can even use obj2 as a Foo, and pass it to methods which accept a Foo.
How can I typecast it to ProBasketballPlayer without getting
ClassCastException
You can't cast in the wrong direction. Think about the following two statements...
ISA BasketballPlayer a ProBasketballPlayer?
Are all BasketBallPlayers ProBasketBall players?
No. I play basketball and I'm not a pro basketball player.
Is every Bird a Duck.
Bird b = new Bird();
Duck daffy = (Bird)b;
daffy.quack(); // Error here, not all birds quack?
You can't cast an object to a subclass. Objects can only be casted "downward" from what their constructor's type was. Every Cat is an Animal, but not every Animal is a Cat. Casting only goes one way.
What you can do is create a constructor in ProBasketballPlayer that accepts a BasketBallPlayer and copies in the relevant fields. Make sure to initialize any additional fields that ProBasketballPlayer may have also.
public ProBasketballPlayer(BasketBallPlayer bbp, int yearsInLeague, String role) {
super(bbp.getName(), bbp.getPosition(), bbp.getTeam(), bbp.getHeight(), bbp.getWeight(), bbp.getAgility(), bbp.getSpeed(), bbp.getBallHandling());
this.yearsInLeague = yearsInLeague;
this.role = role;
}
public public ProBasketballPlayer(BasketBallPlayer bbp) {
this(bbp, 0, "bench");
}
If ProBasketballPlayer is in the same package as BasketBallPlayer, then you can access the fields directly (e.g. bbp.name) instead of using getters.
public class Location {
final public static int INITIAL = 0;
final public static int PRISON = 1;
final public static int DEATH = 2;
final public static int SQUARE = 3;
private String name;
private int type;
private int section;
private int damage;
private Square square ;
// this constructor construct a Location from a name and a type.
public Location(String name, int type) {
this.name = name;
this.type = type;
}
// this constructor constructs a Location of type SQUARE from a name, section, and damage.
public Location(String name, int section, int damage) {
this.name = name;
this.section = section;
this.damage = damage;
this.square = new Square(name,section,damage);
}
// Get the square associated with this Location.
public Square getSquare() {
return square;
}
}
I think I'm misunderstanding what the second constructor is doing, as currently the constructor isn't doing anything to the instance variable square.
In your second constructor, you just have to initialize type with Location.SQUARE:
// this constructor constructs a Location
// of type SQUARE from a name, section, and damage.
public Location(String name, int section, int damage) {
this.name = name;
this.section = section;
this.damage = damage;
this.type = Location.SQUARE;
this.square = new Square(name,section,damage);
}
And now your class' attributes will be consistent.
Regarding initialization of the square attribute, it seems to be OK to me. You can create instances of other classes inside a constructor and assign them to attributes if you want.
In your second constructor you are simply initializing your property - private Square square of your Location class from the parameters you provided to the constructor.
Initializing an Object/non-primitive (eg.- square here) type is completely valid in java like initializing other primitive type (eg. - type, section etc here)
You have a problem: Your first constructor does nothing with the Square reference, so it's null.
Try it like this:
/**
* #link http://stackoverflow.com/questions/31523704/how-to-use-a-constructor-to-initialize-an-different-classs-object-in-java
* User: mduffy
* Date: 7/20/2015
* Time: 3:07 PM
*/
public class Location {
final public static int INITIAL = 0;
final public static int PRISON = 1;
final public static int DEATH = 2;
final public static int SQUARE = 3;
private String name;
private int type;
private int section;
private int damage;
private Square square;
// No idea what damage ought to be. Is that your type?
public Location(String name, int type) {
this(name, Location.SQUARE, type);
}
public Location(String name, int section, int damage) {
this.name = name;
this.section = section;
this.damage = damage;
this.square = new Square(name, section, damage);
}
public Square getSquare() {
return square;
}
}