I would like to know why in Java I can do this
interface Specification{
double Interest =12.5;
void deposit(double);
}
class Base{
private String Account;
public Base(String acct){Account=acct;}
public void Show(){System.out.print("Account # "+Account);}
}
class Child extends Base implements Specification{
public Child (String acct){super(acct);Show();}
public void deposit(double cash){System.out.print("Now you have "+cash+" Dollars");}
}
but I can't do this
class Child implements Specification extends Base{
public Child (String acct){super(acct);Show();}
public void deposit(double cash){System.out.print("Now you have "+cash+" Dollars");}
}
Is there any specific order in Java or rule when using extends and implements in the same class.
I would like somebody to explain me the reasons please.
Because the Java Language Specification says so. A normal class declaration follows this syntax
NormalClassDeclaration:
ClassModifiers(opt) class Identifier TypeParameters(opt)
Super(opt) Interfaces(opt) ClassBody
where Super is
Super:
extends ClassType
and Interfaces is
Interfaces:
implements InterfaceTypeList
In my opinion, this makes sense. You want to define what something is before defining what it can do.
Yes in java there is specific order first class in extended then you can implement many classes :
class Child extends Base implements Specification1,Specification2.. -> valid
&
class Child implements Specification1,Specification2.. extends Base -> not valid
Related
I have a class A that inherit Middle, which inherit OriginBase
public abstract class Base<T>
public class OriginBase<T extends CustomObject> extends Base<T>
public class Middle<T extends CustomObject> extends OriginBase<T>
public class A extends Middle<ObjectA>
public class B extends Middle<ObjectB>
public class C extends Middle<ObjectC>
Due to new feature and refactor of class A, I got a new version of class OriginBase, NewBase, which is similar to OriginBase and only have a few more methods. The problem is that not only class A inherit Middle, so I cannot simply change Middle's superclass to NewBase.
For now, my solution is to create a new class NewMiddle extends NewBase, add corresponding new override methods, and then make class A extends NewMiddle. But this will cause hundreds of lines of code duplication.
To avoid such redundant duplication, I have thought about generics inherit.
The idea is to let class A, B, C specify the Base class they needed, such as:
public abstract class Base<T>
public class OriginBase<T extends CustomObject> extends Base<T>
public class NewBase<T extends CustomObject> extends Base<T>
public abstract class CommonBase<B extends Base>
// I'm not sure is this a good idea, even not sure if it's a right concept...
public class NewMiddle<B extends Base<T extends CustomObject>, T> extends CommonBase<B, T>
// modified class
public class A extends Middle<NewBase<ObjectA>>
// other classes
public class B extends Middle<OriginBase<ObjectB>>
public class C extends Middle<OriginBase<ObjectC>>
How to achieve this kind of inheritance? Is this a good idea to do so?
I have a base abstract class PipelineStage which has the following definition:
public abstract class PipelineStage<I, O> implements Runnable {
...
public abstract O step(I input);
...
}
I then have numerous concrete pipeline stages with definitions such as:
public class ConcreteStage extends PipelineStage<InputContextClass, OutputContextClass> {
...
#Override
public OutputContextClass step(InputContextClass input) {
input.someMethod();
...
return new OutputContextClass();
}
...
}
However, this has led to a rigid design in which either:
The context classes are very tightly coupled to which stages they are used in.
Every stage needs to have two full interfaces defined, defining all the properties of the input and output classes.
I wanted to improve this design by having generic interfaces that specify properties of the context classes, the ConcreteStage would then specify what interfaces it's input and output context classes must extend.
However, I can't figure out how to do this in a way the compiler likes.
For example:
public class ConcreteStage extends PipelineStage<I extends Interface1 & Interface2,
O extends Interface2 & Interface3> {
...
#Override
public O step(I input) {
input.someMethodFromInterface1();
input.someMethodFromInterface2();
...
// OutputContextClass extends Interface2 & Interface3
return new OutputContextClass();
}
...
}
However, this doesn't compile, showing that class I needs to be imported.
A wildcard also doesn't work, saying No wildcard expected.
Does anyone have any suggestions on how to implement this in a neat, flexible way? Many thanks in advance!
You need to put the type variable declarations on the class, not the superclass:
public static class ConcreteStage<
I extends Interface1 & Interface2, O extends Interface2 & Interface3>
extends PipelineStage<I, O> {
You can also make an interface uniting input interfaces together interface InputInterface12 extends InputInterface1, InputInterface2 {} and then class ConcreteStage extends PipelineStage<InputInterface12, OutputInterface12> {...}.
I have a couple of generic classes:
public interface Data<E> {}
public interface Clonable<E extends Clonable<E>> {}
public interface NaturalNumberInterface extends Data<NaturalNumberInterface> {}
public class NaturalNumber implements NaturalNumberInterface {}
public interface SetInterface<E extends Data<E>> extends Clonable<SetInterface<E>> {}
public class Set<E extends Data<E>> implements SetInterface<E> {}
When I'm trying to create the new instance of Set Set<NaturalNumber> s=new Set<NaturalNumber>(); compiler says:
NaturalNumber is not valid substitute for the type parameter <E extends Data<E>> of the type Set<E>
Maybe you can help me to find the mistake, cause I spent a long time and didn't find the solution.
I assume that your SetInterface is defined in the same way as ListInterface and Data is just interface Data<T>.
The generic argument of SetInterface is F-bounded: E extends Data<E>. In your current code NaturalNumber type extends Data<NaturalNumberInterface>. So if E is NaturalNumber, then condition is violated as it should extend more specific type Data<NaturalNumber>.
You should use F-bounds for NaturalNumberInterface as well:
public interface NaturalNumberInterface<T extends NaturalNumberInterface<T>> extends Data<T>
public class NaturalNumber implements NaturalNumberInterface<NaturalNumber>
This way it will work.
I have below classes and interfaces.
SuperInterface.java
public interface SuperInterface{/*some logic*/}
SubOneInterface.java
public interface SubOneInterface extends SuperInterface{/*some logic*/}
SubTwoInterface.java
public interface SubTwoInterface extends SuperInterface{/*some logic*/}
One.java
public class One{/*some logic*/}
Two.java
public class Two{/*some logic*/}
SubOne.java
public class SubOne extends One implements SubOneInterface{/*some logic*/}
AnotherSubOne.java
public class AnotherSubOne extends One implements SubTwoInterface{/*some logic*/}
SubTwo.java
public class SubTwo extends Two implements SubOneInterface{/*some logic*/}
AnotherSubTwo.java
public class AnotherSubTwo extends Two implements SubTwoInterface{/*some logic*/}
Now i have to write a class which will hold the implementation classes of both SubOneInterface and SubTwoInterface.
public class ClassesHolder{
private List<One> one;
private List<Two> two;
//setters and getters
}
Now ClassesHolder should accept all the objects(sub classes of One and Two) which implements either SubOneInterface or SubTwoInterface But not mix of both interfaces.
IF they try to populate the lists with mixed interface implementations then exception should be thrown.
How can i do that?
You can't easily exclude classes that implement a particular interface. If your contract requirement references SubOneInterface, then it'll accept classes that implement SubOneInterface, regardless of what else they implement.
Trying to do otherwise seems like a bad design. If your ClassesHolder contains a class implementing SubOneInterface, then that's how it will refer to that class, and any other functionality will be hidden, due to the additional interfaces not being referenced.
You could inspect your classes upon addition to th elist e.g.
public void addToListOfOnes(final SubOneInterface obj) {
if (obj instanceof SubTwoInterface) {
// throw an exception
}
}
but that seems very poor/counterintuitive. I would take a step back and look at your design again.
Have a look at my example below. If you could introduce another interface as the base type of your interfaces, this solution should work for your. Once instantiated, it will either except subtypes of One or subtypes of Two.
public class Example {
public static void main(String[] args) throws Exception {
ClassesHolder<One> ones = new ClassesHolder<One>();
ones.add(new SubOne());
ones.add(new SubSubOne());
}
}
interface Zero {}
interface One extends Zero {};
interface Two extends Zero {};
class SubOne implements One {};
class SubSubOne implements One {};
class SubTwo implements Two {};
class SubSubTwo implements Two {};
class ClassesHolder<V extends Zero> {
public <T extends V> void add(T item) {}
}
Using Class.isInterface() you can check if it belongs to a particular interface.
As per your requirement you want to check before adding to a list you are trying to check if a class is an Interface of SubOneInterface or SubTwoInterface But not mix of both interfaces.
Does that make sense?
I have a base abstract class public abstract class BaseModel <T extends BaseModel<T>>. Normally, I extend this class with something like public class OtherModel extends BaseModel<OtherModel>. For some of my classes, I want to have an intermediate abstract class, such that A extends B extends BaseModel.
I'd like to be able to declare public class EndModel extends MiddleModel<EndModel>. The only way I've managed to get Eclipse to be happy is if I declare MiddleModel as public abstract class MiddleModel<T extends BaseModel<T>> extends BaseModel<T>, but this seems ugly, and now I have to add a type anywhere I declare a variable as MiddleModel, even if I don't actually care what type it is. Is there a better way to do this?
If you want to add more functionality in MiddleModel, which depends on the generic type of it, declare it like this:
public abstract class BaseModel <T extends BaseModel<T>> {}
public abstract class MiddleModel <T extends MiddleModel<T>> extends BaseModel<T> {}
public class EndModel extends MiddleModel<EndModel> {}
Note that EndModel doesn't support that extensibility. It's a trade-off, because I don't want to write new EndModel<EndModel>() but rather new EndModel().