Using Generic/Parameterized java with multiple classes - java

I am attempting to create a generic/parameterized code to call from multiple classes I have. I will code it so I have several classes that have methods of the same name, so I'm hoping to create a generic way to call them.
Say I have 3 different classes that will all have methods that are called getAmount() that return ints and toString() methods that return Strings
Then I want a generic class that could possibly reference any of those three.
public class Stuff<Project> {
private Project p;
public Stuff(Project aProject) {
this.p = aProject;
}
public int getValue() {
return p.getAmount();
}
public String toString() {
return p.toString();
}
Is there anything in java that would get this functionality for me, or am i thinking in C?
I've tried using Object.getClass() in various ways to attempt to cast things, and several of the other Generic programming related questions on this site and the docs.oracle site don't seem to have what I'm looking for. Is this not possible because of the way type erasure works?

Don't use generics here, use interfaces. In Java, you use interfaces to tell the compiler that a class implements certain methods, without telling it how these methods are implemented.
public interface Project {
int getAmount();
}
public class Stuff {
private Project p;
public Stuff(Project aProject) {
this.p = aProject;
}
public int getValue() {
return p.getAmount();
}
}
You can pass an instance of any class to Stuff's constructor, as long as it implements the Project interface:
public class Construction implements Project {
public int getAmount() {
// implementation
}
}
...
Stuff s = new Stuff(new Construction());

You can use an interface, an abstract class or reflection. I would avoid using reflection unless you really need it. This looks like the perfect job for an interface.
public interface Ammount {
public int getAmmount();
}
public class BankAccount implements Ammount {
#Override
public int getAmmount() {
return -10; // broke
}
}
public class PiggyBank implements Ammount {
#Override
public int getAmmount() {
return 12; // rich
}
}
You can then use some code like
BankAccount myBankAccount = new BankAccount();
Ammount ammount = myBankAccount;
ammount.getAmmount();
PiggyBank myPiggyBank = new PiggyBank();
Ammount ammount = myPiggyBank;
ammount.getAmmount();

Related

Injecting code into a method that is overridden (Java)

I have this:
public class Superclass {
public int getMaxLevel() {
return 1;
}
}
public class Subclass extends Superclass {
public int getMaxLevel() {
return 4;
}
}
and I need it to be this:
public class Superclass {
public int getMaxLevel() {
return 3; //injected
//return 1; //original
}
}
public class Subclass extends Superclass {
public int getMaxLevel() {
return 3; //injected
//return 4; //original
}
}
Both superclass and subclass are in a library. Also, due to my use-case being a Minecraft mod, I aim at compatibility, so it needs to be done in the superclass, not the subclass.
I would prefer answers that use Java only (require no external libraries).
Edit: Modding framework used is Forge 1.16.5, and I do not have access to all subclasses (so there may be additional classes extending Superclass), which is why the injection needs to be performed in Superclass.
You don't mention the modding toolchain you're using, but if it's Fabric or Forge 1.16.5 the Mixin bytecode weaving framework will let you do what you're looking for. Read more about Mixin on the fabric wiki.
#Mixin(Superclass.class)
public class SuperclassMixin {
#Inject(method = "getMaxLevel", at = #At("RETURN"), cancellable = true)
public int getMaxLevelReturnInject(CallbackInfoReturnable<Integer> ci) {
ci.setReturnValue(3);
}
}
and repeat for Subclass.

Partial implementation of interface

I have an Inreface say
public interface myInterfacy {
String kilogramToGram();
Long litresTomiliLitres();
String inchesToMillimeters();
String ouncesToGrams();
}
I need to have multiple implementaton of this interface but I want the partial implementation of this inteface on different implementation,
As:
public class A implements myInterfacy {
public String kilogramToGram(){
//code
};
I don't want to give the definition of other methods.
}
public class B implements myInterfacy {
Long litresTomiliLitres(){
//code
};
I don't want to give the definition of other methods.
}
I thought that I can di it via using an abstract class, but I wonder If any other good approach is possible.
The answer is relatively simple but has many options.
You could
Make a number of partial interfaces and the one that "does it all" implements them all (not great)
You could make a number of "dummy" interfaces which throw an exception of unimplemented functionality. So, every proxy class would implement the full interface but throw runtime errors on unsupported methods (also not great)
Simply do nothing - literally. Implement the full interface and provide empty bodies (also really not great)
Or, you could encapsulate the functionality with a specific proxy to provide the given functionality.For example,
class FullyFunctional {
public void foo() {...}
public void bar() {...}
}
class PartiallyFunctional {
FullyFunctional ff;
public PartiallyFunctional(FullyFunctional ff) {
this.ff = ff;
}
// No foo...
public void bar() { ff.bar(); }
}
One way to do this, is with a convenience base class. This is however not really a good idea, because you won't get compile type checking to help ensure that you don't call unimplemented method.
public interface Converter {
public String kilogramToGram();
public long litresTomiliLitres();
public String inchesToMillimeters();
public String ouncesToGrams();
}
public abstract class AbstractConverter implements Converter {
#Override
public String kilogramToGram() {
throw new UnsupportedOperationException();
}
#Override
public long litresTomiliLitres() {
throw new UnsupportedOperationException();
}
#Override
public String inchesToMillimeters() {
throw new UnsupportedOperationException();
}
#Override
public String ouncesToGrams() {
throw new UnsupportedOperationException();
}
}
public final class A extends AbstractConverter {
#Override
public String kilogramToGram() {
//code
}
}
Follow interface-segregation-principle
Divide fat interface into granular small interfaces
Implement only require interface
One extreme case: I will declare four interfaces for four methods
public interface IKGToGram {
String kilogramToGram();
}
public interface ILitersToMilliLeters{
Long litresTomiliLitres();
}
public interface IInchesToMilliMeters{
String inchesToMillimeters();
}
public interface IOunceToGrams{
String ouncesToGrams();
}
Now you can implement whatever interface set you want to.
Have a look at explanation about interface segregation concept:
Interface Segregation Principle- Program to an interface

Java interface classes?

So, I am trying to learn how the interface classes in Java Work, and i'm really confused about it.
I wan't to make it like a method in a normal class file like this:
public class APIClass {
private int davs;
public int setInt(int dav) {
this.davs = dav;
return davs;
}
public int getInt() {
return davs;
}
}
Two methods. One that set's the int "davs", and one getting the int "davs".
What i wan't to do in the interface is something like that. I have seen in others interface files, that they have something like this:
public interface MyInterface {
public MyInterface setInt(int davs);
public MyInterface getInt();
}
EDIT:
My question is that i can't see what i can use the interface for? All i have seen use it, declare the same method in a new class file, and then they really don't need the interface file. So what is it for?
Interfaces in Java are meant as an abstraction. You're expected to use it strictly for deriving other classes. You don't declare any methods in it all.
So if you have an interface like this:
public interface MyInterface {
int setInt(int davs); // this should probably return void
int getInt();
}
And you implement it in a class like this:
public class APIClass implements MyInterface {
private int da;
public int setInt(int davs) {
// return da; <- this doesn't make a whole lot of sense
da = davs; // I assume you meant this
return da; // usually you don't return anything from a setter
}
public int getInt() {
return dada;
}
}
And another class like this:
public class SecondAPIClass implements MyInterface {
private int dada = 0;
public int setInt(int davs) { // note that you have to keep the same method signiture in all derived classes
dada = davs + 5;
return dada;
}
public int getInt() {
return da;
}
}
You can use the interface to group them both. This is an important part of object oriented design. It's usefulness is probably too long to explain in a simple StackOverflow question, but here's a simple example of its usefullness:
import java.util.ArrayList;
public static void main(String[] args)
{
APIClass first = new APIClass();
SecondAPIClass second = new SecondAPIClass();
first.setInt(20);
second.setInt(20);
ArrayList<MyInterface> list = new ArrayList<MyInterface>();
list.add(first);
list.add(second);
for(MyInterface item : list) {
System.out.println(item.getInt());
}
}
The output should be this:
20
25
This example might be more helpful:
Consider you have several vehicles. All vehicles can drive, but driving a boat is different from driving a car, or a helicopter. This is where interfaces are useful. You can declare what a Vehicle should do, without dictating how it should do it.
public interface Vehicle {
void drive();
}
So when you derive it in a class Car, you can state how you want this vehicle to drive.
public class Car implements Vehicle {
void drive() {
// drive like a car
}
}
Now boats are vehicles, and they can drive too, but driving a boat is much different than driving a car.
public class Boat implements Vehicle {
public void drive() {
// drive like a boat
}
}
In summary, interfaces are useful when you have an abstract concept in mind, where you know what derived objects should do but can't dictate how they do it.

Avoiding code duplication with Java abstract methods

I have a class (let's say Vehicle) with a rather large number of subclasses (Car, Bike, ..). Every subclass stores specific information on the type of the subclass (# of tires, ..).
I want to ensure that all this information is already enforced (at compile-time).
So I don't want to specify this data in the constructor of the subclass (because I might forget to set some of them). I could put this info in the constructor of Vehicle, but this would clutter code quite a lot, since I have many of those parameters.
public class Vehicle {
int numberOfTires;
public Vehicle(int numberOfTires, ...) {
...
}
}
public class Bike {
public Bike() {
super(2,...);
...
}
}
I end up with completely unreadable constructors. It would also store this info per instance, even though it is specific to the subclass.
An alternative way is to introduce abstract static getters/setters and store the info in the subclasses.
public class Vehicle {
...
abstract public int getNumberOfTires();
}
public class Bike {
static int numberofTires = 2;
...
public int getNumberOfTires() {
return numberOfTires;
}
}
This seems way cleaner and also stores the info per subclass and not per instance but there will be a lot of code duplication in the subclasses. Right now, all the subclasses contain ~20 setters/getters but virtually no real functionality. Is there a clean way of avoiding this? Perhaps using the Factory method or alike?
In your shoes, I'd do it this way
public abstract class Vehicle {
public abstract int getNumberOfTires();
}
and
public class Bike extends Vehicle {
#Override
public int getNumberOfTires() {
return 2;
}
}
and
public class Car extends Vehicle {
#Override
public int getNumberOfTires() {
return 4;
}
}
You should put in your Vehicule class everything that is common. If the number of tires is a common attribute of all your Vehicule, than it belongs there.
Using the factory pattern you could avoid having to write each time you want a instance of a Bike all that is needed in the Vehicule class as the factory would do that. Meaning the code that sets the parameters of a Bike is written in one place, the BikeFactory class.
That would make the line creating a Bike looks like
Bike yourBike = BikeFactory.getInstance().create();
instead of
Bike yourBike = new Bike(numberOfTires, ... );
The factory would have either a line that looks like the above one or a bunch of calls to setters. I would recommend you use setters and just a new Bike() constructor without parameter.
The naming of the factory, methods and the factory being a singleton are only as example and can be implemented as you see fit in your application.
As mentionned, you could also use another class for the parameters but that only move the hassle of settings your parameters somewhere else.
Seems to me that what you are talking about here are constants, e.g. values that are not supposed to change at runtime. In Java, constants are variables with the following qualifiers: static final, along with private/public. Then, you won't need setters, since a Bike will never anything other than 2 wheels for instance.
I don't really see the problem with having lots of getters and setters, your Bike-class has a set of properties describing it, and they are all needed. So something like:
public abstract class Vehicle {
public abstract int numberOfTires();
public abstract boolean hasEngine();
}
public class Bike extends Vehicle {
private static final int NUMBER_OF_TIRES = 2;
private static final boolean HAS_ENGINE = false;
public int numberOfTires() {
return NUMBER_OF_TIRES;
}
public boolean hasEngine() {
return HAS_ENGINE;
}
}
These variables are properties of the entity that you are representing, and as per object-oriented principles, they belong as members of the class.
All domain classes will have a number of variables, and in most cases they will require at least a getter, there is no way around this. Still, it is good to keep your domain classes as small as possible, not necessarily with regards to lines of code, concepts it represents. If a domain class has grown large, decompose it and group variables that belong together is separate classes. Then each of the smaller classes will have a constructor with a limited amount of variables, and instance creation
If all that matters in limiting the amount of code in your subclasses you could do something like the code below. I'm not sure if I would recommend it though, and I don't think I'd do this in practice.
public abstract class VehicleInfo {
public abstract int numberOfWheels();
}
public class BikeInfo extends VehicleInfo {
#Override
public int numberOfWheels() {
return 2;
}
}
public class CarInfo extends VehicleInfo {
#Override
public int numberOfWheels() {
return 4;
}
}
public class Vehicle {
final VehicleInfo info;
Vehicle(final VehicleInfo info) {
this.info = info;
}
public int numberOfWheels() {
return info.numberOfWheels();
}
}
public class Bike extends Vehicle {
public Bike() {
super(new BikeInfo());
}
}
public class Car extends Vehicle {
public Car() {
super(new CarInfo());
}
}
This way all getters are located in the superclass (as well as in the info-classes), and the subclasses can stay clean.

Extending Java Enums

I have a question regarding the best design pattern for code reuse when dealing with Java enums. Basically, what I'm trying to achieve is being able to define several enums that model static business collections (sets of constants), but I'd also like to share behavior between them, with minimal coding.
This is trivial to achieve with class inheritance from abstract classes but, since Java enums cannot be extended (they can only implement interfaces), this type of work is tedious and involves a lot of error prone copy/paste work (copying the code from enum to enum). Examples of "business logic" that should be shared among all enums includes converting from/to Strings, instance and logical comparison, etc.
My best shot right now is using helper classes in conjunction with business interfaces, but this only goes so far in reducing code complexity (as all enums still have to declare and invoke the helper classes). See example (just to clarify):
public enum MyEnum {
A, B, C;
// Just about any method fits the description - equals() is a mere example
public boolean equals(MyEnum that) {
ObjectUtils.equals(this, that);
}
}
How do StackOverflowers deal with this "language feature"?
You can move the reusable logic to dedicated (non-enum) classes and then have the enums delegate to those classes. Here's an example:
[Side note: the inheritance of PlusTwo extends PlusOne is not recommended (b/c PlusTwo is not PlusOne). It here just to illustrate the point of being able to extend an existing logic.]
public interface Logic {
public int calc(int n);
}
public static class PlusOne implements Logic {
public int calc(int n) { return n + 1; }
}
public static class PlusTwo extends PlusOne {
#Override
public int calc(int n) { return super.calc(n) + 1; }
}
public static enum X {
X1, X2;
public Logic logic;
public int doSomething() {
return logic.calc(10);
}
}
public static enum Y {
Y1, Y2;
public Logic logic;
public String doSomethingElse() {
return "Your result is '" + logic.calc(10) + "'";
}
}
public static void main(String[] args) {
// One time setup of your logic:
X.X1.logic = new PlusOne();
X.X2.logic = new PlusTwo();
Y.Y1.logic = new PlusOne();
Y.Y2.logic = new PlusTwo();
System.out.println(X.X1.doSomething());
System.out.println(X.X2.doSomething());
System.out.println(Y.Y1.doSomethingElse());
System.out.println(Y.Y2.doSomethingElse());
}
I would do the same, or combine the Enums into a super-enum.
With Java 8 this will be easier. You will be able to define a default implementation for interface methods and have the enum extend the interface.
I rarely find enums useful, except for representing finite states in which case they do not need behavior.
I would suggest refactoring enums that need behavior into classes with a Factory.
This might look a bit ugly, but generally can offer you the required functionality.
You can have interface
public interface MyEnumInterface<T extends Enum<T>> {
String getBusinessName();
T getEnum();
}
Implementation
public enum OneOfMyEnums implements MyEnumInterface<OneOfMyEnums>{
X, Y, Z;
#Override
public String getBusinessName() {
return "[OneOfMyEnums]" + name();
}
#Override
public OneOfMyEnums getEnum() {
return this;
}
}
And utility class instead of your parent class
public class MyEnumUtils {
public static <T extends Enum<T>> String doSomething(MyEnumInterface<T> e){
e.getBusinessName(); // can use MyEnumInterface methods
e.getEnum().name(); // can use Enum methods as well
return null;
}
}

Categories

Resources