I have interface:
interface operations{
void sum();
}
and I want to have classes:
class matrix implements operations {
#override
void sum(matrix m) {
}
}
class vector3D implements operations {
#override
void sum(vecor3D v) {
}
}
How to do this?
I tried something like this:
interface operations < T > {
<T> void sum(T t);
}
class matrix implements operations<matrix>{
#Override
void sum(matrix m){};
}
}
class vector3D implements operations<vector3D>{
#Override
void sum(vector3D v){};
}
but it doesn't work.
Don't add a type parameters to the interface and the type. Also you should specify the generic parameters of the interface you implement:
interface operations<T> {
void sum(T t);
}
class matrix implements operations<matrix> {
#Override
public void sum(matrix m){
}
}
class vector3D implements operations<vecor3D> {
#Override
public void sum(vecor3D v){
}
}
Related
I have the following classes.
interface interface1() {
void function1()
}
interface interface2 extends interface1() {
void function2()
}
class implementation1 implements interface1 () {
#Override
void function1() {
// Implement
}
}
class implementation2 implements interface2 () {
#Override
void function1() {
// Implement
}
#Override
void function2() {
// Implement
}
}
class Main() {
List<interface1> interfaceList = new ArrayList();
for (interface : interfaceList) {
if (interface instanceOf(interface2)) {
interface.function2();
}
}
}
Could you please tell if there is a way to prevent using instanceOf? I read visitor pattern could be used but I am not getting the exact changes to be done.
Following are the classes after discussing with Alex R below (instanceOf is avoided since it is not recommended, visitor pattern is avoided since it still leads to empty visit functions). Please let me know if this can be done better using other design patterns.
interface interface1() {
void function1();
boolean isFunction2Applicable();
default void function2() {
}
}
class implementation1 implements interface1 () {
#Override
void function1() {
// Implement
}
#Override
boolean isFunction2Applicable() {
return false;
}
}
class implementation2 implements interface1 () {
#Override
void function1() {
// Implement
}
#Override
boolean isFunction2Applicable() {
return true;
}
#Override
void function2() {
// Implement
}
}
class Main() {
List<interface1> interfaceList = new ArrayList();
for (interface : interfaceList) {
if (interface.isFunction2Applicable()) {
interface.function2();
}
}
}
One way to do so is to define some method in the base interface and override it in the sub-interfaces or implementations. In the following example I'm using a default method but you don't have to do so; the method can be abstract and only be implemented in the implementations:
interface I1 {
void function1();
default void execute() {
function1();
}
}
interface I2 extends I1 {
void function2();
#Override
default void execute() {
function1();
function2();
}
}
public static void main(String[] args) {
List<I1> ifaces = new ArrayList<>();
for (I1 iface : ifaces) {
iface.execute();
}
}
public abstract class CommonClass {
abstract void send(<what should i put here???>) {}
}
public class ClassA extends CommonClass {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass {
void send(List<Post> postList) {
// do stuff
}
}
I am new to OODP, I am trying to have a method that is able to take in any kind of List data so that I can abstract things out. How can i do this?
You could make it generic on some type T. Like,
public abstract class CommonClass<T> {
abstract void send(List<T> al);
}
And then, to implement it - use the generic. Like,
public class ClassA extends CommonClass<Comments> {
#Override
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
Also, as discussed in the comments, your class names could be improved to be more intuitive; something like,
public abstract class AbstractSender<T> {
abstract void send(List<T> al);
}
and then
public class CommentSender extends AbstractSender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender extends AbstractSender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
That has the advantage(s) of being more readable and easier to reason about (I can tell what a PostSender does by reading the name, ClassB not so much).
Finally, this looks like a case where an interface would work since your abstract class is purely virtual (and should be preferred since you can implement multiple interface, but can only extend from a single parent class);
public interface ISender<T> {
void send(List<T> al);
}
public class CommentSender implements ISender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender implements ISender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
In order to achieve this, you can take multiple approaches, I would suggest looking into Generics: https://docs.oracle.com/javase/tutorial/java/generics/index.html
With that said, there is one approach that is the most elegant and simple: you can supply a List<T> where T is a generic type.
public abstract class CommonClass<T> {
abstract void send(List<T>) {}
}
public class ClassA extends CommonClass<Comment> {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
void send(List<Post> postList) {
// do stuff
}
}
You can do that with the help of generics. https://www.tutorialspoint.com/java/java_generics.htm
Example
The abstract class
public abstract class CommonClass {
public abstract <T> void send(List<T> data);
}
Its child
public class Child extends CommonClass {
public <T> void send(List<T> data) {
// code here
}
}
Retrieving the list's contents
Retrieving the generified list's contents is similar to retrieving any list's contents. In the scope of the method, "T" is a type of object contained in the list.
for (T t : data) {
// to check if t is a string
if (t instanceof String) {
// code
}
}
You can also use lambdas to retrieve every element in the list.
Whats the recommended design approach/alternative to the situation below:
BaseCalculator:
BaseType prepareData()
useData(BaseType)
Derived calculators use derived type to override base functionality -
DerivedCalculator1:
BaseType prepareData(){ return DerivedType1}
useData(BaseType t1){ DerivedType1 t=(DerivedType1)t1 //typecast down and proceed....}
DerivedCalculator2
BaseType prepareData(){ return DerivedType2}
useData(BaseType t1){ DerivedType2 t=(DerivedType2)t1 //typecast down and proceed....}
Is there a design approach to avoid typecasting by the derived classes - as it always leaves the gate open for a run-time mishap?
One alternative is to move the polymorphic behavior into the implementations of the BaseType rather than in the implementations of BaseCalculator. For example:
public interface BaseType {
public void process(Calculator calc);
}
public class DerivedType1 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 1
}
}
public class DerivedType2 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 2
}
}
public class Calculator {
public void doSomething(BaseType bt) {
bt.process(this);
}
}
If that type of solution is insufficient, a more complex solution is the Visitor Pattern. The Visitor Pattern allows any arbitrary BaseType object to be handled by any arbitrary BaseCalculator using double-dispatch. The catch is that all BaseCalculator implementations must have an method to handle each of the BaseType implementations. For example:
public interface BaseType {
public void process(Calculator calc);
}
public class DerivedType1 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 1
}
}
public class DerivedType2 implements BaseType {
#Override
public void process(Calculator calc) {
// Do something specific to derived type 2
}
}
public interface BaseCalculator {
public void handle(DerivedType1 dt);
public void handle(DerivedType2 dt);
}
public class DerviedCalculator1 implements BaseCalculator {
#Override
public void handle(DerivedType1 dt) {
dt.process(this);
}
#Override
public void handle(DerivedType2 dt) {
dt.process(this);
}
}
public class DerviedCalculator2 implements BaseCalculator {
#Override
public void handle(DerivedType1 dt) {
dt.process(this);
}
#Override
public void handle(DerivedType2 dt) {
dt.process(this);
}
}
I have the following situation:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(DerivedA deriv);
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new DerivedA.Something() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
I want to push usefulMethod and Something upto the Base class so that DerivedB can leverage it. And I want implementations of Something.doSomething to be able to use a derived type, so that it can access derived functionality.
How do I do that?
Attempts
I've tried the following:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(Base deriv);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
but that fails as my anonymous Something doesn't implement doSomething(Base). So trying to use generics:
I tried:
interface Something {
void doSomething(<? extends Base> deriv);
}
but that won't compile due to: "Wildcards may be used only as reference parameters"
I tried:
interface Something {
<T extends Base> void doSomething(T deriv);
}
but that requires me to implement the interface as so:
a.usefulMethod(new Base.Something() {
#Override
public <T extends Base> void doSomething(T deriv) {
}
});
which obviously doesn't allow me access to the derived type?
There are ways I can make it "work" but they're undesirable:
This:
interface Something {
void doSomething(Base deriv);
}
a.usefulMethod(new Base.Something() {
#Override
public void doSomething(Base deriv) {
DerivedA a1 = (DerivedA) deriv;
a1.DerivedBMethodA();
}
});
But that requires me to cast in each implementation, which seems wasteful.
And this:
package com.miurasample.ui.info;
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something<T extends Base> {
void doSomething(T deriv);
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something<DerivedA>() {
#Override
public void doSomething(DerivedA deriv) {
}
});
}
}
but that results in a warning/IDE highlight in usefulMethod of:
"Unchecked call to doSomething(T) as a member of raw type Base.Something"
What's the tersest and "cleanest" way to do this? Is that I'm doing even sane?
It is difficult to say if your design is wrong or not. We dont have full scope of your requirements to assert that, but here is clean non cast approach to what you are trying to do. It does require extra method in your derived classes:
public static void main(String... args) {
DerivedA a = new DerivedA();
a.usefulMethod( new Base.Something<DerivedA>() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
} );
}
public abstract static class Base< T extends Base<T> > {
int data = 0;
protected abstract T getThis();
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something<T> something) {
something.doSomething( getThis() );
}
interface Something< T extends Base<T> > {
void doSomething(T deriv);
}
}
public static class DerivedA extends Base<DerivedA> {
protected DerivedA getThis(){
return this;
}
void DerivedBMethodA() {}
}
public static class DerivedB extends Base<DerivedB> {
protected DerivedB getThis(){
return this;
}
void DerivedMethodB() {}
}
I have the following GameObject interface:
public interface GameObject {
void viewDetails();
}
Character Interface:
interface Character{
void pickUp(Weapon weapon);
void use(Weapon weapon);
}
and abstract Weapon class:
public abstract class Weapon implements GameObject {
//left out constructor to focus on methods
#Override
public abstract void viewDetails();
public abstract void attack(Enemy enemyObj);
//Could be bullets, could be a mystical item.
public abstract void replenish(ReplenishItem rpItem);
}
The problem with this is, a GameObject sometimes can be used in different ways.
For example, the primary use of a game weapon is to attack a target, but what if I wanted to reload? How do I let my character interface reload or beware that reload is an option?
I would use the following approach.
I would declare interfaces:
interface MeleeWeapon {
void hit();
void cut();
}
interface FirearmWeapon {
void fire();
void reload();
}
interface MagicWeapon {
void throw();
void apply();
void recharge();
}
Then implement classes, like these:
class Knife implements MeleeWeapon {
public void hit() {
}
public void cut() {
}
}
class Dagger implements MeleeWeapon {
public void hit() {
}
public void cut() {
}
}
class GarandRifle implements FirearmWeapon {
public void fire() {
}
public void reload() {
}
}
class Fireball implements MagicWeapon {
public void throw() {
}
public void apply() {
}
public void recharge() {
}
}
Then, I would declare these interfaces:
interface MeleeWeaponUser {
void use(MeleeWeapon weapon);
}
interface FirearmWeaponUser {
void use(FirearmWeapon weapon);
}
interface MagicWeaponUser {
void use(MagicWeapon weapon);
}
And, I would declare character classes:
class Peasant implements MeleeWeaponUser {
public void use(MeleeWeapon weapon) {
}
}
class Marine implements MeleeWeaponUser, FirearmWeaponUser {
public void use(FirearmWeapon weapon) {
}
public void use(MeleeWeapon weapon) {
}
}
class Sorcerer implements MeleeWeaponUser, MagicWeaponUser {
public void use(MeleeWeapon weapon) {
}
public void use(MagicWeapon weapon) {
}
}
This approach let us add new weapons and characters without sufficient effort later.
In your use() method you can call reload() if there is no more ammo in the weapon dispenser.
But if your game character receives signal from outside, for example, reload the gun, even there is enough ammo to fire, then have an Event->Listener approach implemented.
Create a WeaponEvent class, extend this class to have FirearmWeaponEvent, MeleeWeaponEvent etc.
Make your game character class(es) as a listener to WeaponEvent events, then in your game character class have a method processEvent(WeaponEvent event), and act accordingly to the event you have received.