How do I design my geometric figures class hierarchy? - java

Main purpose of this task is to calculate volumes and surface areas of three dimensional geometric shapes
like, cylinders, cones.
In Java Language
Design your classes as below introducing:
an Interface named “GeometricShapes”
an abstract class named “ThreeDShapes”
two child classes of ThreeDShapes: Cylinders and Cones.
One test class names “TestShapes”
Get the output for volumes and surface areas of cylinders and cones along with respective values of
their appropriate input variables. Try to use toString() method and array. Your classes should be
designed with methods that are required for Object-Oriented programming.
So Far I Have:
package Assignment2;
public interface GeometricShapes {
public void render();
public int[] getPosition();
public void setPosition(int x, int y);
}
package Assignment2;
public abstract class ThreeDShapes implements GeometricShapes
{
public int[] position;
public int[] size;
public ThreeDShapes()
{
}
public int[] getPosition()
{
return position;
}
public void setPosition(int x, int y)
{
position[0] = x;
position[1] = y;
}
}
package Assignment2;
public class Cylinders extends ThreeDShapes
{
public Cylinder()
{
}
public void render()
{
}
}
I don't think this is right and I do not know how to fix it. :( Please help.

Most of the problem solving task is to understanding what is asked from you. Teacher wants to make you show that you know how interfaces, abstract classes and classes are connected, and how do thy contribute to the whole object instance.
There are few things that are assumed from you, but you would just be better of rereading notes provided for you - assuming, that you did not pay attention in the class. My experience shows, that struggling student do need a bit more then just advice to get going - if you need help, find a person who is ace'ing the class and just ask assistance.
But for now, to get you going, this is what part of the assignement could look like
package Assignment2;
import java.util.Arrays;
public class task {
public static interface GeometricShapes {
public double getArea();
public double getVolume();
}
public static abstract class ThreeDShapes implements GeometricShapes {
protected double a, h;
}
public static class Cones extends ThreeDShapes {
#Override public double getArea() {
return Math.PI * this.a * Math.sqrt(a * a + h * h);
}
#Override public double getVolume() {
return (1d / 3d) * Math.PI * Math.pow(a, 2) * a * h;
}
#Override public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Cone [a=").append(a).append("; ").append("h=")
.append(h).append(" ( area=").append(this.getArea())
.append("; volume=").append(this.getVolume()).append(" )]");
return builder.toString();
}
}
public static void main(String[] args) {
System.out.println(Arrays.toString(new ThreeDShapes[] {
new Cones() {{ a = 3; h = 4;}},
new Cones() {{ a = 4; h = 5;}}
}));
}
}
Output:
[
Cone [a=3.0; h=4.0 ( area=39.98594644342529; volume=113.09733552923255 )],
Cone [a=4.0; h=5.0 ( area=71.08612701053386; volume=335.1032163829112 )]
]

Hint #1 - the reqs say this: "Get the output for volumes and surface areas of cylinders and cones ...". So obviously you need API methods to calculate the volume and surface area of a shape, and you need test code to construct sample 3D shapes, and call the methods that calculate the volume.
Hint #2 - the reqs say this: "try to use toString() method". So obviously, you need to implement toString() on your classes.
Hint #3 - the reqs do not talk about rendering shapes, and you don't need the location of a shape to calculate its volume.

So, lets look at you error messages, they are quite clear saying what is wrong.
task.java:25: task.Cones is not abstract and does not override abstract method getVolumeCylinder() in task.GeometricShapes
public static class Cones extends ThreeDShapes
^
task.java:58: task.Cylinder is not abstract and does not override abstract method getVolumeCylinder() in task.GeometricShapes
public static class Cylinder extends ThreeDShapes
^
So, your interface GeometricShapes defines a method getVolumeCylinder(). (Why?)
This means, every (non-abstract) class implementing this interface needs to have this method, too (if not some superclass is already implementing this).
Why did you put these methods in the Interface? What does your GeometricShapes interface represent? A collection of shapes? A single shape (then the name should be in singular, not plural)?
Think about this first, then you'll get the answer about which methods are useful here, and how to structure your subclasses.
task.java:64: cannot find symbol
symbol : variable cylinderBase
location: class task.Cylinder
return cylinderBase * cylinderHeight;
^
This error message (and all the following ones) mention variables that are not declared anywhere. Think about where you are using these variables, and of what object they would be properties. Then declare them in this object, and organize giving the right values to them.
task.java:126: cannot find symbol
symbol : class Cylinders
location: class task
new Cylinders()
^
This last message complains because you are trying to create an object of class Cylinders, and there is no such class. (You have a class named Cylinder, though.)

Related

Access methods on different types

I have something like this:
Figures fig = new Line();
on which Line extends Figure. Figure is an abstract class that only has a method getType() that tells me which figure it is by returning a String;
I have 3 types, Rectangle, Circle and Figure. All of them extend Figures.
Now the real question. I store every single one inside of a List<Figures> and I want to get access to some methods on each object like getStartX(); and getStartY(); and I can't, I only can access the methods that are on Figures also.
Your abstract class should define the getStartX and getStartY method. Either abstract if you want Rectangle, Circle and Figure to have a different behaviour and force them to Override those methods. Else just put the method in Figures it'll be available for use (with the appropriate keyword : public/protected depending your needs).
If you want to use methods that are specific to a class you'll need to check of which instance it is. Something like
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof Circle) {
System.out.println("Oh no a Circle!");
int radius = ((Circle)figure).getRadius();
...
}
}
For your Rectangle/Line you can define an interface with your 2 methods:
public interface HasEndpoints {
int getEndX();
int getEndY();
}
public class Rectangle implements HasEndpoints {
...
public int getEndX() {return endx;}
...
}
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof HasEndpoints) { // Rectangle and Line will go there
System.out.println("HasEndpoints implementor");
int endX = ((HasEndpoints)figure).getEndX();
...
}
}
You can use instanceof with if...else and cast dynamically your object
Figure fig = new //Circle()/Triangle()/Rectangle();
if( fig instanceof Circle) {
((Circle) fig).getRadius(); //This method is only available in Circle class
}
You can always cast the Figure to Line, but not the best choice. Depending on the problem, you can apply Visitor Pattern or add those methods to Figure, even when the Circle doesn't have a starting and ending point.
For example
public abstract class Figure{
public abstract void visit(FigureVisitor visitor);
}
public class Line extends Figure{
public void visit(FigureVisitor visitor){
visitor.visitLine(this);
}
}
public interface FigureVisitor{
public void visitLine(Line figure);
public void visitCircle(Circle figure);
}
public class StartingPointsVisitor implements FigureVisitor{
private Double startX;
private Double startY;
private Double endX;
private Double endY;
public void visitLine(Line figure){
this.startX = figure.getStartX(); //No cast needed
...
}
public void visitCircle(Circle figure){
//Stub-method
}
//Getters to read the results
}
Is a more complex solution, but as i said, it depends on the problem, and most of the complex remains in the Visitor
Either getStartX() and getStartY() should be declared in Figure class or you need to cast the object to Line class:
Figure figure = figures.get(0);
if ("line".equals(figure.getType())) {
Line line = (Line)figure;
}
Another option is to use reflection. But you still need to be sure, that the requested method can be called.

Chess Game in Java: Should Square Class Have "Generate Possible Moves" Method?

I'm writing a chess game. My basic design is to have a 2d array (8 x 8) consisting of square objects. Squares have a number of fields: int height, int width, Piece piece (null if empty, some type of Piece object otherwise.
NB: Rook, Knight, Bishop, etc. all extend Piece.
Now, I'm getting a little tripped up on how to figure out what moves are legal for a given piece, given my OOP design. Here's what I'm thinking:
1) User clicks square
2) We determine what piece is on square (if empty, return error message)
3) Generate legal moves for that piece on that square
I'm worried about writing code like:
if (clickedSquare.piece.instanceOf(Rook)) {
return Rook.getLegalDestinationSquares(clickedSquare);
} else if (clickedSquare.piece.instanceOf(Bishop)) {
return Bishop.getLegalDestinationSquares(clickedSquare);
} else if...
Which seems really bad. There must be a way to do this that conforms better to OOP but I'm still learning.
Thanks for the help,
Mariogs
You don't need to create that if statement. Just get the current piece on the field and call some method like (getLegalMoves()) or something.
If field is empty - return empty list of allowed moves.
public abstract class Piece {
public abstract List<Field> getFieldsAllowed(Field field);
}
public class Rook extends Piece {
#Override
public List<Field> getFieldsAllowed(Field field) {
// TODO Auto-generated method stub
return null;
}
}
public class Field {
public Piece getPiece() {
// get current piece
}
}
Something like this. Try to find your own solution. This one is not perfect.
public final class Point {
public final int x, y;
public Point (int x, int y){
this.x = x;
this.y = y;
}
}
public abstract class Piece {
private Point location;
protected Piece (Point initial){
this.location = initial;
}
public Point getLocation(){ return location; }
public Point setLocation(Point location){ this.location = location; }
public abstract List<Point> getLegalMoves ();
}
public final class Rook {
public Rook (Point initial){
super(initial);
}
public List<Point> getLegalMoves (){
// you know the current location, and you know you are a Rook,
// so you have all you need to determine the possible points where
// this Rook can go to
}
}
Then in other code, you can do:
List<Point> legalMoves = clickedSquare.piece.getLegalMoves();
which clearly makes abstraction of what actual piece it is acting upon.
If you do need a static method for other purposes, you can define them in each class such as Rook. Delegate the instance methods to the static methods to avoid code duplication. Like this:
public final class Rook {
// constructor etc.
public List<Point> getLegalMoves (){
return Rook.getLegalMoves (getLocation());
}
public static List<Point> getLegalMoves(Point start){
// you know the location (start), and you know this method is for a Rook,
// so you have all you need to determine the possible end points
}
}
However, if you do not need that static method, don't use and don't even write it (or at least don't expose it in the API of the class). Users of your classes will otherwise start to abuse it end will end up writing code as you provided in your start post - those countless if-elses.
By using this solution, you can add more concrete subclasses (Pawn, King, ...) in the future without touching any existing code (that now acts on Piece), which gives you a maintainability advantage compared to your provided approach.
If Rook, Bishop etc are:
public class Rook extends Piece {
#Override
public String getLegalDestinationSquares() {
// returns all leagal Rook squers
return null;
}
}
and Piece is:
public abstract class Piece {
public abstract String getLegalDestinationSquares();
}
Then you might do it like (in your sample):
return clickedSquare.piece.getLegalDestinationSquares();
Return String is just example, probably you should return Collection of squares.
From OOD there are a few critics.
a field is a field even if no figure is on the field. A null-filed therefore does not exists (LSP)!
a figure do never know what moves he can do, this must be set only by the game rules. Create a new class called Rules. Its the responsibility of the rules to know what moves he can do(SRP). A King (for example) must know if he already did a Castling to decide if he can do a Castling, therefore he must know the previous moves, and this breaks the DIP - ah, here we have another class we miss: ChessNotation.
instanceof is usefull when you inherit things, a Rook can not inherit a field (LSP,DIP).

return value from method without creating an object

Ok so I have a large structure of classes that looks something like THIS
Its for school and my instructor likes Starcraft, so lets just go with it.
Anyway I have a method in the GeneratorBuilding Class that is supposed to be able to instantiate a new Marine Object. However I need to know how many resources a Marine object costs.
I have an abstract int method in the abstract Unit class called unitCost(). Then the Marine class overrides this method and returns a value like 50.
I am looking for a way to have my GeneratorBuilding class get the return value for the unitCost() method in the Marine class without calling any specific Marine object.
I know that I could probably create a marine object and then ask how much it costs and then if I dont have the resources I would delete the object instead of pushing it into an ArrayList. But this seems almost like a workaround.
EDIT: The whole point is to be able to let ALL of my concrete classes inherit and override the UnitCost() method. So I could make it static but that ruins the whole point of an inheritance structure...
EDIT2: Since there was a request for example code (not exactly hard to imagine)
public void makeMarine(){
//uses resources and throws exception etc if there are not enough resources
Game.useResources(Marine.unitCost());
//creates a marine
Game.addMarine();
}
You can do this by declaring a specifically named static field in each class, and getting it through reflection}.
Suppose your classes look like this:
class ClassNumber1 {
public static final int cost = 123;
}
class ClassNumber2 {
public static final int cost = 321;
}
Then you can obtain their cost fields like this:
public static <T> int getCost(Class<T> cl) throws Exception {
// This is oversimplified: you need to check that the class
// indeed has a field called "cost" by null-checking the return value
// of getField(), verifying your cast, catching exceptions, and so on.
// But this will work in a "closed" system, when you know for sure
// that an int constant field does exist:
return (int)cl.getField("cost").get(null);
}
You call the method as follows:
System.out.println(getCost(ClassNumber1.class));
System.out.println(getCost(ClassNumber2.class));
Here is a demo on ideone.
If you really want a good, abstract OO solution to this problem, you should use the Abstract Factory Pattern.
Basically, this means you create a "factory" class whose only job is to create a specific type of unit. The nice thing about factory classes is that you can create an interface to represent your entire set of factories, and then pass around instances of the factories—which isn't really something you can do with normal class constructors.
A common pattern (which I would recommend here) is to use Anonymous Inner Classes with your abstract factory class or interface to create single instances of the "factory" for each unit type.
Here's a bit of example code to get you started:
/**
* Abstract class for Starcraft units
*/
public abstract class AUnit {
// . . .
}
/**
* Abstract factory for creating Starcraft units
*/
public abstract class AUnitFactory {
public abstract int unitCost();
public abstract AUnit createUnit();
}
public class Marine extends AUnit {
public static final int COST = 50;
/**
* Using an anonymous inner class to create an
* AUnitFactory instance for Marines
*/
public static final FACTORY = new AUnitFactory() {
public int unitCost() { return COST; }
public AUnit createUnit() { return new Marine(); }
}
// . . .
}
public class Zergling extends AUnit {
public static final int COST = 25;
/**
* Using an anonymous inner class to create an
* AUnitFactory instance for Zerglings
*/
public static final FACTORY = new AUnitFactory() {
public int unitCost() { return COST; }
public AUnit createUnit() { return new Zergling(); }
}
// . . .
}
/**
* Starcraft game!
*/
public class Game {
public addUnit(Player player, AUnitFactory unitFactory) {
// Get unit's cost
int cost = unitFactory.unitCost();
// Now deduct it from the player's resources
// . . .
// Create the unit
AUnit unit = unitFactory.createUnit();
// Now add the unit to the game for the given player
// . . .
}
// . . .
}
Now you could do something like Game.addUnit(player1, Zergling.FACTORY) or Game.addUnit(player2, Marine.FACTORY).
The nice thing is that you can pass the FACTORY instances around since they're just objects of type AUnitFactory. This means you could do something like have a combo box to select a unit type, and then a button which creates one of whichever unit type is currently selected in the combo box when clicked.
This is exactly what class methods are for. In a class method, unitCost() is a method of the Marine class itself (i.e. static public int UnitCost()), so you can call Marine.unitCost(), rather than m =new Marine() and then m.UnitCost().
Cool instructor. Wish I had one when I was taking OO.

Java Inheritance/OOP - call child type specific method with only a handle on parent

I'm writing a game engine in Java for Android games and my engine handles collision detection for different shapes. Each shape is its own class (Square, Circle, etc.), and derives from a common abstract parent Collidable. I have a physics manager class which basically checks if any of the existing objects in the game are colliding with another, and then does the appropriate action when collision is detected. The check for collision is implemented inside each physics shape child class as in the code below.
public abstract class Collidable
{
}
public class Square extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class Circle extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class Triangle extends Collidable
{
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
}
public class PhysicsMgr
{
public boolean Collides(Collidable p1, Collidable p2)
{
return p1.Collides(p2);
// This obviously won't work because there is no Collides
// method in Collidable. I want it to somehow call the child's
// method and pass in p2 as its child type rather than as
// a parent. Or somehow do this:
return (p1.child()).Collides(p2.child());
// I know that obviously nothing like this exists.
}
}
I am aware of "instanceof" and really don't want to check the child type of p1 and p2 versus every single collision shape I have. There must be a better way. I'm looking for either a workaround for my current problem, or preferably a redesign of my current collision detection system to avoid this problem altogether.
Thanks!
you should read about the visitor pattern
For starters, I wouldn't make Collidable an abstract class. Even though there are probably good arguments for it; it just seems to me like this is an "is a" situation where a lot of objects could be collidable.
So, that being said, here is what I would recommend:
// Assuming you're working in 2 dimensions
public class Coordinates {
public Coordinates(float x, float y) {
// etc etc etc
}
}
public interface ICollidable {
// Using unusually long name to illustrate point,
// but feel free to rename.
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector);
public Coordinates getCenterOfMass();
}
And then, for Square, Triangle, and Circle, I would implement the interface.
public class Square implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.lengthOfSide;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
public class Circle implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.radius;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
public class Triangle implements ICollidable {
#Override
public int getMaxDistanceFromCenterOfMass(Coordinates unitVector) {
// Must declare and initialize
return this.lengthOfSide;
}
#Override
public Coordinates getCenterOfMass() {
return this.centerOfMass;
}
}
Then, in your PhysicsMgr...
public class PhysicsMgr {
public boolean Collides(ICollidable p1, ICollidable p2) {
Coordinates cm1 = p1.getCenterOfMass();
Coordinates cm2 = p2.getCenterOfMass();
int length = Math.sqrt(Math.pow(cm1.x - cm2.x, 2) + Math.pow(cm1.y - cm2.y, 2))
// It is a misnomer to use coordinates as a unit vector, but if I defined a
// UnitVector class, it would be exactly the same with the exception of
// the class name for this situation.
Coordinates unitVector = new Coordinates((cm1.x - cm2.x)/length, (cm1.y - cm2.y)/length);
int collisionDistance1 = p1.getMaxDistanceFromCenterOfMass(unitVector);
int collisionDistance2 = p2.getMaxDistanceFromCenterOfMass(unitVector);
return (length - collisionDistance1 - collisionDistance2) <= 0;
}
}
The one major caveat here is that using the maxDistance from center of mass literally will only give you an approximation for the Square and Triangle. To be exact, you will have to declare some orientation, theta, and calculate the distance from the center of mass of the object to the edge along the unit vector (which will be tricky, but exact).
Another thing that is nice about this is that it allows you to easily add other collidable objects as your engine becomes more sophisticated. This also makes it so that none of the objects have to know about each other.
I was a physics TA for 3 years and it was actually how I got my first exposure to programming. If you're interested in the extra work, here is a reference to the book we used: http://matterandinteractions.org/ It is great for programmers because it teaches physics by using coding examples in python (specifically, vpython http://vpython.org/ ). So this would be a very good reference to have for physics programming.
public boolean Collides(Square) {...}
public boolean Collides(Circle) {...}
public boolean Collides(Triangle) {...}
You are going to need separate implementations for the various combinations of shapes (because there is no common algorithm, I think). So at one point, there will be the need to call instanceof. I am afraid having an abstract method or interface method public boolean Collides(Collidable) is not going to help here, and what you have now cannot be significantly improved upon. This is a textbook case of the limitations of OOP, because these collision detection methods cannot be neatly attached to any of the shape classes, they live somewhere in between, in something like your physics manager.

Why should I use interface in this situation in Java?

I'm trying to understand the basics of Java OOP concepts so I've a question about the interfaces as it confuses me a little. Below I was playing around with two classes. One which implements the SizeComparable interface and the other which doesn't but works too.
public interface SizeComparable {
int isHigher(SizeComparable obj);
}
public class Interesting implements SizeComparable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(SizeComparable obj) {
Interesting otherInteresting = (Interesting)obj;
if(this.getHeight() > otherInteresting.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
How is the code above better than the code bellow? Personally I don't understand because the code bellow those it's job great too. Am I missing some concepts behind the interface idea?
public class Interesting {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public int isHigher(Interesting obj) {
if(this.getHeight() > obj.getHeight()) {
return 1;
} else {
return 0;
}
}
public static void main(String[] args) {
Interesting i1 = new Interesting(182);
Interesting i2 = new Interesting(69);
int result = i1.isHigher(i2);
System.out.println("Is i1 higher than i2? Result: " + result);
}
}
I was trying to understand it (here), but I'm still unsure about this. Sorry if the question is a little silly, i just want to understand it completely.
If you have Interesting, Boring, Indifferent and Crazy classes which all represent some objects comparable by height, then all of them can implement the SizeComparable interface and thus be comparable to each other.
Without the interface you would need n methods in each class to compare it with itself and all the others.
At the beginning it probably won't make much sense, however when you will start injecting dependencies, start testing or will write more than one implementation of interface, than it will really give you boost.
Also it allows for multiple inheritance. Sometimes you want thing like comparable - very generic interface that may be used by a lot of classes in your system. That will come with bigger systems and larger class hierarchies.
Right now just trust rest of java world, and use them interfaces :)
and good luck
An interface is a contract that any class wishing to implement the interface agrees to follow. The reason for using an interface is to allow some other class or method to access the interface functions without requiring that the your class inherit from a common class... I'll modify your example to make it clearer:
public interface HeightCapable {
int getHeight();
}
public class Interesting implements HeightCapable {
private int height;
public Interesting(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
}
public class SomeOtherClass {
public boolean isHigher(HeightCapable obj1, HeightCapable obj2) {
// ... do something interesting
if (obj1.getHeight() > obj2.getHeight()) {
return true;
}
}
In the example above, any class implementing the HeightCapable interface can call SomeOtherClass.isHigher(). Without the interface, any class wishing to call SomeOtherClass.isHigher() would need to inherit from a common class. Java lacks multiple inheritance.
If you want to have your SizeComparable objects comparable not to all other SizeComparable objects, but only to those of some type, you could use generic types.
interface SizeComparable<X> {
/**
* returns true if this object is higher than that object.
*/
boolean isHigher(X that);
}
Then you could create your implementations like this:
public class Interesting implements SizeComparable<Interesting> {
...
public boolean isHigher(Interesting obj) {
return this.getHeight() > obj.getHeight();
}
}
Or, you could even have another interface
public interface HeigthHaving extends SizeComparable<HeightHaving> {
/**
* returns the height of this object.
*/
public int getHeigth();
/**
* compares this object's height with another objects height.
* #return true if this.getHeight() > that.getHeight, else false.
*/
public boolean isHigher(HeightHaving that);
}
Now every implementation of HeightHaving must implement the isHigher(HeightHaving) method (this would be the case even if we did not repeat it here), and should do that according to the specification here. Other SizeComparable implementations are not affected of this, though.
The good thing here is that now for example sort algorithms can sort lists/arrays of any type X implementing SizeComparable, so you don't have to write it again for every new type of object you may want to sort by height.
(In fact, there is already a similar interface Comparable<X> in the standard API. Maybe you want to use this instead of your SizeComparable.)
By the way, for a isXXX method usually a boolean return type is quite more sensible than an integer.

Categories

Resources