Accessing composed objects in Java - java

New to Java.
I have an instance player1 of the Player class below.
Player player1 = new Player(0,0);
Inside the Player class I have composed an object coordinate of type Coord (defined below). When I instantiate player1 above "Player is at coordinate 0,0" is displayed as expected.
public class Player extends Entity {
public Coord coordinate;
public Player(int x, int y) {
Coord coordinate = new Coord(x,y);
System.out.println(“Player is at coordinate “ + coordinate.getX() + “,”
+ coordinate.getY());
}
}
The Coord class is defined as follows.
public class Coord {
private int x;
private int y;
public Coord(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
The problem arises when I try to access obj and its respective methods after I instantiate player1. When I try to access coordinate I get a NullPointerException error.
Player player1 = new Player(0,0);
System.out.println(“Player is at coordinate “ + player1.coordinate.getX() +
“,” + player1.coordinate.getY());
What am I doing wrong?

You aren't making Coord obj; a field of your class. That could be as simple as something like
public class Player extends Entity {
Coord obj;
public Player(int x, int y) {
obj = new Coord(x,y);
System.out.println(“Player is at coordinate “ + obj.getX() + “,”
+ obj.getY());
}
}
Note that obj is a terrible field name, and that it has default level access permission here. One way to improve that might be something like
public class Player extends Entity {
private Coord coordinates;
public Player(int x, int y) {
coordinates = new Coord(x,y);
System.out.println(“Player is at coordinate “ + obj.getX() + “,”
+ obj.getY());
}
public Coord getCoordinates() {
return coordinates;
}
}
Then you could use it like
Player player1 = new Player(0,0);
System.out.println(“Player is at coordinate “
+ player1.getCoordinates().getX()
+ “,” + player1.getCoordinates().getY());
You might also override toString() in the Coord class, then you could say
System.out.println(“Player is at coordinate “
+ player1.getCoordinates());

Related

Adding methods to arrays of custom objects

I'm trying to add a method an an array like this.
Position[] positions = new Position[10];
Position pos = positions.getPosAt(x, y);
I know this can be accomplished like:
Position pos = getPosAt(positions, x, y)
But I would like to know if there is a way to accomplish the first method.
you can make a class handler for this, like this PositionArray class (name it as you would like):
public class Test {
public static void main(String... args) {
Position[] positions = new Position[10];
positions[0] = new Position(5, 10);
positions[1] = new Position(11, 18);
positions[2] = new Position(20, 7);
PositionArray pa = new PositionArray(positions);
System.out.println(pa.getPosAt(5, 10)); // Position{x=5, y=10}
}
}
class PositionArray {
private Position[] positions;
public PositionArray(Position[] positions) {
this.positions = positions;
}
public Position getPosAt(int x, int y) {
for (Position p : positions) {
if (!Objects.isNull(p)) {
System.out.println(p.getX() + " " + p.getY());
if (p.getX() == x && p.getY() == y) {
return p;
}
}
}
return null;
}
}
class Position {
private final int x;
private final int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public String toString() {
return "Position{" + "x=" + x + ", y=" + y + '}';
}
}
There is no way to do this in Java. You could possibly create your own class that contained an array of Position objects and provides e.g. get methods, but there is no way whatsoever to add methods to classes you do not control, including all array types.

Circle class multiple constructors

I am trying modify the class Circle to include a third constructor for constructing a Circle instance with two arguments - a double for radius and a String for color. Also Modify the main class to construct an instance of Circle using this constructor. I am having trouble with this, i keep getting the message that constructor Circle is never used. Please have a look at the code.
public class Circle {
private double radius;
private String color;
public Circle() {
radius = 1.0;
color = "red";
}
public Circle(double r) {
radius = r;
color = "Blue";
}
public Circle(double r, String c) {
radius = r;
color =c;
}
public double getRadius() {
return radius;
}
public void setRadius(double newRadius) {
radius = newRadius;
}
public String getColor()
{
return color;
}
public void setColor(String newColor) {
color=newColor;
}
public double getArea() {
return radius*radius*Math.PI;
}
}
public class Main {
public static void main(String[] args) {
Circle c1 = new Circle();
System.out.println("The circle has radius of " + c1.getRadius());
System.out.println("and area of " + c1.getArea());
Circle c2 = new Circle(2.5);
System.out.println("The circle has radius of " + c2.getRadius());
System.out.println("and area of " + c2.getArea());
Circle c3 = new Circle(0.5);
c3.setColor("Green");
System.out.println("The circle has radius of "
+ c3.getRadius());
System.out.println("and area of " + c3.getArea());
System.out.println("color is: " + c3.getColor());
Circle c5 = new Circle();
c5.setRadius(500.0);
System.out.println("radius is: " + c5.getRadius());
c5.setColor("Yellow");
System.out.println("color is: " + c5.getColor());
}
}
Well, you aren't using it, so the message should hardly be a surprise. Just stick in a call to the two-argument constructor somewhere (e.g., Circle c3 = new Circle(0.5, "Green");), and the message should go away. Of course, if you change all the instance creations to the two-argument constructor, you'll then get the warning for the zero- and one-argument versions.
Alternatively, you can change your constructor definitions:
public class Circle {
public Circle() {
this(1.0, "red");
}
public Circle(double r) {
this(r, "Blue");
}
public Circle(double r, String c) {
radius = r;
color = c;
}
...
}
I have to say, though, that it's weird to have the default value for the color be "red" when you use a default radius and "Blue" when you specify a radius. I would recommend against that, in which case I'd change the first constructor to:
public Circle() {
this(1.0);
}
You might also want to look at using an enum for your colors, to avoid problems with case differences (like "red" vs. "Red"). You can always convert between an enum value and a String using the built-in enum methods name() and valueOf(String).

Java inheritance how to take user input and pass it to sub-sub class?

This is my first ever post here so bear with me please! I have a program that I need to write. Here are the instructions: create a class called areaExcersice in that class you will have a super class called shapes then below it twoDimensionalShapes followed by sub sub class circle and square under the twoDimensionalShapes. In circle extends twoDimensionalShapes, I will pass the user input of radius for example:
System.out.print("what is the radius");
and then
radius = input.nextDouble()
already know how to create and assign classes in a hierarchy system, however, I have no idea how I'm gonna call my circle class under the twiDimensionalShapes. I have to create an if statement so the user can select which shape to choose so something like this "press 1 for circle or 2 for square" and on my
if(user_input == 1){
Here is my question how would I call circle class under twodDimensionalShapes to find the area and pass on radius? Thanks this is all i need to know please if you can just point me out in the good direction i already have created an instance for ex
Circle c = new Circle
Then in my if statement i would do c.getArea() but then where would I put my radius that is asked from the user?
One of my pet peeves with these kinds of projects is they explicitly ask you to create classes when there is no need for them. This only confuses students who can't figure out why they're doing something because there really isn't a reason to do it. You've given no reason to have a Shape class. In the real world I'd take that as an excuse to get rid of it. Since you're required to have one I'm inventing a reason for it to exist: color. This way you can see what Shape might be useful for. If you say "I don't need color" I say "you don't need Shape". See how that works?
I'm using a dirty little trick here called static inner classes so this all works in one file. If you copy this at least take the static of the classes and move them into their own files.
import java.util.Scanner;
public class AreaExcersice {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Choose 1 for circle or 2 for square:");
int userInput = Integer.parseInt( input.nextLine() );
TwoDimensionalShape twoDShape = null;
if (userInput == 1) {
System.out.println("Enter a radius for circle:");
int radius = Integer.parseInt( input.nextLine() );
twoDShape = new Circle("Blue", radius, radius, radius);
} else if (userInput == 2) {
System.out.println("Enter a length for the sides of the square");
int side = Integer.parseInt( input.nextLine() );
twoDShape = new Rectange("Green", 0, 0, side, side);
} else {
System.out.println("Invalid input.");
}
if (twoDShape != null) {
System.out.println( twoDShape.toString() );
}
}
public static abstract class Shape {
String color;
public Shape(String color) {
this.color = color;
}
public abstract String toString();
}
public static abstract class TwoDimensionalShape extends Shape {
int x;
int y;
public TwoDimensionalShape(String color, int x, int y) {
super(color);
this.x = x;
this.y = y;
}
public abstract double getArea();
}
public static class Circle extends TwoDimensionalShape {
int radius;
public Circle(String color, int x, int y, int radius) {
super(color, x, y);
this.radius = radius;
}
#Override
public double getArea() {
return Math.PI * Math.pow(radius, 2);
}
#Override
public String toString() {
return color + " circle at " + x + ", " + y + " with radius " +
radius + " and area of " + getArea();
}
}
public static class Rectange extends TwoDimensionalShape {
int height;
int width;
public Rectange(String color, int x, int y, int height, int width) {
super(color, x, y);
this.height = height;
this.width = width;
}
#Override
public double getArea() {
return width * height;
}
#Override
public String toString() {
return color + " rectange at " + x + ", " + y + " with height " +
height + ", width " + width + " and area of " + getArea();
}
}
}
Displays:
Choose 1 for circle or 2 for square:
1
Enter a radius for circle:
20
Blue circle at 20, 20 with radius 20 and area of 1256.6370614359173
This maybe overkill but it should be clearly showing you what an inheritance structure can do for you. Each class only has implementation code particular to it. Nothing is duplicated. Instead it's shared. Any questions?
You could move anything that's common amongst all of your Shape or TwoDimensionalShape subclasses so that they can be referenced generically:
public abstract class Shape<T extends TwoDimensionalShape> {
public abstract String getName(); // Get the name of the shape for display purposes
public abstract double getArea(); // Get the surface area of this Shape
}
public abstract class TwoDimensionalShape<T extends TwoDimensionalShape> extends Shape<T> {
private double area = 0;
public double getArea() {
return this.area;
}
protected void setArea(double area) {
this.area = area;
}
}
public class Circle extends TwoDimensionalShape<Circle> {
public Circle ( double radius ) {
setArea( Math.PI * Math.pow(radius, 2) );
}
public String getName() {
return "Circle";
}
}
public class Square extends TwoDimensionalShape<Square> {
public Square ( double width, double height ) {
setArea( width * height );
}
public String getName() {
return "Square";
}
}
So the point of having TwoDimensionalShapes is a bit obscure, but we can guess that it defines methods like "getArea()" without implementing them. Each class that extends TwoDimensionalShapes has to implement its own area calculation.
I don't think things like "setArea(double area)" are very useful; areas are not so difficult to calculate that we need to store them, and storing them causes other problems.
So we end up with something like these:
public TwoDShape extends Shape // I have no use for Shape in this example...
{
public double getArea(); // this is an abstract method, hope you've covered those.
}
public Circle extends TwoDShape
{
private double radius;
public Cirlcle(double givenRadius) { radius = givenRadius; }
public double getArea() { return PI*radius*radius; }
}
I've left out a great deal. The getArea() should insure the radius is not 0 and do something like throw an exception if it is, for instance.
Now, to use this, you might have:
public class Main
{
public static void main(String ... arguments)
{
Circle c = new Circle(4.0);
System.out.println("Radius of 4 gives area of " + c.getArea();
}
}
Now, I'll leave Square to you to do, it will be quite similar to Circle. Let us know how it goes. After you've done Square, you'll be able to do something like:
public Main
{
public static void main(String ... arguments)
{
Shape[] shapes = new Shape[3];
shapes[0] = new Circle(4.0);
shapes[1] = new Square(5.0);
shapes[2] = new Square(6.0);
for (shape : shapes)
{
System.out.println("Area is " + shape.getArea());
}
}
}
Thanks guys! You guys are all awesome!! I have not yet covered abstract classes but your explicit code showed me the way! Something clicked on me and alas! i saw the light beaming across the room! I idolize you programmers as well as admire you because someday i will become a professional just like you guys. I am striving to achieve deep knowledge within the programming field and this is just the start. Again thank you so much for clearing my head and pointing me in the right direction! It feels so good to complete a program on your own and have it output correctly and thanks Stack Overflow and all its respective members!I am a noob and first time posting here so i might get down voted for answering in an incorrect format.

How to return an superclass object in a subclass's instance method?

The following is a toy problem of my original problem. Bird is an interface. Cardinal is the subclass of Point and it implements the Bird interface. The Aviary class carries out the implementation.
Question: What should I put in the getPosition() instance method such that the Aviary class carries the getPosition() method correctly?
Please correct me if the abstract method in the bird interface is coded wrong.
public interface Bird{
public Point getPosition();
}
public class Point{
private int x;
private int y;
// Constructs a new Point at the given initial x/y position.
public Point(int x, int y){
this.x = x;
this.y = y;
}
// Returns the x-coordinate of this point
public int getX(){
return x;
}
// Returns the y-coordinate of this Point
public int getY(){
return y;
}
}
Question is in the following code:
public class Cardinal extends Point implements Bird{
// Constructors
public Cardinal(int x , int y){
this(x,y);
}
// not sure how to write this instance method
public Point getPosition(){
???????????
}
}
public class Aviary{
public static void main(String[] args){
Bird bird1 = new Cardinal(3,8);
Point pos = bird1.getPosition();
System.out.println("X: " + pos.getX() + ", Y: " + pos.getY() );
}
}
Just return the object itself:
public Point getPosition(){
return this; // returns a Point object
}
I gave an answer, but I am not sure if you have a design nightmare or a one-of-a-kind design simplification. A Point subclass implementing a Bird makes me bang my head on the wall, but having both types in one object will make the calculations pretty neat, (if you have massive calculations, that is). Because instead of bird.getPosition().getX(), you can write bird.getX().
Point bird1 = new Cardinal(3, 8);
Point bird2 = new Cardinal(4, 12);
// calculate the distance between two birds
double distance = Math.sqrt(Math.pow(bird2.getX() - bird1.getX(), 2) + Math.pow(bird2.getY() - bird2.getY(), 2));
But if your system is not a bird simulator that needs heavy calculations on birds represented by mere Point objects, I think you should use composition over inheritance.
public interface IBird {
public Point getPosition()
}
class Bird implements IBird {
private Point position;
public Bird(int x, int y) {
this.position = new Point(x, y);
}
public Point getPosition() {
return this.position;
}
}
// and then in main()
Bird bird = new Bird(3, 8);
Point pos = bird.getPosition();
System.out.println("X: " + pos.getX() + ", Y: " + pos.getY() );
The Cardinal class objects have an is-a relationship with the Point class objects, so you could just return this; as Krumia suggested.
P.S. you can use the super keyword when referring to a superclass within a subclass to access it's protected and public methods.

Java - trying to initialise an object with parameters passed in another constructor, in another class?

Very basic java knowledge at the moment, in need of some assistance in trying to create a game of Pacman.
Currently I have three classes, the player class, the dot class and the game class, all interacting to create a basic game of Pacman.
The issue I am having is this:
I need the 'initialX and initialY fields as show below (these will be user inputted coordinates);
public class Player
{
private int x, y, collectedDots;
public Player(int initialX, int initialY)
{
x = initialX;
y = initialY;
collectedDots = 0;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
to pass through as my parameters within the new 'player' object within the Game Class.
public class Game
{
public Game()
{
Player player = new Player();
Dot dot1 = new Dot();
Dot dot2 = new Dot();
Dot dot3 = new Dot();
}
}
It has me stumped, and I'm assuming I've either gone about this the wrong way, or I'm completely missing something.
Your declared constructor take two int parameters, and you call it with out sending any parameters.
When use the below line, the compiler will look for a default constructor that takes no parameters, but it will fail since you haven't declared a default one, but you declared a constructor with two int parameters.
Player player = new Player();
With this line:
Player player = new Player(1, 2);// pass two int parameters t your defined constructor.
You can have variables defined in your Player class and then assign those variables to other variables in the constructor of the same class like so:
public class Player
{
private int x, y, collectedDots;
int initialX = 15;
int initialY = 20;
public Player()
{
x = initialX;
y = initialY;
collectedDots = 0;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
Now your x is equal to 15 and y is equal to 20. But these values are all part of the Player class. However, you create an object of the Player class in the Game class and through that object you can access x and y like so:
public class Game
{
public Game()
{
Player player = new Player();
System.out.println(player.getX()); // prints out 15 in the console
System.out.println(player.getY()); // prints out 20 in the console
Dot dot1 = new Dot();
Dot dot2 = new Dot();
Dot dot3 = new Dot();
}
}
You can of course do whatever you want with these values (like assign them to new variables in the Game class and manipulate them there). I am just printing them out so you can see that its the values from the Player class.
UPDATE
You can take user input before you create the Player object and then pass those values to the constructor of the Player class like so:
public class Game
{
public Game()
{
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
int j = sc.nextInt();
Player player = new Player(i,j);
System.out.println(player.getX()); // prints out 15 in the console
System.out.println(player.getY()); // prints out 20 in the console
Dot dot1 = new Dot();
Dot dot2 = new Dot();
Dot dot3 = new Dot();
}
}
This is, of course, provided you keep your Player class how you posted it originally. But if you want to continue being able to change the values of x and y you can always provide Setter methods. Your class will then become:
public class Player
{
private int x, y, collectedDots;
public Player(int initialX, int initialY)
{
x = initialX;
y = initialY;
collectedDots = 0;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void setX(int newX)
{
x = newX;
}
public void setY(int newY)
{
y = newY;
}
}
Whenever you want to then change the values of x and y from the Game class then you'd just have to do the following (just an example):
public class Game
{
public Game()
{
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
int j = sc.nextInt();
Player player = new Player(i,j);
player.setX(35);
player.setY(48);
}
}
Again, this is just an example. I wouldn't really be doing all of this in the constructor but just using this to explain how you can do what you want.

Categories

Resources