Here is the problem I want to use a constructor that will simplify image loading process. All you neeed to do is specifty a file path.
Would it be possible to do this via inheritance or do i need to create a new buffered image object?
here is the idea for the code to make it easier to understand.
public class specialImage extends BufferedImage {
specialImage(String path) {
super();
this = ImageIO.read(new File(Path)); // <--- how can i Do this in java.
}
}
OR SHOULD I DO THE FOLLOWING
class specialImage{
BufferedImage manipulator;
specialImage (String path) {
manpiulator = ImageIO.read(new File(path));
}
}
————————EDIT 1:————————-
I am trying to avoid returning. I want to create a series of functions that will manipulate the specialImage class. like
specialImage objectName = new specialImage(FILE_PATH);
objectName.toGrayscale();
objectName.specialTransformation();
//While still using the BufferedImage class, i.e.,
objectName.getRaster();
There is a general answer to your question, and a specific one. Pragmatically, we should cover the specific one first.
You should do something along the lines of this.
Unless you know that your subclass will share the same “behavior” as the parent class, avoid sub-classing. By putting the
BufferedImageinto your class as a field, you are using a technique called “Composition” and in general, when in doubt, favor composition over inheritance.Inheritance works best when the classes follow the Liskov Substitution Principle, or in near-English terms, when they both have the same “behavior” but modified implementations of that “behavior”. For example,
BufferedImages andVolatileImages both behave exactly likejava.awt.Images, but one does so with an accessible buffer, and the other doesn’t guarantee buffer accessibility (or even buffer existence).The more general answer to your question follows.
Objects are modeled as instances of “things”, where the “things” are modeled with a template called aClass. Construction is the process of creating a new “thing” form it’s template, or in Object Oriented terminology, creating anObjectfrom it’sClass.With this understanding, you can see that constructing a “thing” to an existing “thing” is awkward English at best, and a near-nonsense statement at worst. What you probably meant was one of
If you want a second copy of an Object, you need to provide a “copy constructor”, which is a general term for a constructor that returns a second, equivalent, copy of the first “thing”.
You create a new name, and assign it to an old name. The old name will (under the covers) yield a reference which will become the new value of the new name. References are mostly hidden, as all operations on names automatically “dereference”.
To have two parts of the code reference the same “thing”, you do not need to use a constructor, as it would create two things. Instead you use two different “names” or “references”. References in Java are sort of like pointers in other languages, except that they are restricted in a number of interesting ways.
They do not refer to real memory locations. This allows garbage collection to compact memory without the burden of rewriting an unknown number of references. Memory compaction involves moving the data storage of an object from one starting address to another starting address, and by using a “memory reference id” instead of an actual address, the only physical address that needs changed is the one in the “memory reference id” to “physical address” table (this table cannot be reached from a user-written program).
They cannot be assigned arbitrary locations. The named reference has a declared type, and the Object to be assigned has a declared type. The strong type checking of the compiler and run time environment guarantee that only compatible types can be assigned to a named reference. As such, it is not possible to cast an arbitrary object to be referenced by a non-compatible named reference.
Math operations are forbidden, or more properly, math operations are not implemented. This last constraint prevents offsetting a named reference in such that it might reference a different object with a possibly different non-compatible type.
With these items in mind, your original plan will work nicely; the real question is how you will achieve those goals. If your “GrayScale” image is the same thing as your non-GrayScale image, then using the same class (with a
toGrayScale()method) is a good design choice. If your “GrayScale” image is a different thing than your non-GrayScale image, then havingtoGrayScale()return a second image is a good design choice.Where Object Oriented programming starts to fall apart is when you don’t make these design choices. You see your Object as a “memory pad” and you avoid creating new objects and discarding old objects in preference for maintaining a particular “memory pad”. Unless you are modeling memory pads, this is not object oriented design, and as such, you will be fighting your object oriented environment every step of the way to the solution that will get you your desired output.
Good luck with you efforts.