I have a question about polymorphism in Java. I have a abstract base class Shape and two derived classes Rectangle and Circle. I know that I can call overridden methods in Circle and Rectangle class with a Shape class reference but what if I have a method that Shape class doesn't have but Circle class has. How can I use polymorphism in this situation?
You cannot use polymorphism in this situation. The very idea of polymorphism is that you can use an object in a specified way irrespective of its actual shape (specific object type). By requiring access to a method that is unique to (literally) a specific shape, you must forego polymorphism.
(The above argument would not apply if Circle actually had subclasses, in which case you could polymorphically call these methods, but this is just moving the argument somewhere else.)
This happens all the time. The answer is that you need to cast your Shape to a Circle to access the method
Shape s = ...;
if (s instanceof Circle) {
((Circle)s).foo(); //method only on Circle
}
If you store a Circle in a Shape instance, you can invoke Circle methods on s by casting s to Circle:
Shape s = new Circle();
...
if ( s.instanceof(Circle) ) {
((Circle)s).circleMethod();
}
Apart from the casting solution suggested by other answers, if you think all subclasses of Shape should provide that method but you can't/don't want to implement it on Shape, you can declare the method as abstract and implement the method in Circle and Rectangle.
public abstract class Shape {
public abstract void foo();
}
public class Circle extends Shape {
public void foo() {
// Implementation
}
}
then you can do:
Shape s = new Circle();
s.foo();
Related
i started learning Java in university and we have an assignment that requires us to use a Superclass for Shape and Subclass that extend the shape.
This is the full questions:
Create a super class “Shape” from which you derive two subclasses “Square” and “Rectangle” with functions to calculate the square area and the rectangle area. In addition, to the function “toString” to display the square and rectangle info. Derive another sub class “Cube” from square with a function to calculate its area and a function “toString” to display the cube info."
What we need to do is calculate the shapes using the classes. Where should I start or move forward to solve the assignment?
This is where I think I should start, but need some guidance
public class Shapes {
class Shape {
}
class Rectangle extends Shape {
}
class Square extends Shape {
}
}
First, Shape class should be abstract, since you won't create any specific object of this class and you'll only use it as a "canvas".
This class has to have an abstract method, let's call it getArea(), that you'll have to override in your child classes to accomodate to the specified requirements for each kind of shape.
The toString() method belongs to Object class, since every class in Java extends from Object, you don't have to define anything, just override this method to return the desired String in every child class.
According to the definition you have post, the Cube class would be a composition of Square (a cube is composed by squares, but it's not a square), so I'd extend it from Shape and define it as a List or an array of 6 Square, so the getArea() of Cube would be the summatory of every Square area in it.
Putting aside the quality of the question:
You have a Shape class that will contain a method calculateSomething().
Shape does not define a specific shape so most likely you can return a -1 or 0?
Now, we can determine that the method of the Shape class does not provide us with any real value/info. Even if you create a Shape shape = new Shape() object and call its method, it does not help us at all.
Instead it provides us with a method that each subclass has to override in order to get the intended results.
What does that mean and how it works?
For you to not always have to do Rectangle rect = new Rectangle() for every single class and object, the Rectangle becomes a subclass of the Shape class.
This enables you to later do Shape rect = new Rectangle().
The big benefit of this is that you create an abstraction mechanism, meaning that you have a lot of shapes, either rectangles or triangles etc, but they all are Shape objects in the end.
So later you can just do:
Shape rect = new Rectangle();
Shape triangle = new Triangle();
rect.calculate();
triangle.calculate();
Instead of the more meticulous:
Rectangle rect = new Rectangle();
Triangle triangle = new Triangle();
rect.calculate();
triangle.calculate();
The former can further be utilised by:
// Putting all the objects in a list
List<Shape> shapes = new ArrayList<>();
// Create objects and add them
Shape rect = new Rectangle();
Shape triangle = new Triangle();
shapes.add(rect);
shapes.add(triangle);
As you can see for yourself, it is easier to handle and iterate over a list with all the elements being of type/class Shape.
// Basic example
for (Shape shape : shapes)
shape.calculateSomething();
Imagine if you had a hundred different shapes except Rectangle and Triangle. The latter method, without using inheritance, would quickly come to consume your project in an ever ending trial of maintenance and code changing.
By utilising inheritance otherwise, you can increase your Shape classes as much in quantity as you want and the same methods that used to work for a Shape, would still work for all the future new objects.
How does it work in practise? How do i create a subclass?
As you already know you can link your classes through the extend keyword.
But that is only the start.
To be able to utilize the inheritance, you will have to overwrite the method of your choosing, in the child class.
Take for instance the previous example:
Shape rect = new Rectangle();
rect.calculate();
But that raises the question, how can you get the correct value of calculate() method, when Shape class has a -1 or 0 returning from it and rect variable is now of type Shape?
Easily, you can override a method of the parent class through the #Override tag and by implementing the same method again on the child class but with different calculations. Example:
class Shape {
public void calculate() { return 0; }
}
class Rectangle extends Shape {
#Override
public void calculate() { return 2; }
}
Note that the name, variables etc of the method must be identical.
Now in the case of:
Shape rect = new Rectangle();
rect.calculate();
the calculate() method will return the number 2.
This happens because even though the rect object is of type Shape, it is also a Rectangle. Every Rectangle is a Shape. So when you try to call the desired method, the program knows to choose the overrided method of the Rectangle class, because in essence it is a Rectangle, covered by the abstraction Shape.
This works for any number of Shape subclasses, each with their own unique implementation of the method.
Also note that a Rectangle subclass can have its own private fields that are used in the other methods:
class Rectangle extends Shape {
private int height;
private int width;
// constructor
public Rectangle(int h, int w) {
this.height = h;
this.width = w;
}
#Override
public void calculate() {
return this.w * this.h;
}
}
So to answer your question, you just override the methods you want for each class as you desire. If a method is not overriden, then the original of the Shape parent class is run.
I hope this shined a little bit of light in your confusion towards abstraction and inheritance.
PS:
I know that you might be confused, but there are hundreds of answers and forums out there explaining this exact thing and that is how we all learned it. It needs time unfortunately but you will have a deeper understanding if you look at something yourself. I'm sure you have taken a taste of what is defined as 'wrong' or 'bad' to ask in here and that you will be more susceptible into studying it yourself in the future, considering there is material needed. I just tried to reach out to you because i have been in your place and believed i could make a difference with my approach.
If you have anything else to add or something to correct, it is always welcome in the comments section.
Edit:
As mentioned by the other guy that answered, the Shape class can and should be an abstract one. I just assumed you wanted it to be a normal one.
I'm using a Processing library to build my project in Java. I use a function that returns me an object of type PShape (which I don't have access to source).
I need to make this object of type Shape (a class I designed that extends PShape).
How can I make that?
Basically I have:
PShape pShape = loadShape(filename);
Where loadShape is a function I don't have access to source code.
I want to somehow do:
class Shape extends PShape {...}
and then
Shape shape = (Shape) loadShape(filename);
But it won't work, once loadShape() will give me a PShape, not a Shape
How can I make loadShape returns a Shape?
Thank you
If loadShape() returns a PShape, then it returns a PShape. You can't make it return a subclass of PShape.
Easiest approach would be Shape either copies the PShape into a new instance:
e.g.
Shape myLoadShape(String filename)
{
return new Shape(loadShape(filename));
// Assumes you have a `Shape(PShape)` constructor.
}
or perhaps Shape isn't a subclass, but it contains a PShape data member.
class Shape
{
// No one picked up my C++ syntax goof ;-)
protected PShape pshape;
// Using a constructor is just one way to do it.
// A factory pattern may work or even just empty constructor and a
// load() method.
public Shape(String filename)
{
pshape = loadShape(filename);
// Add any Shape specific setup
}
}
Suppose the following classes are defined:
class Shape { }
class Circle extends Shape { }
class Rectangle extends Shape { } // 1
You can write a generic method to draw different shapes:
public static <T extends Shape> void draw(T shape) { } // 2
The Java compiler replaces T with Shape:
public static void draw(Shape shape) { } // 3
My Question is, if we define directly // 3 in our class then we still be able to pass Shape, Circle and Rectangle reference to method at //3. Then why do we need to write // 2 generic method with type parameter <T extends Shape> which is untimately going to be same as //3 ?
You can refer this link with same example : http://docs.oracle.com/javase/tutorial/java/generics/genMethods.html
You may or may not need it. You need it if your method has to deal with other objects of the type T that must match the type of T extends Shape exactly, for example:
public static <T extends Shape> void drawWithShadow(T shape, Class<T> shapeClass) {
// The shadow must be the same shape as what's passed in
T shadow = shapeClass.newInstance();
// Set the shadow's properties to from the shape...
shadow.draw(); // First, draw the shadow
shape.draw(); // Now draw the shape on top of it
}
Above, passing Shape would not be enough, because we wouldn't be able to make the shadow of the exactly same type.
In case when there is no such requirement, a simple Shape would be sufficient.
In this particular case, you don't need a generic method.
But you can do more in a generic method than call a dynamically linked method on its arguments.
For example, you might have a generic method that accepts and returns a collection of T elements. Parameterizing it by type allows you to use it on multiple collection types.
Other examples where generic methods are useful are in this Java tutorial.
In your example, //3 is indeed the same as //2. But in other usecases, generic type may be useful:
you want to return value from the method, of the same type as the argument
you have 2 or more parameters and want to set restriction that they must be of the same type
The difference is that the kind of polymorphism you are using.
In the generic case you are using parametric polymorphism while in the second one you are using polymorphism by subtype. Actually you first case uses both kind of polymorphism.
Now, they could be similar in some aspects but they are not the same. A practical example:
List<Shape> shapes;
List<T extends Shape> specificShapes;
You can see that in the first case, not having a type parameter, I can't manage a list of a specific subtype of Shape, I can only manage an eterogeneous list of shapes but I'm unable to force any specific one on it. So I don't have any compile time juice that forbids me from adding a Triangle and a Rectangle to the shapes.
class ShapeDecorator {
private Shape shape;
..
Shape get() { return shape; }
}
class ShapeDecorator<T extends Shape> {
private T shape;
T get() { return shape; }
}
Here is another example, in this case you could write a generic decorator which is able to return a type T without the need of any cast. This can be useful in many situations in which having the common ancestor as subtype is not enough.
The main interest is that you can restrict the usage of your method to a specific type of shape in different part of the code.
At some point you may want to parametrize it to draw only Rectangle and in another place only Circle and this will be checked at compile time even if, at runtime, you will pass something of type Shape
I have a class called Shape that is abstract, and a class named Circle that extends Shape
Shape shapeCircle = new Circle();
I can set and get colors of shapeCircle fine because the color getters and setters are in Shape , but the dimensions of Circle is only for the Circle class (radius).
If Circle class has an instance variable private int radius and a method called getRadius(), how can I get/set the radius of shapeCircle? I tried shapeCircle.getRadius();, but no luck.
Only methods of Shape are accessible with object shapeCircle.
shapeCircle is type Shape, methods in Circle are not visible.
By using this,
Circle shapeCircle = new Circle();
you can call both method of Circle and Shape. The above case is take advantage of only Inheritance.
Edit
But if you add public abstract int getDimension(); in Shape class and Circle class implements getDimension() method
#Override
public int getDimension() {
return radius;
}
All classes that extends Shape needs to implements getDimension() method. But each subclass has its own dimension.
You can use
Shape shapeCircle = new Circle();
shapeCircle.getDimension();
This takes advantage of both polymorphism and abstract class.
Shape shapeCircle = new Circle();
Here the reference is of Shape and shape class doesn't defines radius variable.So you cannot use shapeCircle.getRadius();
To invoke get/set radious method type cast the shapecircle variable like this
Circle shapeCircle = (Circle)shapeCircle;
Now you can invoke the get/set radious methods. Please note that typecasting code should be in some different method to benefit using polymorphism.
EDIT:
You should design your abstract classes or interfaces to be having all important/common operations/methods which will help you in writing polymorphic code. For example: Radius field is specific to a Circle class.But consider you eventually want to calculate the area. So you should define CalculateArea() method in your abstract class and let every shape implement this method.This way, you achieve polymorphism.
Shape ShapeCicle = new Circle(Radius);
Float area = ShapeCircle.area();
Point is don't confine yourself with the radius example.Try to define classes in a way so that you can benefit from polymorphism.
You have to use instanceof keyword to check for the original type here . If the type is Circle, then you can type cast and call the getRadius method. Something like
if (shapeCircle instanceof Circle) {
Circle circle = (Circle)shapeCircle;
int radius = circle.getRadius();
}
That should do.
'Shape is not Circle' = Circle methods not available for Shape.
After reading the most excellent book "Head First Design Patterns", I began proselytizing to my colleagues the benefits of patterns and design principles. While extolling the virtues of my favorite pattern - Strategy Pattern - I was asked a question which gave me pause. Strategy, of course, uses inheritance and composition and I was on one of my tirades about "program to an interface (or supertype) not an implementation", when a colleague asked "why use an abstract base class instead of a concrete class?".
I could only come up with "well you force your subclasses to implement abstract methods and prevent them from instantiating the ABC". But to be honest the question caught me off gaurd. Are these the only benefits of using an abstract base class over a concrete class at the top of my hierarchy?
If you need specific methods to be implemented, then use an Interface. If there is shared logic that can be pulled out, use an abstract base class. If the base set of functionality is complete on its own, then you can use a concreate class as the base. An abstract base class, and an Interface cannot be instantiated directly, and that is one of the advantages. If you can use a concrete type, then you need to do override methods, and that has a "code smell" to it.
Program to interface, not to implementation has little to do with abstract and concrete classes. Remember the template method pattern? Classes, abstract or concrete, are the implementation details.
And the reason to use abstract classes instead of concrete classes is that you can invoke methods without implementing them, but by leaving them to be implemented to subclasses instead.
Programming to an interface is a different thing - it is defining what your API does, not how it does it. And this is denoted by interfaces.
Note one key difference - you can have protected abstract methods, which means that this is implementation detail. But all interface methods are public - part of the API.
Yes, although you could also use an interface to force a class to implement specific methods.
Another reason for using an abstract class as opposed to a concrete class is that an abstract class obviously can't be instantiated. Sometimes you also wouldn't want this to happen, so an abstract class is the way to go.
First of all, the Strategy Pattern should almost never be used in modern C#. It is mainly for languages like Java that don't support function pointers, delegates, or first-class functions. You will see it in older versions of C# in interfaces such as IComparer.
As for Abstract Base Class vs. Concrete Class, the answer in Java is always "What works better in this situation?" If your strategies can share code, then by all means let them do so.
Design patterns are not instructions on how to do something. They are ways to categorize things that we have already done.
Abstract base classes are usually used in scenarios where the designer wants to force an architectural pattern where certain tasks are to be carried out in the same manner by all the classes while other behaviours are dependent on the subclasses.
example:
public abstract class Animal{
public void digest(){
}
public abstract void sound(){
}
}
public class Dog extends Animal{
public void sound(){
System.out.println("bark");
}
}
Stratergy pattern asks designers to use Compositional behaviour for cases where there are families of alogirthms for a behaviour.
If the client relies on "implied behavior contract[s]", it is programmed against an implementation and against unguaranteed behavior. Overriding the method while following the contract only exposes bugs in the client, not causes them.
OTOH, the mistake of assuming contracts that aren't there is less likely to cause problems if the method in question is non-virtual--i.e., overriding it cannot cause problems because it cannot be overridden. Only if the implementation of the original method is changed (while still obeying the contract) can it break the client.
The question of whether a base class should be abstract or concrete depends IMHO largely on whether a base class object which implemented only behaviors that were common to all objects in the class would be useful. Consider a WaitHandle. Calling "wait" upon it will cause code to block until some condition is satisfied, but there's no common way of telling a WaitHandle object that its condition is satisfied. If one could instantiate a "WaitHandle", as opposed to only being able to instantiate instances of derived types, such an object would have to either never wait, or always wait forever. The latter behavior would be pretty useless; the former might have been useful, but could be achieved almost as well with a statically-allocated ManualResetEvent (I think the latter wastes a few resources, but if it's statically allocated the total resource loss should be trivial).
In many cases, I think my preference would be to use references to an interface rather than to an abstract base class, but provide with the interface a base class which provides a "model implementation". So any place one would use a reference to a MyThing, one would supply a reference to "iMyThing". It may well be that 99% (or even 100%) of iMyThing objects are actually a MyThing, but if someone ever needs to have an iMyThing object which inherits from something else, one could do so.
Prefer abstract base classes in below scenarios:
A base class can't exist with out a sub class => the base class is simply abstract and it can' t be instantiated.
A base class can't have full or concrete implementation of a method => Implementation of a method is base class is incomplete and only sub classes can provide complete implementation.
Base class provides a template for method implementation but it still depends on Concrete class to complete the method implementation -Template_method_pattern
A simple example to illustrate above points
Shape is abstract and it can't exist without Concrete shape like Rectangle. Drawing a Shape can't be implemented at Shape class since different shapes have different formulas. The best option to handle scenario : leave draw() implementation to sub-classes
abstract class Shape{
int x;
int y;
public Shape(int x,int y){
this.x = x;
this.y = y;
}
public abstract void draw();
}
class Rectangle extends Shape{
public Rectangle(int x,int y){
super(x,y);
}
public void draw(){
//Draw Rectangle using x and y : length * width
System.out.println("draw Rectangle with area:"+ (x * y));
}
}
class Triangle extends Shape{
public Triangle(int x,int y){
super(x,y);
}
public void draw(){
//Draw Triangle using x and y : base * height /2
System.out.println("draw Triangle with area:"+ (x * y) / 2);
}
}
class Circle extends Shape{
public Circle(int x,int y){
super(x,y);
}
public void draw(){
//Draw Circle using x as radius ( PI * radius * radius
System.out.println("draw Circle with area:"+ ( 3.14 * x * x ));
}
}
public class AbstractBaseClass{
public static void main(String args[]){
Shape s = new Rectangle(5,10);
s.draw();
s = new Circle(5,10);
s.draw();
s = new Triangle(5,10);
s.draw();
}
}
output:
draw Rectangle with area:50
draw Circle with area:78.5
draw Triangle with area:25
Above code covers point 1 and point 2. You can change draw() method as template method if base class has some implementation and calls sub-class method to complete draw() function.
Now same example with Template method pattern:
abstract class Shape{
int x;
int y;
public Shape(int x,int y){
this.x = x;
this.y = y;
}
public abstract void draw();
// drawShape is template method
public void drawShape(){
System.out.println("Drawing shape from Base class begins");
draw();
System.out.println("Drawing shape from Base class ends");
}
}
class Rectangle extends Shape{
public Rectangle(int x,int y){
super(x,y);
}
public void draw(){
//Draw Rectangle using x and y : length * width
System.out.println("draw Rectangle with area:"+ (x * y));
}
}
class Triangle extends Shape{
public Triangle(int x,int y){
super(x,y);
}
public void draw(){
//Draw Triangle using x and y : base * height /2
System.out.println("draw Triangle with area:"+ (x * y) / 2);
}
}
class Circle extends Shape{
public Circle(int x,int y){
super(x,y);
}
public void draw(){
//Draw Circle using x as radius ( PI * radius * radius
System.out.println("draw Circle with area:"+ ( 3.14 * x * x ));
}
}
public class AbstractBaseClass{
public static void main(String args[]){
Shape s = new Rectangle(5,10);
s.drawShape();
s = new Circle(5,10);
s.drawShape();
s = new Triangle(5,10);
s.drawShape();
}
}
output:
Drawing shape from Base class begins
draw Rectangle with area:50
Drawing shape from Base class ends
Drawing shape from Base class begins
draw Circle with area:78.5
Drawing shape from Base class ends
Drawing shape from Base class begins
draw Triangle with area:25
Drawing shape from Base class ends
Once you have decided that you have to make as method abstract, you have two options : Either user interface or abstract class. You can declare your methods in interface and define abstract class as class implementing the interface.