Need help creating an Oval and Line class that extend shape class at the bottom
ID: 3863232 • Letter: N
Question
Need help creating an Oval and Line class that extend shape class at the bottom of this code. Thank You.
package first_shape_drawing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
enum DrawType {scribble, oval, rectangle, polygon, line};
class DrawingProperties
{
DrawType drawType;
boolean filled;
Color color;
DrawingProperties(DrawType drawType, Color color, boolean filled)
{
this.drawType = drawType;
this.color = color;
this.filled = filled;
}
public String toString()
{
return drawType + " color=" + color +" filled="+ filled;
}
}
public class Drawing {
DrawingProperties drawingProperties = new DrawingProperties(DrawType.rectangle, Color.blue, false);
ArrayList<Shape> shapeArr = new ArrayList<Shape>();
Shape inProgress = null;
public String toString()
{
return drawingProperties.toString();
}
public void draw(Graphics g)
{
for (int i=0; i < shapeArr.size(); i++)
{
Shape s = shapeArr.get(i);
s.draw(g);
}
if (inProgress != null)
inProgress.draw(g);
}
public void setColor(Color color)
{
drawingProperties.color = color;
}
public void setFilled(boolean filled)
{
drawingProperties.filled = filled;
}
public void setDrawType(DrawType drawType)
{
drawingProperties.drawType = drawType;
}
public void mousePressed(Point p)
{
switch(drawingProperties.drawType)
{
case rectangle:
inProgress = new Rectangle(drawingProperties.color, drawingProperties.filled);
break;
case oval:
//inProgress = new Oval(drawingProperties.color, drawingProperties.filled);
break;
case line:
//inProgress = new Line(drawingProperties.color);
break;
case scribble:
inProgress = new Scribble(drawingProperties.color);
break;
}
inProgress.firstPoint(p);
}
public void mouseDragged(Point p)
{
switch(drawingProperties.drawType)
{
case rectangle:
case oval:
case scribble:
case line:
inProgress.subsequentPoint(p);
break;
}
}
public void mouseReleased(Point p)
{
inProgress.subsequentPoint(p);
shapeArr.add(inProgress);
inProgress = null;
}
}
abstract class Shape
{
Color color;
Shape ( Color c)
{
color =c;
}
abstract void firstPoint(Point p);
abstract void draw(Graphics g);
abstract void subsequentPoint(Point p);
}
class Rectangle extends Shape
{
boolean filled=false;
Point start;
Point lastPoint;
Rectangle(Color c, boolean filled)
{
super(c);
lastPoint = start;
this.filled = filled;
}
@Override
void firstPoint(Point p) {
start =p;
lastPoint =p;
}
@Override
void draw(Graphics g) {
g.setColor(color);
int x = Math.min(start.x, lastPoint.x);
int y = Math.min(start.y, lastPoint.y);
int w = Math.abs(start.x - lastPoint.x);
int h = Math.abs(start.y - lastPoint.y);
if (filled)
g.fillRect(x, y, w, h);
else
g.drawRect(x, y, w, h);
}
@Override
void subsequentPoint(Point p) {
lastPoint =p;
}
}
class Scribble extends Shape
{
ArrayList<Point> points= new ArrayList<Point>();
Scribble(Color c)
{
super(c);
}
@Override
void firstPoint(Point p) {
points.add(p);
}
@Override
void draw(Graphics g) {
g.setColor(color);
for (int i=1; i < points.size(); i++)
{
Point first = points.get(i-1);
Point next = points.get(i);
g.drawLine(first.x, first.y, next.x, next.y);
}
}
@Override
void subsequentPoint(Point p) {
points.add(p);
}
}
Explanation / Answer
ANSWER: For Oval and Line class that extend shape class at the bottom:
In fact, we will define the Shape class (using an id instance variable and constructor) throughout the examples in this lecture as
Again, logically this method belongs in the class, even if it cannot be written there (because Shape is too high in the hierarchy).
For example, we can define a concrete Circle subclass by extending Shape as follows
Because the Circle class is concrete, we can construct new objects from this class. So, we can write
In fact, we can even write
which prints exactly the same thing! Here is the reasoning. Both Shape and Circle define toString methods, Java allows us to call toString on such variables. In both cases the object to which c/s refer is constructed from the Circle class, so it is the method DEFINED IN THIS CLASS that is called.
Stop and think hard! Many students reason that since s is DEFINED to be of type Shape then calling s.toString calls the toString method defined in the Shapeclass. THIS IS INCORRECT THINKING! Recall that Java's rule say that the TYPE determines WHAT methods can be called, but the CLASS OF THE OBJECT determines WHICH method is called! This is polymorphism in action.
Of course, if we wrote Shape s = new Circle("c1",1.0); then we COULD NOT call s.setRadius(2.0); because the type Shape defines no setRadius method. But if we wrote Circle c = new Circle("c1",1.0); then we COULD call c.setRadius(2.0); because the type Cirble does define this method.
In fact, we will define the Shape class (using an id instance variable and constructor) throughout the examples in this lecture as
public abstract class Shape { public Shape (String id) {this.id = id;} //This abstract method must be defined in a concrete subclass. //Note that it is called in this class in the toString method. public abstract double getArea(); public String getId() {return id;} public String toString( ) {return "Shape[id="+id+",area="+getArea()+"]";} private String id; } Generally, abstract classes can specify all the standard class components: constructors, methods, and instance variables. Again, a class must be defined with the keyword abstract (as is the case above) if any of its methods is defined with the keyword abstract (as is the case above). Note that we can call the abstract method in other methods defined in the class, even if its body isn't defined yet. Again, logically this method belongs in the class, even if it cannot be written there (because Shape is too high in the hierarchy).
For example, we can define a concrete Circle subclass by extending Shape as follows
public class Circle extends Shape { public Circle (String name, double r) { super(name); radius = r; } //Overide the abstract method declared in shape public double getArea() {return Math.PI * radius * radius;} public double getRadius() {return radius;} public void setRadius(double newRadius) {radius = newRadius;} public String toString( ) {return "Circle["radius="+radius+","+super.toString()+"];} private double radius; } Here the Circle subclass does override the one abstract method that it inherits from Shape; it defines a few new methods, but none of them is abstract; so, it is a concrete class -and therefore not defined with the abstract keyword. Also notice that its constructor must be supplied a radius that is stored in an instance variable in this class, and is used to compute the area. As we described above, although we cannot constuct a new object from the class Shape, we can call the constructor for this class inside the constructor for a subclass (as the Circle class does with its call of super(name); in its constructor). Because the Circle class is concrete, we can construct new objects from this class. So, we can write
Circle c = new Circle("c1",1.0); System.out.println(c.toString()); //or just ...(c); Which will print Circle[radius=1.0,Shape[id=c1,,area=3.141592653589793]] In fact, we can even write
Shape s = new Circle("c1",1.0); //Note the type System.out.println(s.toString()); //or just ...(s); which prints exactly the same thing! Here is the reasoning. Both Shape and Circle define toString methods, Java allows us to call toString on such variables. In both cases the object to which c/s refer is constructed from the Circle class, so it is the method DEFINED IN THIS CLASS that is called.
Stop and think hard! Many students reason that since s is DEFINED to be of type Shape then calling s.toString calls the toString method defined in the Shapeclass. THIS IS INCORRECT THINKING! Recall that Java's rule say that the TYPE determines WHAT methods can be called, but the CLASS OF THE OBJECT determines WHICH method is called! This is polymorphism in action.
Of course, if we wrote Shape s = new Circle("c1",1.0); then we COULD NOT call s.setRadius(2.0); because the type Shape defines no setRadius method. But if we wrote Circle c = new Circle("c1",1.0); then we COULD call c.setRadius(2.0); because the type Cirble does define this method.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.