I have 2 classes that perform a very similar task, but require different data types passed to them in order to perform those functions.
They both ultimately write to files and have expose a single public method: write() using the constructor for simple dependency injection.
This is where they differ - 1 class accepts a single object of a specific type, while the other accepts an array of that object type.
Is this a valid case for polymorphism? I think it can be but tehcnically should not?
How is this situation to be correctly handled i.e. 2 or more classes which perform a very similar function, but in a slightly different way and crucially, require different data types passed in as dependencies?
You need overloaded methods in this case. One which works with single object and other with a number of objects. They should be in the same class.
Here is an easy-to-remember way of when to use what:
1. Overloading is when you need to do the same thing with different data
2. Overriding is when you need to do the same thing with the same data in a different way
public class FileWriter {
public void write(File from){ // single file
// magic logic
}
public void write(File... from){ // multiple files using varargs
// magic logic
}
}
If you only have two Write methods, one taking a single object and the other taking a List of objects -> I would put both methods on the same class.
If you have one Write for each type, I would go for generics.
Introducing a base class wouldn't be my first choice, better to extract the general stuff into another class and use it from different classes (has-a instead of is-a).
Polymorphism is only useful if you have the same method signature but need to do stuff in different ways.
Hard to answer without a particular code sample, but the scenario you've presented fits something similar to a decorator pattern:
class X
{
public void doSomething(int number) { ... }
};
class XForCollections
{
public XForCollections(X x) { ... }
public void doSomething(int[] numbers) { ... }
};
Note, that it's not really a decorator, as XForCollection doesn't inherit X.
Use an abstract generic superclass with the common stuff.
If you want WriterA that writes an argument of type ArgA, and WriterB that writes an argument of type ArgB, you'll make
an abstract Writer<T> with all of the common stuff in it, and an abstract method such as public void write(T arg)
WriterA that extends Writer<ArgA>
WriterB that extends Writer<ArgB>
Say you have this:
class A{
void write(int a){}
}
class B{
void write(int[] a){}
}
Since you say the implementations for those methods vary deeply between each other, then varargs probably wouldn't be a suitable option. To simplify things, do this::
class WriteStuff{
void write(int a){}
void write(int[] a){}
}
This would let you attain a higher level of cohesion for your classes. Polymorphism isn't really necessary here.
Then again, it's really too little information to go on with. You should probably write up some example code.
Polymorphism – means the ability of a single variable of a given type to be used to reference objects of
different types, and automatically call the method that is specific to the type of object the variable references. In a
nutshell, polymorphism is a bottom-up method call. The benefit of polymorphism is that it is very easy to add new
classes of derived objects without breaking the calling code that uses the polymorphic classes or interfaces. When you send a message to an object even though you
don’t know what specific type it is, and the right thing happens, that’s called polymorphism. The process used by
object-oriented programming languages to implement polymorphism is called dynamic binding.
Example:
Launcher
private void init() {
//client or calling code
double dim = 5.0; //i.e. 5 meters radius or width
List<Shape> listShapes = new ArrayList<Shape>(20);
Shape s = new Circle();
listShapes.add(s); //add circle
s = new Square();
listShapes.add(s); //add square
getTotArea (listShapes,dim); //returns 78.5+25.0=103.5
//Later on, if you decide to add a half circle then define
//a HalfCircle class, which extends Circle and then provide an
//area(). method but your called method getTotArea(...) remains
//same.
}
/** called method: method which adds up areas of various
** shapes supplied to it.
**/
public double getTotArea(List<Shape> listShapes, double dim){
Iterator<Shape> it = listShapes.iterator();
double totalArea = 0.0;
//loop through different shapes
while(it.hasNext()) {
Shape s = (Shape) it.next();
totalArea += s.area(dim); //polymorphic method call
}
return totalArea ;
}
}
Shape
public abstract class Shape {
protected abstract double area(double dim);
}
Square
public class Square extends Shape{
#Override
protected double area(double dim) {
return dim*dim;
}
}
Circle
public class Circle extends Shape{
#Override
protected double area(double dim) {
return Math.PI*dim*dim;
}
}
Related
Here's the problem, I have two drawing JAR libraries (A and B). Both provide separate but useful functionality. However, in their infinite wisdom they have two different concepts of the basic point class.
Neither has any interesting or particularly unique methods or fields and both basically boil down to:
public class PointA{
double x;
double y;
}
and
public class PointB{
double x;
double y;
}
The functions in these libraries have methods that look like:
public static List<PointA> doInterestingThing();
or
public static PointB calculateThatThing();
I feel like there should be some nice way to just understand that these two classes are for all intents, the same.
If I had source access I could just have them implement some IPoint interface, but both libraries are in JARS.
The way I see it, there are several options:
Convert one to the other. Either make functions to convert all PointA's to PointB's or vice versa. That would mean essentially making a abstraction layer atop one of the libraries by wrapping every function in it with some boilerplate conversion code.
public static List<PointA>doInterestingThingWrapper(){
return convertPoints(LibraryB.doInterestingThing());
}
Make some third class PointC, that both library's results are converted to which represented my code's understanding of a point. Same problems as above, but now I need to write two times as many boilerplate conversions!
Edit the JARS directly. Obviously this is not preferable. However, it would allow me make PointA and PointB implement the same interface.
Some magic dynamic interface interaction I don't know about.
Could it be that Java has some way of dynamically assigning interfaces to already loaded classes?
Something like:
public interface IPoint{
double getX();
double getY();
}
public static void main(){
//Magical made up linking syntax
PointA implements IPoint{
public getX(){
this.getX()//PointA's method
}
public getY(){
this.getY(){//pointA's method
}
}
//And same for pointB
//And now we can say things like:
List<? extends IPoint> listOPoints=A.doInterestingThing();
//and:
IPoint thePoint=B.calculateThatThing();
}
I apologize in advance if this is a duplicate. I didn't even know what to call the problem which makes searching hard. If there's some obvious design pattern (adapter pattern?) that I missed that solves this, let me know.
You have two solutions
Use reflection and unreflection to use same named functionatily.
Wrap both in your project code into a object that implements the interface.
Sample:
class A { public void d(){}}
class B { public void d(){}}
interface D { void d(); }
class AD extends A implements D {}
class BD extends B implements D {}
Or
class AD implements D {A obj = new A(); public void d(){obj.d();}}
So as part of a car rental system I need to write classes to represent large and small cars, the difference between these being that they have different size tanks and consume fuel at different rates. Currently my approach is to have an interface, Car, implemented by an abstract class AbstractCar, which is extended by two concrete classes SmallCar and LargeCar. However this is my first time using interfaces and abstract classes (we are just covering them in class and this assignment is designed to assess our knowledge of them) and I'm having trouble knowing what to place in what class.
The fill method implementations are exactly the same, they just need to refer to the correct value of FUEL_CAPACITY, so it feels that I should be implementing these methods in the AbstractCar class, but then I don't know how to get them to refer to the correct FUEL_CAPACITY values. The field fuelLevel is also obviously held by all cars so it feels that I should declare it in AbstractCar, but then I cannot access it from the subclasses without removing its privacy.
Would anyone be able to help me figure out what I'm doing wrong or misunderstanding about interfaces and inheritance? One thing I've been considering is producing an enum CarType, having AbstractCar hold a CarType as a field and all implementation is done in the AbstractCar class using if statements to switch to the correct FUEL_CAPACITY value, and simply using SmallCar and LargeCar as constructors or factory classes without much or even any actual implementations.
Thanks in advance for any help I realise its a bit long winded, however I try to make sure I'm fully understanding the concepts we are learning and that I'm implementing them correctly rather than just botching together something that 'works' but might not necessarily be the correct or most elegant solution.
You can transfer the logic to the AbstractCar with the values like you pointed out. Then just set those values in the constructor of SmallCar and LargeCar. This would be one approach. Like you pointed out, you always have to have the common logic in the parent class. You want to avoid duplicate code. Then you just have to make sure you set different values in the constructor. And if you know the fix value (as you do from the given example), you can even omit giving parameters to SmallCar or LargeCar constructors and just set those fixed values in the super() call inside the constructor.
Here is the implementation of my solution.
The interface Car, where I REMOVED the getFuelMethod() method since the access level has to be protected:
public interface Car {
RegistrationNumber getRegistration();
int getFuelCapacity();
// int getFuelLevel(); this can not be implemented
// all methods in an interface are PUBLIC
// so you have to lower the access level by removing it from the interface
// HERE goes the rest of the method signatures
}
}
The abstract class AbstractCar:
public abstract class AbstractCar implements Car {
// this is the common variable
// that is why we save it in the parent class
private int fuelCapacity;
private int fuelLevel;
// we forward the value to the parent constructor with the super call
public AbstractCar(int fuelCapacity) {
this.fuelCapacity = fuelCapacity;
// I set the value to 0 for the start, but
// you can also pass the value to the super call,
// same as fuelCapacity - it is up to you
this.fuelLevel = 0;
}
// The getters and setter allow us to retrieve the values
// from the abstract class through capsulation!
// here we have the getter to be able to retrieve the value from SmallCar and LargeCar
public int getFuelCapacity() {
return.fuelCapacity;
}
public void setFuelCapacity(int fuelCapacity) {
this.fuelCapacity = fuelCapacity;
}
protected int getFuelLevel() {
return fuelLevel;
}
protected void setFuelLevel(int fuelLevel) {
this.fuelLevel = fuelLevel;
}
// HERE goes the rest of the code
}
Here is the SmallCar implementation:
public class SmallCar extends AbstractCar {
private static final int FUEL_CAPACITY = 45;
public SmallCar() {
// we set the value in the parent class
super(FUEL_CAPACITY);
}
public int drive() {
// HERE goes the logic for drive for SmallCar. Same method is needed
// in the LargeCar class, because the logic differes.
}
// HERE goes the rest of the code
}
If you just want to hide FUEL_CAPACITY from the class user but not from the further developers, you can declare it as protected in the AbstractCar and initiallize it with a proper value in the child classes. Also I would declare a getter method getCapacity() in the AbstractCar which returns this value.
If your Capacity is only one property (only data) of Car, use #Jernej K approach, but if calculating the capacity may have some logic, use this:
Best way is to use abstract methods. you put a method to abstract Integer getCapacity(); in your abstract class
public abstract class AbstractCar implements Car {
private final RegistrationNumber registration;
private boolean isRented;
AbstractCar() {
this.registration = RegistrationNumber.getInstance();
}
public RegistrationNumber getRegistration() {
return registration;
}
public boolean isRented() {
return isRented;
}
//You can use this method in other methods of AbstractCar, but is implemented in your concrete classes
public abstract Integer getCapacity();
public boolean isFull() {
if (fuelLevel == getCapacity()) {
return true;
} else return false;
}
}
and then use it in other functions. and in your concrete class, you define the body of method:
public Integer getCapacity(){
//Your logic to calculate capacity for every concrete class here
}
I am using the Processing.org api - so i cant just change the classes in question.
Problem is simple, but i havent found an answer:
void drawStuff(PGraphics view) {
view.beginShape();
view.vertex(... lots of vertex calls / lines
}
void drawStuff(PShape view) {
view.beginShape();
view.vertex(... lots of vertex calls / lines
}
what i need is a way to combine them into one method, like:
void drawStuff(Object view) {
// how to cast to PShape and PGraphics
view.beginShape();
view.vertex(... lots of vertex calls /lines
}
the classes PShape and PGraphics have same/similar methods, at lest for the one i call, they are the same. But according to the Processing javadocs, PShape and PGraphics are both coming from java.lang.Object, so as far as i understand the dont share anything.
Like others pointed out in the comments of the OP, write a wrapper class/interface. The interface is the abstraction towards your code in which you don't want to know the actual implementation you're dealing with:
Start with defining the interface:
public interface PWrapper {
public void beginShape();
public void vertex();
}
Then, because of the unfortunate design in which PShape and PGraphics have nothing in common but Object, you'll need to implement a wrapper for each of these classes that implements your new interface. These wrappers are infact delegating their method calls to the appropriate methods of the wrapped object. For example, the wrapper for a PShape would be implemented like this:
public final class PShapeWrapper implements PWrapper {
private final PShape ps;
public PShapeWrapper (PShape ps){
this.ps = ps;
}
#Override
public void beginShape(){
ps.beginShape();
}
#Override
public void vertex(){
ps.vertex();
}
}
Then again in your code, define the method like this:
void drawStuff(PWrapper wrap) {
wrap.beginShape();
wrap.vertex();
}
As you can see, this method does not know what runtime object it's dealing with: it may be a PShapeWrapper (see above) or a PGraphicsWrapper (not posted). Even better: it may be any class that implements PWrapper but doesn't exist yet, so this is a maintainability plus.
This design pattern is called "Adapter".
I was reading some article about collision avoidance systems in cars when my programmer mind led me to think of that concept in the object-oriented way, and it made me wonder if those systems respect the object-oriented programming model.
Being mainly a Java developer, I transposed this problem in a Java environment and it raised a particular question: does calling a public method within the same class (in a non-static context) respect and follow the object-oriented way?
I mean, take this brief hypothetical Car class:
public class Car {
// Class attributes.
// Constructors.
public void accelerate(final double amplitude) {
// Accelerate according to the amplitude.
}
public void brake(final double amplitude) {
// Brake according to the amplitude.
}
// Other useful methods.
private void collisionPreventionActions() {
// Some actions.
brake(100.0);
// Some other actions.
}
}
Suppose some Thread is responsible of detecting a collision and take actions when it does detect a collision, and one of those actions would be braking. Obviously the brake(...) method becomes an interesting choice, but doesn't that break the object-oriented way of doing things? It's not just the brakes though. What if the collision avoidance system in this class used the steering wheel instead to avoid the accident? I find it weird that the car would be using its own input from an internal point of view...
On a more general scope, suppose you have a generic object, which I like to see as a black box. The public methods would be the equivalent of levers on that black box that would control its behaviour. Calling a public method within this object would mean that the black box would activate its own levers from its internal mechanism.
I ask because I know it's legal in Java to do so, and that I've seen public methods being called within the same class numerous times in my life, but it being legal doesn't necessarily mean that it's the proper OO way of doing it.
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation? If not, what would be the proper way of doing it or what could be the workaround?
There is nothing wrong with this choice from the OOP perspective: it is perfectly fine for a method to perform things that require combinations of other methods.
In practice, though, a common approach would be to separate the functionality into a public and a private portions, like this:
public void brake(final double amplitude) {
// check preconditions
if (speed == 0) throw new IllegalStateException("cannot brake when standing");
if (amplitude <= 0) throw new IllegalArgumentException("amplitude must be positive");
// ... do other important checks
doBrake(amplitude);
}
private void doBrake(final double amplitude) {
// The real code goes here
}
Now your collisionPreventionActions could call doBrake instead of brake, assuming that you have checked all the necessary preconditions before making the call.
Note: doBrake should check its preconditions as well. However, rather than throwing exceptions when preconditions are not met, it can use assertions. The difference is that exceptions indicate a misuse of your public methods by others, while assertions indicate misuse of your encapsulated methods by you or someone else maintaining your code.
No rules are violated when an object uses its own API. On the contrary, problems are likely to occur if a class has an API that can be overridden, but it fails to use that API internally.
As a trivial example, consider a non-final property accessor. An object could skip the accessor and read (or worse, write) fields directly. Suppose the accessor is overridden in a subclass to compute the property value using the field together with some other information from the subclass. Now the class is broken because it failed to honor its own contract.
Consider the (somewhat contrived) Point and OffsetPoint classes below. The derived class, OffsetPoint is written correctly, but it's inherited toString() method will not work as expected because the parent class, Point, wrongly fails to use its own accessors.
public class Point {
private final int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int getX() { return x; }
public int getY() { return y; }
#Override
public final String toString() {
/* Here's the bug; should be getX() and getY() instead of x and y */
return String.format("(%d,%d)", x, y);
}
}
class OffsetPoint extends Point {
private int dx, dy;
OffsetPoint(Point point, int dx, int dy) {
super(point.getX(), point.getY());
this.dx = dx;
this.dy = dy;
}
#Override
public int getX() { return super.getX() + dx; }
#Override
public int getY() { return super.getY() + dy; }
}
Does using public methods within the same class in a non-static context follow the rules of object-oriented programming and encapsulation?
No, there is no problem with encapsulation becuase the method is public so anyone (even this) can call it.
However, for something like a collision avoidance system, relying on public methods could be bad security wise.
Let's use your example of this intenal Collision detector calling the public method brake(). What if someone subclassed car and overrode the method?
public class BrokenCar extends Car{
#Override
public void brake(final double amplitude) {
//BREAKS CUT!!!
}
}
So there are some security rules of not relying on overridable methods. Making brake and accelerate final methods resolves this problem.
Yes, I think it is proper in an OO context to call your own public method. It's quite common when there are overloads for a method that all but one call the most specific one, either filling in defaults for missing parameters or transforming the type of the argument(s). I also see the pattern where all the overloads call into a private or protected method of the same name with _internal or _impl added to the end. For example, several overloads of ComputeSpeed might all call ComputerSpeed_internal. This pattern would be appropriate if there is parameter validation in the public methods that you don't want to do twice, or would be inappropriate for internal calls.
You can certainly introduce problems by not having a clear separation of concerns. For example, if the caller of collisionPreventionActions also decided it was a good idea to set the brake, you could have a conflict in how much brake is applied.
KC
In general, it is fine to call the public methods. The thing to consider is what the interface of the Car should be. In this case, does preventCollision() belong in the Car class or in some other CollisionPrevention class.
Breaking your code multiple classes each with a single responsibility, and then using them a bigger class like Car, is generally a good idea.
I totally agree with you that it's common that a class itself addresses its private members and methods. But I don't understand why it shouldn't be legal in terms of the Object Oriented Paradigm. Consider the following example:
public class Human {
public Human() {
liveYourLife();
}
private void liveYourLife() {
while(alive){
createYourDay();
}
}
private void createYourDay() {
drink();
eat();
sleep();
awake();
drink();
}
private void eat() {}
private void drink() {}
private void sleep() {}
private void awake() {}
}
Probably someone will criticise the simple rule of life, shown in the example above. But what I want to demonstrate with the few lines above is, that "normally" a human is allowed to decide on his daily routine.
The basic principle of the OO-Paradigm is to describe the actions and properties of real world entities. Hence, as long you are allowed to yourself decide on when you want to eat, drink, sleep, etc. your above described model is absolutely correct. But if you discover some exceptional cases in your problem domain which you want to address in your software (e.g. you got arrested, etc. ) you should update your OO-design.
In case that there is an something, which heavily influences the state of another instance, you should treat that "instance of disturbance" as a different object which has a reference to the actual instance.
public class Prisoner extends Human {
#Override
private void liveYourLife() {
while(jailed){
createYourDay();
}
}
#Override
private void createYourDay() {
// A bit different :)
}
}
public class Prison {
private List<Prisoner> prisoners;
}
I'm working on an application in which I have two fairly similar object classes whose fields need to be normalized. Many of the fields that need to be normalized are shared by both of these classes, but there are some that pertain only to one or the other.
I was thinking to create an interface with getters and setters for all of the fields that need to be normalized, that way I could pass both objects to the same class and access the fields / set the normalized values via the interface methods. Would this be considered bad convention?
Below is simplified example-- the objects I am normalizing will only ever be read from once the normalization is completed. Thanks in advance!
class A implements C{
T x;
T y;
T z;
...
}
class B implements C{
T x;
T y;
T k; // no 'z', above has no k
....
}
interface C {
public T getX();
public void setX(T x);
public T getY();
public void setY(T y);
public T getZ();
public void setZ(T z);
public T getK();
public void setK(T k);
}
If the code is properly documented saying A does not support
public T getK();
public void setK(T k);
and B does not support
public T getZ();
public void setZ(T z);
then I think you can go ahead with this design.
And, also construct UnsupportedOperationException with the specified detail message for the classes that doesn't support some of the methods of C. For example,
class A implements C{
T x;
T y;
T z;
...
public T getK(){
throw new UnsupportedOperationException("YOUR MESSAGE");
}
}
Isn't implementing an interface and providing an empty implementation a bad design issue? though you document it, it goes against the concept of interface and is inconsistent as you may have an empty implementation of one method in one class, and another implementation in another class and the code will become inconsistent in the long run, making it unsafe.. consider this
interface iSample {
void doThing1();
void doThing2();
void doThing3();
}
class sClass1 implements iSample {
void doThing1() { //doThing1 code }
void doThing2() { //doThing2 code }
void doThing3() { } // empty implementation
}
class sClass2 implements iSample {
void doThing1() { //doThing1 code }
void doThing2() { } // empty implementation
void doThing3() { //doThing2 code }
}
class Test {
public static void main (String[] args) {
testing(new sClass1());
testing(new sClass2());
}
public void testing(iSample s) {
// you would have no idea here which object has omitted which method.
s.doThing1();
s.doThing2();
s.doThing3();
}
as stated above you would have no idea which object has omitted which method and inconsistency prevails.
Well, based on your description, you would have empty methods inside both of your classes because you won't need them. class A would leave getK and setK unimplemented, and class B would do the same with getZ and setZ.
In this case it might be best to use a parent class that has x and y, and leave the implementation of z and k local to class A and class B, respectively.
Highly similar classes?
This sounds like a really good time to design for inheritance. Note that designing for inheritance should be a really deliberate decision ... because there's a right way to do it which will make your API a joy to use and a wrong way which can make your API a hassle to use.
You can also use an interface-based type system as you are suggesting. This has the advantage of being applicable to classes that may not otherwise be related.
Or you can do both.
I suggest that you capture the essence of the relationship in your classes and describe that as the contract for your interface-based type system.
Then, I suggest that you produce a skeletal implementation of your contract in an abstract skeletal implementation class. Your concrete classes can inherit from your skeletal implementation and, if done well, will inherit much of the behavior and state that describes the essence of your contract.
Note that you should use your interface as the type designation for all your objects, much like we do with the Java Collections API. It is not encouraged to declare a parameter type as void myFunc(HashMap m); the best practice is to declare void myFunc(Map m). In the latter case, Map represents the interface-based type system for all the different implementors of the Map contract.