I have a parent class with methods for writing and reading it from the db. The problem is I have a static method which I want to generalise. What is the best practice for doing this? I've came up with some solutions but all don't work with the static method.
Is there a way to force the childobject to implement the abstract method?
Parent Class:
public class Data_object {
public byte[] toByteArray() throws IOException {
return null;
}
public static Data_object fromByteArray(byte[] data){
return null
}
}
Child class:
public class ModelObject extends Data_object {
public static Data_object fromByteArray(byte[] data){
ModelObject result = new ModelObject();
//set data from byte arrray
return result;
}
}
thanks
A static method in Java can't be abstract and you can't override it. So you can't force a subclass to implement a certain static method.
The only way out is to require the static method by convention (like a note in the accompagnying JavaDoc) and using reflection to ensure at runtime (or at build time), that the subclass implements the required static method.
BTW - this is a common "pattern". Serializable does not define any methods, but it's documentation mentions three methods:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;
The "object serialization framework" now uses reflection to test, if those methods are implemented by a class and, if yes, invokes those methods.
But I recommend looking for other solutions before using this strategy.
Static methods can't be overridden. You can only hide superclass methods by defining a method with same name and signature in the subclass, but it's quite confusing and therefore generally not recommended. The original superclass method could be still accessed by, for example, ((SuperClassName) subClassInstance).staticMethod().
In your case it's probably better to make the method non-static.
Inheritance does not apply to static methods that way. You call a static method on a specific class, like this:
MonkeyModelObject.fromByteArray(data)
Even when you do this from "inside" a class, you're behind-the-scenes still invoking that specific method on that specific class. So if you "override" a static method, you're just making a new method with the same name in another class (the child class). There's no run-time selection of methods for static methods.
For the specific case that you're working on, it seems like you're doing serialization from/to byte arrays. Perhaps you're serializing messages from a network stream, or something like that? I would recommend the following approach, maybe this pseudocode can inspire you:
abstract class Message
{
void write(stream)
{
stream.write(getMessageTypeCode());
writeParameters(stream);
}
abstract int getMessageTypeCode();
abstract void writeParameters(stream);
abstract void readParamters(stream);
}
class ChatMessage
{
String text;
int getMessageTypeCode() { return 1; }
void writeParameters(stream)
{
stream.write(text);
}
void readParameters(stream)
{
text = stream.read();
}
}
class MessageDecoder
{
Message decode(stream)
{
int type = stream.read();
message = createMessage(type);
message.readParameters(stream);
return message;
}
Message createMessage(int type)
{
if (type == 1)
{
return new ChatMessage();
}
throw new error;
}
}
Related
I have the following code, which does not work as intended.
When I call the Chumbles constructor with Grumbo as type it calls every time the static method of the Schlami interface instead of the method of Grumbo.
What am I missing here? and what workaround, and I am pretty sure I need one, should I implement?
Thanks in advance!
p.s.: I feel already sorry for my naming convention
EDIT: my intention:
I have several classes that all need to be converted to JSON and from JSON back into a class.
additional to that I have a wrapper class for each of them that holds an array list of the classtype and can convert that list back and forth to JSON.
so I tried to build an generic class that I can reuse to minify code. my attempt was to implement an interface that guarantees the existence of both methods and to call them in that generic class. but this seems not to work.
in know that the object cast doesn't work. that function should never be called anyway
public class main {
public static void main(String[] args){
Chumbles<Grumbo> schleem = new Chumbles<>("test");
System.out.println("pause");
}
}
public class Chumbles<T extends Schlami> {
public Chumbles(String s){
T fleeb = T.fromJSON(s);
System.out.println(fleeb.toJSON());
}
}
public class Grumbo implements Schlami {
String s;
public Grumbo(String s) {
this.s = s;
}
#Override
public String toJSON() {
return "GrumboJSON";
}
public static Grumbo fromJSON(String s) {
return new Grumbo("Grumbo Success ");
}
}
public interface Schlami {
String toJSON();
static <T> T fromJSON(String json){
return (T) new Object();
}
}
EDIT2: so I use now a combination of generic factoryclasses and non static call of fromJSON. it feels gross to use new Grumbo().fromJSON(json) but I'll use it till I find a better workaround. thanks everyone for helping.
So, your question is why at "T.fromJSON(s);" the method from Schlami instead of the method from Grumbo is called?
Since T extends Schlami, Schlami is always the class referenced when calling static methods.
Please note, that you cannot override static methods!
I would suggest just calling the method by "Grumbo.fromJSON();". If you need to override the method, you could turn Schlami in an abstract class, override the method in Grumbo and call it from object-context.
I have the following
public abstract class MyData
{
private String sID;
public void setsID(String sID) {
this.sID= sID;
}
public String getsID() {
return sID;
}
}
This base class is being extended by 2 other classes
public class DataTypeOne extends MyData
{
private String sName;
public void setsName(String sName) {
this.sName= sName;
}
public String getsName() {
return sName;
}
}
public class DataTypeTwo extends MyData
{
private String sSummary;
public void setsSummary(String sSummary) {
this.sSummary= sSummary;
}
public String getsSummary() {
return sSummary;
}
}
I am initializing this class as follows
MyData oDataOne = new DataTypeOne();
MyData oDataTwo = new DataTypeTwo();
Reason for that is that I have a factory method which shall give me the class based on type (One or two)
With oDataOne & oDataTwo, I am able to access getsID() from the base class but not the getters & setters of the respective class.
How can I access those? I
You can't access a method that doesn't exist. All you've promised your Java compiler is that oDataOne and oDataTwo are MyData objects. Since the MyData class doesn't have the implementation-specific methods, you cannot ask Java to call those methods (since it doesn't think they exist).
If you want to access those methods, you need to either cast the object to a class that actually has the right methods, or you can add abstract method stubs to your base class, which will tell Java that those methods actually exist.
Type casting is simpler to write in the short term, but less clear, and you may run into more trouble down the road:
((DataTypeOne) oDataOne).getsName();
((DataTypeTwo) oDataOne).getsSummary(); // Throws ClassCastException!
Adding abstract stubs is more robust, but may not make sense if not all concrete subclasses should implement all abstract methods:
public abstract class MyData {
public abstract void setsName(String name);
public abstract String getsName();
public abstract void setsSummary(String summary);
public abstract String getsSummary();
}
public class DataTypeOne extends MyData {
public String getsName() {
// implement
}
public void setsName(String name) {
// implement
}
// Still have to implement these!!!
public String getsSummary() {
// raise an exception or something if appropriate
}
public void setsSummary(String summary) {
// raise an exception or something if appropriate
}
}
// Same for DataTypeTwo
Since you declared the variable as a MyData, you can only access the methods of MyData. You can get to the subclass methods by casting it to DataTypeOne or DataTypeTwo:
((DataTypeOne)oDataOne).getsName()
But you need to be sure it is of type DataTypeOne or you will get a ClassCastException
MyData oDataOne = new DataTypeOne();
this says, that your oDataOne object is of the type MyData. Even if it is created as a DataTypeOne, java can only be sure that it is defiantly a MyData instance.
If you are sure that the MyData instance is in reality also a DataTypeOne instance, you can cast and then access the DataTypeOne methods + the MyData methods.
To make sure that an object is of a specific type test:
if(oDataOne instanceOf DataTypeOne){
((DataTypeOne) oDataOne).getsName(); // this will return the Name if oDataOne is really of the type DataTypeOne
}
An object of type MyData has no knowledge of whether any other classes extends it or not, so there is no way to access members of those classes.
You will have to cast your object to the specific type to access the specific members.
If you find yourself in this situation, you can be pretty sure that your design is flawed. If you need to perform a specific action for each type of MyData extension, add a method, e.g specialAction() to the interface and hide the specifics in there. That eliminates the entire need to find out which subclass you are dealing with.
I have an abstract class type that I'm inheriting from to create new classes. As an equivalent example, consider:
public abstract class BaseClass {
public BaseClass(String input)
{
...
}
public abstract void doSomething();
public String getResult()
{
...
}
}
Now I can override BaseClass and implement "doSomething" to perform different actions (for example, reverse or capitalize, if I were really working with strings, though I'm not really, it's just an example).
The most common usage is:
BaseClass bc = new ExtendsBaseClass(input);
bc.doSomething();
String result = bc.getResult()
So I want to make a static wrapper method for this.
I'd like to implement:
public static String doSomethingForResult(String input)
{
BaseClass bc = /*new current type*/;
bc.doSomething();
return bc.getResult();
}
But I have no idea what to replace that comment with, or how to make it work; I don't want to force every implementing class to re-implement this (if that's even conceptually possible; since abstract static is not allowed.
Static methods are not polymorphic, and thus can't be inherited and overridden. What you want to do is impossible.
Why do you bother with static things in this case?
Just benefit from polymorphism and merge doSomething() and getResult().
You would end up with:
public abstract class BaseClass {
public BaseClass(String input)
{
...
}
public abstract String doSomething();
}
and your client would look like:
BaseClass bc = new ExtendsBaseClass(input);
String result = bc.doSomething();
In generally, defining a separated getResult() method would make sense in specific cases like in implementing Builder Pattern. Indeed, several distinct methods participate to the object construction and end up with a call to a kind of getResult() method.
---------------------After your comment just below------------------------
If, as you said, the common case was to use doSomething() follows by getResult() and depending on a specific subclass, you could use Template Method pattern:
public abstract class BaseClass {
public BaseClass(String input)
{
// assigments
}
public String process(){ //process is a template method
doSomething();
return getResult();
}
protected abstract void doSomething();
protected abstract String getResult();
}
public class ExtendedClass extends BaseClass {
protected void doSomething(){
//...
}
protected String getResult(){
//....
}
}
Your client would only call process() method:
BaseClass bc = new ExtendsBaseClass(input);
String result = bc.process();
But please :), avoid static things when possible, they aren't lead to a good OO programming.
So I want to make a static wrapper method for this.
I think I see why you might want to do this. You want a simple method to perform a common set of operations without having keep copying the boilerplate code again and again. But as you are painfully aware by now, static methods have no place in an inheritance hierarchy. I would recommend you get inspiration from the various Apache Commons projects and their XxxUtils classes which are composed solely of static methods and exist completely outside of the hierarchy of the classes they act on.
Consider the class FileUtils in Commons IO. It's just static methods but they are so helpful. Consider two methods:
static byte[] readFileToByteArray(File file) // Reads the contents of a file into a byte array.
static String readFileToString(File file) // Reads the contents of a file into a String
One methods deals with files and byte arrays, the other deals with files and strings? How do you know which does what - because it uses a descriptive name which spells it out. The are no inheritance, implementation, polymorphism issues because FileUtils exists completely outside the inheritance hierarchy of Files, Strings, byte arrays etc.
Let's get back to your hypothetical method. I would put this method in a separate class named MyUtils - or BitmapUtils and create a method for every combination of concrete classes that was meaningful.
public static String doSomethingWithExtendsBaseClass(String input)
{
BaseClass bc = new ExtendsBaseClass();
bc.doSomething();
return bc.getResult();
}
public static String doSomethingWithOtherClass(String input)
{
BaseClass bc = new OtherClass();
bc.doSomething();
return bc.getResult();
}
But I have no idea what to replace that comment with, or how to make it work
Simple - you just instantiate the concrete class directly in the method with the corresponding name.
I think you can define a static method in BaseClass and pass the other class as argument to it using BaseClass as argument class e.g.
public static String doSomethingForResult(String input ,BaseClass bc){
bc.doSomething();
return bc.getResult();
}
Then in your ExtendedBaseClass you may write as:
ExtendedBaseClass extendedBaseObject= new ExtendedBaseClass();
String result = BaseClass.doSomethingForResult("input", extendedBaseObject);
System.out.println(result);
As you may know, some people are declaring singletons with an Enum of 1 instance, because the JVM guarantees that there will always be a single instance with no concurrency problems to handle...
Thus what about an Enum with multiple instances?
Can we say something like an Enum is a kind of ordered set of singletons sharing a common interface?
Why?
public enum EnumPriceType {
WITH_TAXES {
#Override
public float getPrice(float input) {
return input*1.20f;
}
public String getFormattedPrice(float input) {
return input*1.20f + " €";
}
},
WITHOUT_TAXES {
#Override
public float getPrice(float input) {
return input;
}
},
;
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
In this code why this doesn't work:
WITH_TAXES.getFormattedPrice(33f);
What is the interest of declaring a public method if it can't be called without passing through the common interface?
I guess this is why i don't see any syntax to be able to declare an interface just for one of the instances of an Enum.
Edit:
It seems that enum instances are a special kind of anonymous classes.
Thus i understand why you can't call that method.
My question is kinda related to: why can't an anonymous class implement an interface (in addition to the interface it may already implement!)
I totally understand why we CANT do that:
Vehicle veh = new Vehicle() {
public String getName() {
return "toto";
}
};
veh.getName();
(getName here is not an override)
Why i don't understand is why we can't do that with anonymous classes:
Runnable veh = new Vehicle() implements Runnable {
#Override
public void run() {
System.out.println("i run!");
}
};
veh.run();
Or something that would result in the same thing.
Think about it: if you do not use anonymous classes you can absolutely extend the Vehicle class and then make that subclass implement any other interfaces you want...
I'm pretty sure that if it was possible we would be able to call WITH_TAXES.getFormattedPrice(33f) in a typesafe way, since WITH_TAXES would not be a real EnumPriceType but it would but a subclass of EnumPriceType, with its own interface, and by calling WITH_TAXES.getFormattedPrice(33f) with a hardcoded WITH_TAXES, you know at compile that which EnumPriceType child you are calling.
So my question is: are there any reasons why this is not possible? Or it just haven't be done yet?
Your enum is equivalent to the following normal class (in fact, that's pretty much what the compiler turns it into):
public abstract class EnumPriceType {
public static final EnumPriceType WITH_TAXES = new EnumPriceType() {
//getPrice() {...}
//getFormattedPrice() {...}
};
public static final EnumPriceType WITHOUT_TAXES = new EnumPriceType() {
//getPrice() {...}
};
public abstract float getPrice(float input);
public static void main(String[] args) {
WITH_TAXES.getFormattedPrice(33f);
}
}
The getFormattedPrice() method is unavailable on the abstract type, and therefore can't be called from the main method. Consider what would happen if the main method is rewritten to use a local variable:
public static void main(String[] args) {
EnumPriceType foo = EnumPriceType.WITH_TAXES;
foo.getFormattedPrice(33f);
}
This doesn't compile because getFormattedPrice() is not available on the base class. Since the WITH_TAXES instance is an anonymous subclass of EnumPriceType, there's no way you can define the local variable to a type where the getFormattedPrice() method is visible.
As a meta observation, this is a key difference between strongly typed languages such as Java and "duck typed" languages such as Ruby. Ruby will happily invoke the getFormattedPrice() method if happens to be there, regardless of what type of object is held in the foo variable.
As another meta observation, it doesn't make much sense for different constants of the same enum to have different sets methods. If you can't put everything you need as abstract (or concrete) methods on the base enum type, you're probably using the wrong tool to solve the problem.
Add
public String getFormattedPrice(float input) {
return input + " €";
}
outside the overrides as the default implementation. (Next to the declaration of getPrice.) And you are good to go.
You can also have enums implement interfaces, to define what everybody needs to implement.
Thus what about an Enum with multiple instances?
There is no such thing, and your example doesn't demonstrate it. You have an Enum with multiple values. They are all singletons.
I know it is not a good coding practice to declare a method as private in an abstract class. Even though we cannot create an instance of an abstract class, why is the private access modifier available within an abstract class, and what is the scope of it within an abstract class? In which scenario is the private access specifier used in an abstract class?
check out this code where Vehicle class is abstract and Car extends Vehicle.
package com.vehicle;
abstract class Vehicle {
// What is the scope of the private access modifier within an abstract class, even though method below cannot be accessed??
private void onLights(){
System.out.println("Switch on Lights");
}
public void startEngine(){
System.out.println("Start Engine");
}
}
Within is the same package creating a Car class
package com.vehicle;
/*
* Car class extends the abstract class Vehicle
*/
public class Car extends Vehicle {
public static void main(String args[]){
Car c = new Car();
c.startEngine();
// Only startEngine() can be accessed
}
}
Since an abstract class can contain functionality (as opposed to an interface) it can have private variables or methods.
In your example you might do something like
public void startEngine(){
injectFuel();
igniteSpark();
// etc. my understanding of engines is limited at best
System.out.println("Start Engine");
}
private void injectFuel() {}
private void igniteSpark() {}
That way you can spread some of the work to other methods (so you don't have a 1000 line startEngine method), but you don't want the children to be able to call injectFuel separately since it doesn't make sense outside the context of startEngine (you want to make sure it's only used there).
Or even more you might have a private method that gets called in several other public methods, with different parameters. This way you avoid writing the same code twice or more in each of the public methods, and grouping the common code in a private method makes sure the children don't access it (like they couldn't just call part of the public method before). Something like this:
public void startEngine() {
dishargeBattery(50);
System.out.println("Start Engine");
}
public void startRadio() {
dischargeBattery(20);
}
private void dischargeBattery(int value) {
battery.energy -= value; //battery should probably be a private field.
}
This way your methods can have access to the battery, but the children shouldn't mess with it, and you don't write the same line (battery.energy -= value) in both of them. Take note though, that these are very simple examples, but if dischargeBattery was a 500 line method, writing it in both the other methods would be a hassle.
It's the same as in a non-abstract class, there's no difference.
Which means that if nothing in your abstract class calls the private method, then you can just as well remove it, as it won't be called (baring some evil reflection work).
Usually, private methods are only used as internal utility methods that have a very specific task that the other methods in the class use to do their work.
I know it is not a good coding
practice to declare a method as
private in an abstract class.
I don't. Where did you get that idea?
what is the scope of it within an abstract class?
The abstract class.
The method can be accessed only from within the abstract class. For example, you could have an abstract class with a public final method that makes use of a private helper method.
package arrayafter;
public abstract class Abstract_Demo {
abstract void display();
private void display1() {
System.out.println("Private Method");
}
final void display2() {
System.out.println("final Method");
display1();
}
public static void display3() {
System.out.println("Static methods");
}
}
package arrayafter;
import java.util.Scanner;
public class Practice extends Abstract_Demo{
public static void main(String[] args) {
Practice pr=new Practice();
pr.display();
pr.display2();
Abstract_Demo.display3();
}
#Override
void display() {
// TODO Auto-generated method stub
System.out.println("Abstract method");
}
}