I have a set of operations. Every operation is a sequence of 2 steps. So, I have a base class which executes these two steps and all the operations extend this base class and provide the actual implementations for the two steps. Ex.
class Base {
Step1 step1;
Step2 step2;
B execute() {
A a = step1.perform();
B b = step2.perform(a);
}
//Set methods...
}
Here Step1 and Step2 are interfaces and one can change the implementations for them to do different things.
I have the following questions:
Every implementation of step2 takes instance of A as input which can also contain a derived type of A. So I need to do a downcast. Is it ok to do a downcast in this case or is there a better way to achieve this?
Some implementations of step2 may not return any value. Is it ok if we have an empty class just for the type hierarchy and other classes extend this class?
Question 1
Yes, that is ok. Every class which extends the class A or implements the interface A (what ever A is) will be "an instance of A". So it is perfectly OK to pass it to a method which needs an object of the type A. Nothing to worry about. This is how you should use interface and inheritance. There are different kind of "specializations" of the same super-class.
Question 2
This is a question of your API design. If you want that this method could return null, you can do this. But you should document it very good!
A very new possibility in Java 8 are so called Optionals. You can use them if a method could return null and you want to force the programmer to keep that in mind. That would be the cleanest (and recommended) way. You can find an example and a description at http://java.dzone.com/articles/optional-java-8-cheat-sheet. Basically you would say that your method perform of the class Step2 will return an Optional instead of the type:
interface Setp2 {
public Optional<B> perform(A a);
}
// the optional will wrap the actual result which could be null
// since Java 8
Optional<B> b = step2.perform(a);
It sounds like you should use generics:
interface Step1<T extends A> {
T perform(T a);
}
interface Step2<T extends A, U extends B> {
U perform(T a);
}
class Base<T extends A, U extends B>>{
Step1<T> step1;
Step2<T, U> step2;
B execute() {
T a = step1.perform();
U b = step2.perform(a);
}
//Set methods...
}
Regarding returning "nothing", the best way is to return null.
Related
I've seen a number of similar questions, but I don't think any were quite isomorphic, and none quite answered my question.
Suppose there are two interfaces, Tree and Named. Suppose further that I am given a method whose signature is
public <T extends Tree & Named> T getNamedTree();
How can I save the returned value to a variable, while still retaining the information that it implements both Tree and Named? I can't find a way of declaring a variable like
public <T extends Tree & Named> T mNamedTree;
and trying to cast it to an interface extending Tree and Named results in a class cast exception.
Assuming there is no third interface inheriting both Named and Tree, you cannot retain information about both interfaces statically. The compiler will require you to do a cast for one or the other, or for both:
Object namedTree = getNamedTree();
Tree asTree = (Tree)namedTree;
Named asNamed = (Named)namedTree;
Both casts should succeed.
If you have influence on the design of the API for the class, ask the authors to introduce an interface combining both Named and Tree, and returning an instance of that interface instead.
One possible solution would be to create another interface that extends both Tree and Named, and simply store that as the variable:
interface NamedTree extends Tree, Named {
}
public NamedTree namedTree;
public NamedTree getNamedTree();
What scope does the variable has to have?
There is three possibilities here.
A) the variable is just a local variable. In that case you nearly have already the answer... you just need to declare a type-parameter for the enclosing method for that type:
interface ItfA { Number propA(); };
interface ItfB { Number propB(); };
class Main {
private <T extends ItfA & ItfB> T getT() {
return null;
}
private <TT extends ItfA & ItfB> void doStuffWithT() {
TT theT = getT();
System.err.println(theT.propA());
System.err.println(theT.propB());
}
}
B) The scope is the live of an object and in that case is a member field.
The obvious answer is to make the class generic and the type-parameter would
have the same & constraint:
interface ItfA { Number propA(); };
interface ItfB { Number propB(); };
class Main<T extends ItfA & ItfB> {
T theT;
public void setT(T newT) {
theT = newT;
}
public void doStuffWithT() {
System.err.println(theT.propA());
System.err.println(theT.propB());
}
}
C) The scope is the live of the program, then the variable is a static class member. Here you don't have a generics solution.
C.1) Obviously if the class of the values that you are going to handle is known you would just use that class as the field type.
C.2) If not, you could constraint the code to handle only classes that implement an interface that extends ItfA and ItfB. That interface, say ItfAB. Would be to field type.
C.3) Now, what about not imposing that constraint? What about allow the code to handle objects from any class that implement those interfaces?
Unfortunately there is no a clean-cut solution to that:
C.3.a) You could either type the field Object and provide methods to access it as an ItfA or as a ItfB (basically hiding the casting).
C.3.b) Or, instead of holding directly a reference to the object, you use a proxy object that implements those interfaces and delegates calls to those interfaces methods to the original "T" typed value. The class for that proxy could itself be a generic accepting an arbitrary <T extends ItfA & ItfB> value (similar to the B. example above).
Pre information.
public abstract class Person {}
public class A extends Person{}
public class B extends Person{}
public class C extends Person{}
public X getPersonByType(String type){
//This Method will return either A or B or C based on type
//what should X be ?
}
I need to create a method which takes in a String and returns an object which is a subtype of Person.
More Information.
Each of the classes A B C have an attribute public List roles. These cannot be moved upto the Person class as I require these uniquely named for (JPA many to many table).
Now If possible, i would not like it to return person as I would not be able to access the roles attribute (Person does not know about it). I would also prefer a solution (if possible) which does not require me to cast or use instanceOf (again if possible).
P.S tried <? extends Person> but Eclipse gave me error "return type of method is missing"
public Person getPersonByType(String type) should work fine because all your return types extend Person.
You can also add an additional class parameter if you want to avoid instanceof checks after calling this method:
public <T extends Person> T getPersonByType(String type, Class<T> type) {
...
// cast result to T
}
Using this way you would be able to assign the return type to a subclass directly:
C c = getPersonByType("c", C.class);
Be aware that this can cause ClassCastExceptions if you pass in a String and a Class parameter that don't match each other.
You should return Person X. As Person is an abstract type it can't be instantiated. You can have Person X as a reference that should point to an object of any of the concrete implementation of Person which are A B & C in your case. This is the beauty of run time polymorphism. Based on your input at the run time it would create an object of any of the A, B or C class and use reference X to point to that object.I would suggest you go through Factory Design Pattern which will give you more information about how this type of design works in real life scenario.
X should be Person.
since Person is an abstract class and can't be instantiated it will always return one of your subtypes.
If you need to know what getPersonByType returned from your calling method, you can use the instanceof operator
public Person getPersonByType(String type){
// analyze type and return appropriate instance...
if ("A instance".equals(type)) {
return new A();
}
...
}
If I have two classes, A and B,
public class A {
public int test() {
return 1;
}
}
public class B extends A{
public int test() {
return 2;
}
}
If I do: A a1 = new B(), then a1.test() returns 2 instead of 1 as desired.
Is this just a quirk of Java, or is there some reason for this behavior?
This is called polymorphism. At runtime the correct method will be called according to the "real" type of a1, which is B in this case.
As wikipedia puts it nicely:
The primary usage of polymorphism in industry (object-oriented
programming theory) is the ability of objects belonging to different
types to respond to method, field, or property calls of the same name,
each one according to an appropriate type-specific behavior. The
programmer (and the program) does not have to know the exact type of
the object in advance, and so the exact behavior is determined at
run-time (this is called late binding or dynamic binding).
No, that is correct (it is due to polymorphism). All method calls operate on object, not reference type.
Here your object is of type B, so test method of class B will be called.
This is polymorphism and more specifically in Java overriding. If you want to invoke Class A's test method from Class B then you need to use super to invoke the super classes method. e.g:
public class B extends A{
public int test() {
return super.test();
}
This is intended behavior. The method test() in class B is overriding the method test() of class A.
For
A a1 = new B();
a1 is pointing towards the object of B which is the real type at run-time. Hence value is printed from Object B.
A obj = new A();
obj.test()
will return 1
A obj = new B();
obj.test()
will return 2
B obj = new B();
obj.test()
will return 2
As stated in other answers this is how polymorphism works.
This post may make things a bit clearer
Java uses dynamic binding (or late binding), so the method of B is called, not A. This is the opposite of static binding. There is a nice example here.
You declare your object as A but your instance is B. So the method which will be called is from class B. B extends A(we can say that A is parent for B) if you will comment method test in B and then recall this method, in this case the method invoked will be test from A class and will return 1.
What is the best use of Inheritance, other than it will reduce redundant code!
Let us take an example
Class A:Base Class
Class B:Sub Class
and Class C.
CLASS A
^
| And CLASS C
|
|
CLASS B
i can use methods from Class A, in Class B by inheritance.
in the same i can use the methods from Class A, in Class C, by creating instance of Class A.(say A is Public)
using inheritance, only reduce creating new Object/Instance?
Plz help me to better understand!
A great benefit is polymorphism. If classes B and C both inherit from A, then whenever an object of type A is required, it can be replaced by either an object of type B or an object of type C. Assuming the corresponding methods are overriden in B and C, this is very handy to get different behavior depending on which object you pass.
Example:
class A {
public void foo() { System.out.println("A"); }
}
class B extends A {
public void foo() { System.out.println("B"); }
}
class C extends A {
public void foo() { System.out.println("C"); }
}
Then:
public static void printMessage(A obj) {
obj.foo();
}
public static void main(String[] args) {
A b = new B();
printMessage(b); // prints 'B'
A c = new C();
printMessage(c); // prints 'C'
}
The main point of inheritance is polymorphism: to allow other classes to use an instance of ClassB knowing only that it can be used as a ClassA.
My favourite example is streams - I could easily write a copyStream method taking an InputStream and an OutputStream for example, using only the methods declared on those types. Then I could copy a FileInputStream to a ByteArrayOutputStream, or use network-related streams etc, all without changing any of the code in the copyStream method.
The main reason to use inheritance is not to remove redundant code.
Inheritance and all magic made possible is a key, central point in OOP. Extending a class doesn't only allow you to use its functionality, but also modify (by polimorphism) and add more functionality.
The difference comes with the need to understand the ability to pass class B into functions that act on class A. In this sense B is-a type of A where class C has or owns A. The difference is small and only significant in certain circumstance.
That is not to say that the difference is often made explicit in code tbh. Often people will inherit when they really want ownership and sometimes they do ownership when an object really is-a type of something else.
I have an interface with several method definitions, and I would not like to require some of them.
Is this possible? if so, how can i implement this?
I have tried setting an annotation of #Optional but this doesn't seem to work.
Do i have to define the Optional annotation somewhere?
There is no #Optional annotation in Java. One thing you can do is to create an interface, and then create an abstract class that provides stub implementations. Your classes can then extend this base class and override the methods they are interested in.
You can have an Abstract class that implements this interface with empty function implementations and then extend from the Abstract class
Having said that, I would question why you need to do this. Maybe you need to split you interface into multiple smaller ones and implement the only ones that you need for a class
Although I agree with the other answers, one should note that such optional methods exist in the JDK. For example, List.add() is optional. Implementations must throw an UnsupportedOperationException if they don't want to implement this method.
If you want to be able to know if the optional method is implemented or not, then you could add another method (not optional) :
/**
* Returns true if optionalOperation() is supported and implemented, false otherwise
*/
boolean isOptionalOperationSupported();
/**
* implements he foobar operation. Optional. If not supported, this method must throw
* UnsupportedOperationException, and isOptionalOperationSupported() must return false.
*/
void optionalOperation();
"Conceptually, what good is an interface if you cannot rely on the contract it provides" said Erik.
That's true but there is an other consideration: One can expect objects of different classes conforming to some properties or methods included in an interface to securely process with them by testing which properties or methods are implemented.
This approach can be frequently meet under Objective-C or Swift Cocoa for which the “protocol” — equiv of “interface” — allows to defined as “optional” a property or a method.
Instance of objects can be tested to check if they conform to a dedicated protocol.
// Objective C
[instance conformsToProtocol:#protocol(ProtocolName)] => BOOL
// Swift (uses an optional chaining to check the conformance and the “if-let” mech)
if let ref: PrototocolName? = instance => nil or instance of ProtocolName
The implementation of a method (including getter and setter) can be checked.
// Objective C
[instance respondsToSelector:#selector(MethodName)] => BOOL
// Swift (uses an optional chaining to check the implementation)
if let result = instance?.method…
The principle allows to use methods depending on their implementation in unknown objects but conforming to protocol.
// Objective C: example
if ([self.delegate respondsToSelector:#selector(methodA:)]) {
res = [self.delegate methodA:param];
} else if ([self.delegate respondsToSelector:#selector(methodB)]) {
res = [self.delegate methodB];
} …
// Swift: example
if let val = self.delegate?.methodA?(param) {
res = val
} else if let val = self.delegate?.methodB {
res = val
} …
JAVA does not allow to make “optional” an item in an interface but it allows to do something very similar thanks to interface extension
interface ProtocolBase {}
interface PBMethodA extends ProtocolBase {
type methodA(type Param);
}
interface PBMethodB extends ProtocolBase {
type methodB();
}
// Classes can then implement one or the other.
class Class1 implement PBMethodA {
type methodA(type Param) {
…
}
}
class Class2 implement PBMethodB {
type methodB() {
…
}
}
Then instances can be tested as “instance of” both ProtocolBase in order to see if object conform to the “general protocol” and to one of the “subclassed protocols” to execute selectively the right method.
While delegate is instance of Class1 or Class2 it appears to be instance of ProtocolBase and either instance of PBMethodA or PBMethodB. So
if (delegate instance of PBMethodA) {
res = ((PBMethodA) delegate).methodA(param);
} else if (dataSource instanceof PBMethodB) {
res = ((PBMethodB) delegate).methodB();
}
Hope this helps!