I need a bit of help here. so i have this. I was basically wondering when you create an array of object of a parent class, then change that object to a child class, can I access the methods of that child class and if not why. thanks for any help.
public class Racer {
private String name;
private int position;
// Constructor
public Racer()
{}
public Racer(String name)
{
this.name = name;
position = 0;
}
public String getName()
{
return name;
}
public int getPosition()
{
return position;
}
public void setPosition(int n)
{
position = n;
}
public void setName(String n){
this.name=n;
}
}
the child class
public class Spartiates extends Racer{
private int energy;
public Spartiates(){
super();
}
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
public void setEnergy(int energy){
this.energy=energy;
}
public int getEnergy(){
return energy;
}
}
main class
public class demo{
public static void main(String[] args){
Racer [] player = new player[3];
for(int i=0; i<player.length; i++){
player[i] = new Spartiates();
}
System.out.println(player[1].getEnergy());
}
so here the problem the getEnergy method doesn't work so I was wondering why. If anybody can help it would be very much appreciated. thanks
This is discussed here:
Is it possible to call subclasses' methods on a superclass object?
Along with all the reasons why doing something like this is probably never a good idea :).
You'll have to cast it to an instance of the subclass. If you plan on having a mixed array of object instances you'd need to first check the type:
System.out.println(((Racer)player[1]).getEnergy());
You need either define the function in the superclass or cast the object to the subclass.
If you intend the array to hold ONLY elements of the subclass Spartiates, then declare it as such.
Otherwise, if it needs to hold objects of both type, there only way to do this is to check with instanceof.
if (player[1] instanceof Spartiates)
System.out.println(((Spartiates)player[1]).getEnergy());
else
// handle other types
The reason energy is 0 is because you are calling your empty (no arg) constructor:
player[i] = new Spartiates();
which does not initialize the energy variable (so it will be 0 by default). You only set the variable to 100 in the constructor which takes in a String, namely here:
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
So either call that constructor in the for loop with some string as an argument, or call your setEnergy() setter with some value after creating the object with the empty constructor.
Also, this is wrong:
Racer [] player = new player[3];
It should read:
Racer [] player = new Racer[3];
or:
Racer [] player = new Spartiates[3];
Related
I have a parent class named Set representing a set of a tennis matches.
public class Set {
private String set1;
private String set2;
private String set3;
//private Object[] match;
public Set() {
setSet1(set1);
setSet2(set2);
setSet3(set3);
}
public void setSet1(String set1) {
this.set1 = set1;
}
public String getSet1() {
return set1;
}
public void setSet2(String set2) {
this.set2 = set2;
}
public String getSet2() {
return set2;
}
public void setSet3(String set3) {
this.set3 = set3;
}
public String getSet3() {
return set3;
}
public String toString(){
return String.format("set1: %s, set2: %s, set3: %s", set1, set2, set3);
}
}
and a sub class of Set named SingleSet where I try to add the sets into an array named `game.
public class SingleSet extends Set{
private Object homePlayer;
private Object awayPlayer;
private String[] game;
public SingleSet(Object homePlayer, Object awayPlayer){
super();
game = new String[3];
game[0] = super.getSet1();
game[1] = super.getSet2();
game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
public void setHomePlayer(Object homePlayer) {
this.homePlayer = homePlayer;
}
public Object getHomePlayer() {
return homePlayer;
}
public void setAwayPlayer(Object awayPlayer) {
this.awayPlayer = awayPlayer;
}
public Object getAwayPlayer() {
return awayPlayer;
}
public void setGame(String[] game) {
this.game = game;
}
public String[] getGame() {
return game;
}
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
}
This is where I am trying to add the Sets from my parents class into my sub class (this is for FXML, so the code is in my controller):
public void submit() {
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
System.out.println(game1);
}
When I print the result, my array values are null. I tried printing them individually and that worked fine, so I know the set1Box.getText() is working fine.
The reason you are seeing null values when you print is because they are actually null.
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue()); is creating a new SingleSet, which extends Set.
SingleSet constructor makes a super() call to Set constructor.
When Set is created for the first time, all its values are null. Then constructor kicks in, but Set constructor actually does nothing, so Set's instance variables remain null.
Ten SingleSet carries on on building your object with parameter given, which do nothing for setting a value for set1, set2, set3.
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
They actually set a value to set1, set2, set3 (since you are saying that set1Box1.getText() and others are working). So why you are still seeing null when printing?
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
That's why: you are printing game[0], and so on, that are actually null because when you set your game array, those values where null!
public SingleSet(Object homePlayer, Object awayPlayer){
super(); //setting null values to set1, set2, set3
game = new String[3];
game[0] = super.getSet1(); //this returns null!
game[1] = super.getSet2(); //this returns null!
game[2] = super.getSet3(); //this returns null!
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
Print some values when you build your object and will see :)
To solve, one way is to use a parametrized constructor public Set(String set1, String set2, String set3), use a parametrized child constructor public SingleSet(String set1, String set2, String set3, Object homePlayer, Object awayPlayer) and a parametrized call to super, super(set1, set2, set3)
Then you should set values when creating game1
SingleSet game1 = new SingleSet(set1Box1.getText(), set1Box1.getText(), set1Box1.getText()homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
You are not setting anything in Set's default constructor
Should really find a better name for your class as "Set" is confusing with collections Set.
Make use of immutable for both of your classes to save yourself from trouble - remove all the setters and initialize in constructor.
I'm not that good at tennis scoring rules, but to my best knowledge a "set" has number of "games", and "match" consists from a number of sets. What is the logic for this relation "Set <- SingleSet"? What if you change your hierarchy in this way (in pseudo-code, will skip most method bodies for brevity):
class Player{
private String name;
public Player(String name);
}
class Match{
private Player homePlayer;
private Player awayPlayer;
private List<Set> sets;
public Match(Player homePlayer, Public awayPlayer);
public List<Set> getSets(){
if(sets == null){
sets = new ArrayList<>();
}
return sets;
}
}
class Set{
public Set(Game... games);
}
class Game{
// game score details
public Game(int scoreHomePlayer, int scoreAwayPlayer);
}
So that in your Controller, you could use it like this:
Match match = new Match(new Player("Williams"), new Player("Johnson"))
match.getSets().add(new Set(
new Game(6, 1),
new Game(4, 6),
new Game(7, 0)
// etc.
))
You could further refactor #4 hierarchy and spare all these "new ()" constructor calls using Builder Pattern, something along the line:
Match match = new MatchBuilder("Williams","Johnson").addSet()
.addGame(6,1).addGame(4,6).addGame(7,0)
.build()
you should override set method .Instead of in the set after the constructor is instantiated
public SingleSet(Object homePlayer, Object awayPlayer) {
super();
game = new String[3];
// game[0] = super.getSet1();
// game[1] = super.getSet2();
// game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
#Override
public void setSet1(String set1) {
this.game[0]=set1;
super.setSet1(set1);
}
#Override
public void setSet2(String set2) {
this.game[1]=set2;
super.setSet2(set2);
}
#Override
public void setSet3(String set3) {
this.game[2]=set3;
super.setSet3(set3);
}
So I want to use a method to write multiple objects to respective files. However I do not know how to import the array of Objects without defining the specific Object.
The people is class is purely for storing the created objects in arrays so it is easier to access across other classes.
For example
public class People {
private Student[10];
private Teacher[10];
public void setStudentArray(Student, index) {
Student[index] = Student;
}
public void setTeacherArray(Teacher, index) {
Teacher[index] = Teacher;
}
}
public class Student extends People {
String name;
int StudentID;
public String getName() {
return name;
}
}
public class Teacher extends People {
String name ;
int Teacher ID;
public String getName() {
return name;
}
}
public class Main {
People p = new People();
public void main (String[] args) {
Student s = new Student("default-name" , 1);
p.setStudentArray(s, 0);
Teacher t = new Teacher("default-name", 1);
p.setTeacherArray(t, 0);
outputName(p.getStudentArray, 0);
outputName(p.getTeacherArray, 0)
}
//THIS IS WHERE I AM STRUGGLING I dont know how to pass teachers or students array to it.
//I want the Object[] parameter to accept both Student[] and Teacher[]
public void outputName(Object[], index) {
System.out.println(Object[index].getName);
}
}
I think that my Method taking an Object[] is wrong but I do not know how to approach it otherwise. I believe the issue is that Object[] is an entirely different class to Teacher[] and Student[] and this is where I am going wrong.
I want to use the .getName method in both the classes of Teacher and Student in order to print the name of the Teacher of Student. (Merely so I can see the passing is working.)
If this is just not possible I guess I will just not try a method that can take different objects.
I know that I can just use two methods one for students and one for teachers but I want the method to work for multiple objects so that I can add more object arrays to it.
So People class is extended by both Student and Teacher.
What commonalities are here?
String name is present in both Student and Teacher
public String getName() is also present in both Student and Teacher
You can move these commonalities to People class. Also ensure to remove the name attribute and getName from Student and Teacher class
So your People updated class can be:
public class People {
private String name; //Newly added
private Student[10]; //This ideally shouldn't be in People class rather a different class
private Teacher[10]; //This ideally shouldn't be in People class rather a different class
public void setStudentArray(Student, index) {
Student[index] = Student;
}
public void setTeacherArray(Teacher, index) {
Teacher[index] = Teacher;
}
public String getName() {
return name;
}
public void setName() {
this.name = name;
}
}
The outputname method should be like:
public void outputName(People[] people, index) {
System.out.println(people[index].getName());
}
NOTE: I am not correcting the syntax here, but just giving an idea.
What #Li357 said is right... You have to change your modeling a bit. Even if you managed to pass Student[] as an Object[], you wouldn’t be able to call the getName method as it’s not an Object method.
So a better modeling would be to make the getName method a People method, and both Student and Teacher classes would inherit it.
Then you could receive People[] as the outputName method argument, and use the getName method inside.
First of all learn how to declare array and choose valid variables.
In your People class do following modifications.
public class People {
//Declare arrays like this.
private Student[] student;
private Teacher[] teacher;
//Initialize arrays
public People(){
student = new Student[10];
teacher = new Teacher[10];
}
public void setStudentArray(Student s,int index) {
student[index] = s;
}
public void setTeacherArray(Teacher t, int index) {
teacher[index] = t;
}
//Add getter methods
public Student[] getStudentArray(){
return student;
}
public Teacher[] getTeacherArray(){
return teacher;
}
}
Inside sub classes Student and Teacher add Argument constructor
Finally in your outputName method you can do something like this.
public static void outputName(Object[] obj, int index) {
if(obj instanceof Student[]){
Student[] s = (Student[])obj;//parsing to student array
System.out.println("Student name : "+s[index].getName());
}
if(obj instanceof Teacher[]){
Teacher[] teacher = (Teacher[])obj;//parsing to teacher array
System.out.println("Teacher name : "+teacher[index].getName());
}
}
Output:
Student name : default-name
Teacher name : default-name
I need help creating a setter method for my code. I have created two setter methods for both of my string values, but I am A) not sure if they are implemented correct, and B) not sure how to call them so that they appear on the screen. Essentially I would like to be able to just call my lion and hippo classes and have them already have a name and a size, and not have to implement them inside my main function directly by inserting something like
Hippo h = new Hippo("Tom", "42")
package game2;
public class Game2 {
public static void main(String[] args) {
//I am getting the error here, what I want to do is figure out how to
//get this to work and then declare a name and size for the animal
Hippo h = new Hippo();
Lion l = new Lion();
}
}
package game2;
public abstract class Animal {
private String name;
private String Size;
public String getName() {
return name;
}
public String getSize() {
return Size;
}
public void setName(String name) {
name = "Tom";
}
public void setSize(String name) {
name = "42";
}
public Animal(String theName, String theSize) {
name = theName;
Size = theSize;
}
}
package game2;
public class Hippo extends Animal {
public Hippo(String name, String Size) {
super(name, Size);
}
}
package game2;
public class Lion extends Animal{
public Lion(String name, String Size) {
super(name, Size);
}
}
Remember when implement constructor by your own, you are overload the default constructor. So you need to pass two arguments.
You didnot pass the arguments for constructors when you instantiate:
Hippo h = new Hippo();
Lion l = new Lion();
Because your class constructors expect two parameters.
public Hippo(String name, String Size) {
super(name, Size);
}
And:
public Lion(String name, String Size) {
super(name, Size);
}
Solutions:
Either you can pass arguments when you instantiating objects:
Hippo h = new Hippo("name", "33");
Lion l = new Lion("name", "22");
Or you need to implement overloaded constructors for these.
Read this to learn more about constructor overloading.
your code is not compiling because you are not using the right constructor,
Both Hippo's and Lion's constructors expect two string arguments so you have to do something like:
Hippo h = new Hippo("myHippo", "220");
Lion l = new Lion("Simba", "400");
new Hippo()/Lion() is calling a function you don't have (empty constructor)
You have function Hippo(String name, String Size) which need 2 parameters
try new Hippo("Billy", "10")
Both Hippo's and Lion's constructors expect two string arguments - the name and the size. You need to pass them when you call the respective constructors. E.g.:
Hippo h = new Hippo("Happy", "Huge");
Lion l = new Lion("Leo", "Big");
If you want to decide the name and size after you have created your animal, you need a parameterless constructor. Currently all the constructors require you to pass 2 arguments. So write one!
Here is an example:
public Hippo() {
setSize(insert default size here);
setName(insert default name here);
}
Then, you can create a hippo like this:
Hippo hippo = new Hippo();
hippo.setName("Tom");
I don't know is it possible or worst idea ever lol;
however i'm trying to write constructor for my model class which uses String array and automatically bind parameters from it :)
Thank you for wasting your gold time on my poor question :D
here is example:
edited: code and my point is, i create object of this class just giving String[] to constructor .... :(
//Like ---->>>>
public class MemberEducation{
String name;
String surname;
String address;
//empty constructor
public MemberEducation(){
}
//it's for parameters
public MemberEducation(String[] a){
int i=0;
for(String val:a){
my_parameters[i]=a;// my parameters mean surname, name, and address
i++;
}
}
// it's my solution now i'm using, create new object with empty constructor
then set all parameter with String array
public void setAll(String[] a){
this.surname=a[0];
this.name=a[1];
this.address=a[2];
}
Problem
You were assigning String Array where it is expecting a String,Thats where it went wrong.I think you are looking for this
Solution
public class MemberEducation{
String[] arr = new String[10];// just taking size 10 for test
public MemberEducation(String[] a) {
int i = 0;
for (String val : a) {
arr[i++] = val;// arr is an string array
}
}
public static void main(String args[]) {
new MemberEducation(args);
}
}
If we create a String like below and print the value:
String s=new String("demo");
System.out.println(s);
...the output is:
demo
Good. This is the expected output. But here String is a class. Remember that. Below is another example. For example, take a class like this:
class A
{
public static void main (String args[])
{
A a =new A();
A a1=new A("hi"); //we should create a Constructor like A(String name)
System.out.println(a1); //here O/P is address
}
}
My doubt is that I created the A instance in the same way I created the new String object, and I printed that object. So why does it not print the given String for the instance of A?
You need to override the Object#toString() in your class. By default, the toString() method of Object is called.
Also, to print the value, you just need to override the method as internally a call will be made to the toString() method when this statement is executed.
System.out.println(a1);
Sample overriden toString() method.
#Override
public String toString() {
// return a string value
return "The String representation of your class, as per your needs";
}
You have to override toString() method in your class the way you want to print something when call System.out.println();. In String class toString() method has override and you will get out put above due to that.
As pointed out already, you need to override the default toString() method inherited from the Object class. Every class automatically extends the Object class, which has a rather simple toString(), which can't know how to turn your particular object into a String. Why should it, especially if your class is arbitrarily complex? How is it supposed to know how to turn all your class's fields into a "sensible" string representation?
In the toString() of your class, you need to return the string that you want to represent your class with. Here is a simple example:
class A {
String foo;
public A(String foo) {
this.foo = foo;
}
public String toString() {
return foo;
}
}
public class sample {
public static void main(String[] args) {
A a = new A("Hello world!");
System.out.println(a);
}
}
String is a class whose purpose is to hold a string value and will return that value if referenced. When you use other classes, you will usually want to add other behavior. If you want to use the class to hold different values that you can set (on object creation or later in processing) you may want to use "setter" and "getter" methods for such values.
Here is an example:
public class Snippet {
private static final String C_DEFAULT_VALUE = "<default value>";
private String name;
private static Snippet mySnippet;
public Snippet() {
}
public Snippet(String value) {
setName(value);
}
/**
* #param args
*/
public static void main(String[] args) {
if (args != null && args.length > 0) {
mySnippet = new Snippet(args[0]);
} else {
mySnippet = new Snippet(C_DEFAULT_VALUE);
}
System.out.println(mySnippet.getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}