In Objective-C, I could do:
id<HTTPRequestDelegate> delegate;
to say that delegate (a variable of type id) conforms to the HTTPRequestDelegate protocol (or implements the HTTPRequestDelegate interface in Java speak).
That way, whenever I send a message defined by the HTTPRequestDelegate protocol to delegate, the compiler understands that delegate responds.
How do I do this, i.e., duck typing / dynamic typing, in Java?
Duck typing doesn't exist in Java. If a class implements an interface, it must declare that this interface is implemented. It isn't sufficient just to have methods with the same signature as the ones in the interface.
An interface is a type, though, and you may declare a variable of this type. For example:
List<String> myList;
declares a variable myList of type List<String>, where List is an interface.
You may initialize this variable with any object implementing this List interface:
myList = new ArrayList<String>();
But then ArrayList must declare that it implements the List interface (which it does).
//Static typing
HTTPRequestDelegate delegate;
Interface a = new Implementation();
Java has no concept of duck typing. You must cast the instance to a known type.
I'm assuming then that delegate doesn't explicitly implement the interface you want.
You could make a new class that implements the interface and extends the implementing class you want (or has the implementing class and explicitly calls the appropriate method in the interface).
If this isn't what you want, you might be in for a healthy dose of reflection. Take a look at java.lang.reflect.Proxy and InvocationHandler.
If you are looking for a shorthand to avoid explicitly implementing methods for an interface using composition, Java doesn't really provide syntactic support for this. You'll have to be explicit.
If you do want to go the reflection-heavy way (not recommended over extra typing), take a look at Mockito.
Most of the answers given already are correct. If an object implements an interface, then you can use that object anywhere an implementation of that interface is needed. This is the most natural approach given Java's strong typing system.
To keep with the example of List/ArrayList, you can create an ArrayList object and then use it anywhere a List is required -- or, based on the other implemented interfaces, Serializable, Cloneable, Iterable, Collection, or RandomAccess. Considering superclasses, an instance of ArrayList can be used as an AbstractList, AbstractCollection, or a java.lang.Object.
Reflection can be used, along with dynamic proxy objects, to wedge an object with the correct methods into a duck costume. That shifts the type checking to runtime, and there are usually far better reasons to work with the normal typing system than against it.
Because it sounded like fun, here an example of wrapping a non-Duck in a proxy object.
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DuckDemo {
public static Duck getDuckProxy(final Object duckLike) {
final InvocationHandler invocationHandler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?> actualClass = duckLike.getClass();
String methodName = method.getName();
Class[] parameterTypes = method.getParameterTypes();
Method requested = actualClass.getDeclaredMethod (methodName, parameterTypes);
return requested.invoke(duckLike, args);
}
};
final ClassLoader originalObjectClassLoader = duckLike.getClass().getClassLoader();
Duck woodenDuck = (Duck) Proxy.newProxyInstance(
originalObjectClassLoader,
new Class[] { Duck.class },
invocationHandler
);
return woodenDuck;
}
private interface Duck {
void quack();
};
public static void makeItQuack (Duck duck) {
duck.quack();
}
public static void main (String args[]) {
Object quacksLikeADuck = new Object() {
void quack() {
System.out.println ("Quack!");
}
};
// Does not compile -- makeItQuack(DuckDemo.Duck) [...] cannot be applied to (java.lang.Object)
// makeItQuack (quacksLikeADuck);
// Runtime java.lang.ClassCastException: [...] cannot be cast to GenericProxyFactory$Duck
// makeItQuack ((Duck)quacksLikeADuck);
Duck d = getDuckProxy(quacksLikeADuck);
makeItQuack (d);
}
}
For what it's worth, IBM developerWorks also has a good article on the topic of dynamic proxies.
In Objective-C, the type consists of two parts: 1) An class pointer type (e.g. NSObject *, NSString *, etc); this could also be id, which is a special type that can accept any object pointer and disables static type compiler warnings for calling methods; and 2) optionally, one or more protocols (which are like interfaces in Java) that the object conforms to (e.g. <NSCopying, NSCoding>)
In Java, a reference type is either a class or interface name. (You can only pick one.) There is not so much separation between classes and interfaces.
In your case, your object pointer type is id, which expresses no information, and you specified one interface, HTTPRequestDelegate. This can be equivalently expressed in Java as
HTTPRequestDelegate delegate;
If you had specified more than one protocol, or you specified an actual class pointer type plus one or more protocols, then your type is an "intersection type", the intersection of the multiple types you specified. In that case, it would be harder because there is no simple way of expressing intersection types in Java. (Although intersection types can be specified in generic type bounds, e.g. class Foo<T extends Collection & Comparable & CharSequence>)
Other than that, the only other difference between Objective-C and Java is that in Objective-C, you can send any message (i.e. call any method) on an object pointer and it is allowed, even if the static type of the variable does not indicate that it is supported (the compiler will give a warning if you use an actual class pointer type; if you use id it will not give a warning). I guess this is the dynamic typing you're talking about. Whereas in Java, you can only call methods that are known to be supported by the static type at compile time.
But if you're using a type like id<HTTPRequestDelegate>, then chances are that you only intend to use the methods provided by HTTPRequestDelegate anyway, so you are not using any of the dynamic typing abilities. So in Java just HTTPRequestDelegate will suffice.
I think there's a lot of terminology to unpack here. Java doesn't let you have a raw pointer, only a reference, which has a type.
Anyway, say you have a reference to an instance that you know implements HTTPRequestDelegate. You can cast it, like so:
HTTPRequestDelegate delegate = (HTTPRequestDelegate) ref;
The bit in the parentheses is the cast. You can now call methods on delegate (pass messages in java speak) to your hearts content as long as they are defined on HTTPRequestDelegate.
The other way Java programmers do duck typing type stuff is refection, but if you know the interface, casing is the way to go.
Related
The Java class Class<T> being Generic is confusing because of following reasons.
Imagine a class Cake<T>{}
So you can create
new Cake<Pineapple> and new Cake<Apple> etc
If each class e.x Apple has a parameterizable Class Object, and If class Class is generic, then it seems like a possibility to create Apple<Something> or Integer<Something>, which does not make any sense.
I dont know what i am perceiving wrongly here. It seems like inception, but a deeper level is the same level as above level.
Assume below generic Class
public class Cake<T> {
T cakeType;
void setCakeType(T cakeArg){
this.cakeType = cakeArg;
}
void doStuff(){
System.out.println(cakeType.toString());
}
}
Assume Pineapple is the non generic class as Parameter type for Cake
public class Pineapple {
#Override
public String toString() {
return "I am a Pineapple";
}
}
If class Class was not generic, then by intuition, there will be Pineapple Class object
But as class Class<T> itself is generic. Then it seems like a possibility to create parameterizable class object of Pineapple i.e Pineapple<Something>.
Base Assumption: There is only one Class Object for each class. What is the sense about parameterizing it ?
I'll try to tackle this from a few different approaches; I think there's a fundamental disconnect between what's happening, so a scattershot approach might have a better chance of one of the points making it all "click."
The hierarchy
So, firstly, don't think of Apple as having a Class object; rather, there is an Apple class, and, sitting next to it, a Class object which describes it. But that Class object just exists on its own, and is not part of Apple's hierarchy. It's not Apple's parent; it's its best friend.
The base class for all classes is Object, not Class. Now, if Object were parameterized, you'd have something along the lines of what you're describing -- but it's not. Since Class is not part of Apple's hierarchy, it does not logically follow that Class being parametrized makes Apple parameterized.
By analogy to other generic classes
The point of a Class object is to talk about other objects -- to tell us things like "this is a T," or "here's how you create a T." So, how does each instance tell us at compile-time which kind of things it's talking about? Via the parameter.
Similarly, the point of a List object is to talk about other objects -- to put them into a group together. And it also uses the generic parameter to describe the kinds of things it talks about. With a List, you can tell what's in it just by the type signature: a List<String> concerns Strings while a List<Integer> concerns Integers. Well, in just the same way, a Class<String> talks about Strings while a Class<Integer> talks about Integers. The fact that Class is parameterized has no more effect on String or Integer than does the fact that List is parameterized.
In other words: at the highest level, List<String> does things with Strings. So does a Class<String>
Some use cases
Finally, it may be helpful to think about why Class is parameterized. There are only a few methods on Class that return the T type. Let's take a look at two of them:
T newInstance()
T cast(Object o);
If Class were not parameterized, both of these would return Object. You'd have to do something like this:
Class<Apple> appleClass = ...;
Apple newApple = (Apple) appleClass.newInstance();
Apple existingApple = (Apple) appleClass.cast(existingObject);
Okay, as such that's not too bad. But in this case, we already knew the type of thing we were interested in (an Apple). That's why we could add the Apple casts, but by the same token, it's why using the Class<Apple> isn't useful. That snippet above would be better off just being done as:
Apple newApple = new Apple();
Apple existingApple = (Apple) existingObject;
Instead, the generic aspect of classes are most often useful when you're in a method that is itself generic. For instance:
<T> T tryConsume(Consumer<T> consumer, Object item, Class<T> consumeClass) {
T itemCasted = consumeClass.cast(item);
consumer.consume(itemCasted);
}
Granted, this example isn't very interesting. But the one thing I'll point out is that without the consumeClass, you would have to cast item to (T). Due to type erasure, this would actually be a no-op at runtime, and if the item were of the wrong class, the ClassCastException would come in from a weird, generated line within the consumer code -- not from within tryConsume, where it's nice and clear. To make that cast method actually do the cast, and do it usefully, you need consumeClass.cast(item) to return a T. And to do that, consumeClass has to be of type Class<T>.
In Objective-C it is possible to pass a function parameter with type in the form Object<Protocol> which has the meaning "an object of type Object that implements the protocol Protocol". I was wondering whether there is a way to do the same in Java, for instance "an Android View that implements some custom interface" (protocol = java interface).
You can use generics to specify that the parameter implements an interface:
public <T extends Protocol> void foo(T t) { ... }
This can be extended to specify multiple bounds. The type must be a subtype of all the specified types. Object isn't the best example, but here's how you could specify it:
public <T extends Object & Protocol> foo(T t) { ... }
Here's a related tutorial:
Oracle Docs - Bounded Type Parameters
Especially note this paragraph:
To declare a bounded type parameter, list the type parameter's name,
followed by the extends keyword, followed by its upper bound, which in
this example is Number. Note that, in this context, extends is used in
a general sense to mean either "extends" (as in classes) or
"implements" (as in interfaces).
The unexpected part here is that extends is used for interfaces as well.
Note that you can get the desired behaviour without generics as well (see comments below):
public void foo(Protocol p) { ... }
since this allows for any object that is-a Protocol. If you want to specify multiple interfaces with this approach you could for example create a third interface that implements the other two. However, this assumes that you're in control of the classes that should be able to be passed as arguments since you need to implement that interface.
If you're passing a "regular" generic type parameter you simply specify the type directly:
public void foo(Object<Protocol> o) {
// TODO: Implement
}
when you have a method, I understand that it makes sense to declare it generic so that i can take generic arguments. Like this:
public <T> void function(T element) {
// Some code...
}
But what exactly is the idea behind making a whole class generic if I can simply declare every method generic?
Well, the difference is if you try to make each method in your class generic the generic type you'd use in your say firstGenericMethod may or may not be the same type.What i mean is.
public <T> void firstGenMethod(...){
}
public <T> void secondGenMethod(...){
}
Test:
SomeClass ref = new SomeClass();
ref.firstGenMethod("string");
ref.secondGenMethod(123);//legal as this generic type is not related to the generic type which is used by firstGenMethod
In the above case there is no gaurentee that both the methods have the same generic type.It depends on how you invoke them. If you make the class generic though, the type is applied to all the methods inside that class.
class Test<T>{
public void firstGenMethod(T t){
}
public void secondGenMethod(T t){
}
}
Test:
Test<String> testingString = new Test<>();
testingString.firstGenMethod("abc");
testingString.firstGenMethod(123);// invalid as your Test class only expects String in this case
You'd usually make your class generic where you'd want the entire behaviour(methods) of that class to process on the same type. best examples are class's in Java Collection Framework
Have a look at the Collection classes. Take List<T> as an example. If the class weren't declared generic, how would you make sure that only elements of the correct class could be inserted into the list? And how would you know what you get when calling ArrayList.get(i)?
Precisely, to enfore that all the methods in this class apply to a certain type.
This is typically used in "containers" classes. If you're building a List, and you make it generic, you want to be sure that adding element, getting element, iterating, etc... always uses the same type.
As you mention, this also allows you to use instance variables of a certain type, and have several methods use this instance (maybe returning it, affect it...) in a coherent way.
If you have a class that is "generic" with several different types, it might be a sign that you're really writing two generic classes in one... (although this can be a legitimate thing.)
The main idea is to bound the class/method for a type.The best example is the concept of Generics in programming language.It is the real application of polymorphism
Generic classes encapsulate operations that are not specific to a particular data type. The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees and so on where operations such as adding and removing items from the collection are performed in much the same way regardless of the type of data being stored.
For most scenarios requiring collection classes, the recommended approach is to use the ones provided in the programming languages.
Reffering from oracle docs
A generic type is a generic class or interface that is parameterized over types
public class Box {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
By generically you can strict it to
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
I also suggest you to see this tutorial
I just saw a member function like this:
public Cat nextCat(GameState state);
But Cat is an interface like this:
public interface Cat {
void makeCat(GameState state);
}
So I am confused as to how to interpret this. I know what it means when something returns an object or a primitive. But what does it mean to return an interface? How to use this function's return value?
Think about this way: If Cat where a regular class, what exactly would you care about when you wanted to call some methods on it?
You'd care about the method definitions: their names, their argument types, their return values. You don't need to care about the actual implementation!
Since an interface provides all of that, you can call methods on it, just as you can on a regular class.
Of course, in order for the method to actually return some object, there needs to be some class that implements that interface somewhere. But what class that actually is or how it implements those methods doesn't really matter to the code that gets that object returned.
In other words, you can write code like this:
Cat cat = nextCat(GameState.STUFF);
cat.makeCat(GameState.OTHER_STUFF);
That code has no knowledge of the concrete type that implements the Cat interface, but it knows that the object can do everything that the Cat interface requires.
This function returns an object of a class which implements the Cat interface. The implementation details (for this concrete class) are up to you, as long as you implement all the methods of the Cat interface for it.
For example you could do this:
interface Cat {
String meeeeow();
}
public Cat nextCat(GameState state) {
return new Cat() {
public String meeeeow() {
return "meeeeeeeeeow!!!!";
}
};
}
in which case the method nextCat returns an implementation of the Cat interface by means of an 'anonymous-inner-class'. This shows that the code calling nextCat does not need to know which code implements the returned Cat interface. This is an example of one of the key strengths of Object-Oriented programming: because the calling code doesn't know the implementation, the impact of changing the implementation later on is small (as long as the interface remains the same).
This is one way of abstration, "Hiding Actual implementation", The Best Example is Map interface where if some API has return type as Map, then user actually don't need to care about the type of object implementation i.e. 'Hasmap for Hashtable', With the help of methods defined in Map interface, user can perform operation on the returned object because interface create a contract with the implementing classes that the "implemeting class must provide defination for declared method" otherwise declare that implementing class as abstract.
It is worth emphasizing once again that it is perfectly legal—and in fact very common—to have variables whose type is an interface, such as :
Measurable meas; //"Measurable" is an interface name.
Just remember that the object to which meas refers doesn’t have type Measurable. In
fact, no object has type Measurable. Instead, the type of the object is some class that
implements the Measurable interface. This might be an object of the BankAccount class or
Coin class, or some other class .
meas = new BankAccount(1000); // OK
meas = new Coin(0.1, "dime"); // OK
What can you do with an interface variable, given that you don’t know the class of
the object that it references?
You can invoke the methods of the interface:
double m = meas.getMeasure();
and also you should know that there can be type conversians between class and interface types.
It means, that the member function can return any implementation. This follows the "Program to an interface, not an implementation." design pattern.
Methods do not return interfaces or classes. They return a reference to an instance (=object) or null (or a primitive value, but let's stick with objects). This reference is usually either stored in a variable or used to call instance methods or access instance members.
The declared return type tells us the least specific type of the real instance, whose reference is returned by the method. The object behind that reference may be exactly that type or any subclass (or sub-subclass, ...).
A method can return nothing (void), or a primitive value int, double, ...), or a reference that is either null or refers to an instance. When a method returns a reference, it is
declared as returning a reference to some particular kind of object.
In your case, the reference this method returns will either be null or will refer to an object whose class implements Cat
When you don't need to know about implementation you can return interface to leave implementation to that method and caller can just use methods that interface provides.
Cat cat = nextCat(state);
cat.makeCat(state);
As per the object oriented definition, an interface is a group of related methods with empty bodies. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. Having said that, nextCat(GameState state) returns an Interface Cat which means that at runtime it could return any object which Implements Cat. Now, isn't that flexible?
Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
Returning interface allows a member function to return reference of any implemented class. It gives flexibility to program to an interface and also is helpful in implementation of factory and abstract factory design pattern.
It return an Object which implements the interface.
There are some examples for reference :
https://blog.csdn.net/hduxiejun/article/details/52853153
Is Collection<?> a subtype of Object in Java? This might be a stupid question, but isn't Object the root of every class?
No. Collection is an interface, and interfaces cannot inherit from classes -- therefore they cannot inherit from Object. (It does not make sense for an interface, which has no implementation, to inherit from a class, which can have an implementation.)
However, any class that implements Collection will obviously have to inherit from Object. So you can treat objects implementing Collection as though they do inherit from Object, because ultimately they will have to.
It's a semantic difference, but an important distinction in OO theory.
UPDATE: For those challenging this answer with the Java spec, I refer you to this code sample, which indicates that either the spec is not implemented correctly, or is just plain wrong.
TestInterface.java
public interface TestInterface {
public void foo();
}
Test.java
import java.lang.*;
import java.lang.reflect.*;
public class Test {
public static void main(String[] args) {
Class ti = TestInterface.class;
Class sti = ti.getSuperclass();
System.out.println("superclass is null: " + (sti == null));
for (Method m : ti.getMethods()) {
System.out.println(m.getName());
}
}
}
On my system (Java(TM) SE Runtime Environment (build 1.6.0_20-b02) according to java -showversion) the output of the compiled program is:
superclass is null: true
foo
So I'm sorry, but no, interfaces do not technically inherit from anything (except possibly other interfaces) and they do not inherit the methods of Object.
Yes, Collection<?> is a reference type and therefore a subtype of java.lang.Object.
This is easy to check:
import java.util.Collection;
class Assign {
public Object check(Collection<?> things) {
return things;
}
}
Just as well, because it allows us to have collections of collections, for instance.
JLS 4.10.2 sayeth:
Given a type declaration for
C, the direct supertypes of
the parameterized type (§4.5)
C are all of the following:
[...]
The type Object, if C is an
interface type with no direct
superinterfaces.
Yes. Any interface type is a subtype of Object.
I think a lot of the confusion here (by which I mean cdhowie's incorrect answer and the large number of upvotes it has received) centers around an incorrect understanding of the term "subtype". "Subtype" is a compile-time concept defined by the Java Language Specification that indicates a relationship between two types. While the subtype relationship is used various places in the JLS, a type S being a subtype of a type T effectively means that an instance of S is always also an instance of T. Given that, for a reference of type S to be assigned to a reference of type T without casting and without producing a compiler error, S must be a subtype of T!
Thus, the fact that the following code is legal is actually proof that the interface type Collection is considered a subtype of the type Object by the Java langauge, just as the JLS specifies.
Collection<?> collection = ...
Object obj = collection;
cdhowie's "proof" that his answer is correct does not actually prove anything other than that the methods Class.getSuperclass() and Class.getMethods() obey the contracts they specify in their documentation... this has nothing to do with Java's concept of a "type".
Class.getSuperclass():
If this Class represents either the Object class, an interface, a primitive type, or void, then null is returned.
Class.getMethods():
This method returns an array of length 0 if this Class object represents a class or interface that has no public member methods, or if this Class object represents a primitive type or void.