I am looking at the Interface chapter provided on the Java website
Using Interface as a type
So my understanding was that the whole point of interface is that it is like a class but it's not possible to form objects from it, but this page says how to use interface as a data type. the line Relatable obj1 = (Relatable)object1; seems to create an object of type Relatable which is an interface. Although I must say that the new keyword has not been used here, thus not really creating a reference to an object of type Relatable. Is that really the cause for this line NOT creating an object of type Relatable?
Again, it further says
If you make a point of implementing Relatable in a wide variety of
classes, the objects instantiated from any of those classes can be
compared with the findLargest() method—provided that both objects are
of the same class.
What does this mean? Does this mean anything that implements Relatable can call findLargest()? If it's so, why does it say provided that both objects are of the same class?
----- EDIT -----
From the previous chapters of this tutorial:
Definition of relatable:
public interface Relatable {
// this (object calling isLargerThan)
// and other must be instances of
// the same class returns 1, 0, -1
// if this is greater // than, equal
// to, or less than other
public int isLargerThan(Relatable other);
}
Using relatable as a type:
public Object findLargest(Object object1, Object object2) {
Relatable obj1 = (Relatable)object1;
Relatable obj2 = (Relatable)object2;
if ((obj1).isLargerThan(obj2) > 0)
return object1;
else
return object2;
}
----- EDIT 2 -----
In the chapter on anonymous classes, it does this:
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
.
.
.
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
So how does this work?
the line Relatable obj1 = (Relatable)object1; seems to create an object of type Relatable
No. This line creates a reference (obj1) of type Relatable and assigns it to object1. In order for this to work, object1 has to be cast to the (interface) type Relatable.
No new objects are being created here.
Does this mean anything that implements Relatable can call findLargest()?
Yes.
If it's so, why does it say provided that both objects are of the same class?
It has to do with the implementation of isLargerThan(). Since any class implementing the Relatable interface can't know anything about other classes implementing it, they can't do meaningful comparisons with other classes. Therefore, in order for this to work, both objects need to be of the same class.
Response to EDIT 2
So how does this work?
Instead of first defining a class and then creating an instance of it, as in the case with the EnglishGreeting, the frenchGreeting is created on the fly. What happens under the cover is that a new class implementing HelloWorld is created, just like in the english case, only this time it is anonymous (you never get to give it a name). It is just a convenience shortcut for those times when you need a one-time implementation of an interface.
Interface types belong to the category of reference types in java. You can never instantiate an interface, but it can be assigned references to any of the objects of classes which implement it:
A variable whose declared type is an interface type may have as its
value a reference to any instance of a class which implements the
specified interface.
Interfaces are like behaviors. If a class happens to implement an interface, lets say Serializable, this adds a behavior to the class, which is, the class can be serialized.
This helps you introduce abstraction in your code. For example lets assume that you need a method in one of your utility classes which will be responsible for the actual job of serialization. Without interfaces you will end up writing a lot of methods, one for each object type that you want to serialize. Now imagine if you asked each of those objects to take care of their serialization themselves (by implementing a serialize method declared in the interface they implemented). With such implementation you need to write only one utility method for serialization. This method can take an argument of Serializable type, and instances of any class implementing this interface can be passed to the method. Now within the method you only need to invoke the serialize method on the interface variable. At runtime this will result in actual object's serialize method getting invoked.
Hope I was able to keep it simple.
Interface in Java is a mutual structure for classes that implement the interface, so the classes benefit from the methods/other member of that interface in their own way, which is called polymophism,
interface A
{
// method header only declared here, so implementation can vary between classes
public int foo();
}
class B implements A
{
public override String foo()
{
return "Class B";
}
}
class C implements A
{
public override String foo()
{
return "Class C";
}
}
so you can call foo() both from class B and C but they will react differently since they implement that method in their own way
An interface is just a class that defines the behaviour of an object, but not the underlaying implementation of it.
By making Relatable obj1 = (Relatable)object1; you are just casting the object1 to a Relatable type, and therefore you can call any of the methods defined in the Relatable interface
To your first question about Relatable obj1 = (Relatable)object1;:
A simple Relatable obj1; will not create an instance of Relatable, but specifies that any object assigned to it must be of a type implementing the Relatable-interface.
Therefore any object that is to be cast, must be of a type implementing the Relatable-interface.
Related
I'm using reflections to find all classes implementing IAnimal Interface.
but how do I return a class instance using the animals set in the below code:
Reflections reflections = new Reflections(IAnimal.class);
Set<Class<? extends IAnimal>> animals= reflections.getSubTypesOf(IAnimal.class);
I have 3 classes implementing IAnimal interface Dog, Cat, Duck. and I want to apply this logic but I don't know how to do it.
method findAnimal(String animalName){
for (Iterator<Class<? extends Operations>> it = animals.iterator(); it.hasNext(); ) {
String classname=it.Name;
if (classname.eqauls(animalName)){
System.out.println("found");
return new class(); }
}}
I want the findAnimal method to return a class instance if matched with the passed string. i.e., if I passed a "Dog" string as a parameter, the method will return a dog class.
is it possible to do that, any ideas on how to implement the logic in the box above?
So this basically boils down to how to create an instance having the java.lang.Class that represents that type?
You can create an instance by using the following code:
Class<?> cl = it.next();
... if condition, you decide to create the instance of cl
IDog object= cl.getDeclaredConstructor().newInstance(); // will actuall be a Dog, Cat or whatever you've decided to create
Note, you've assumed that the default constructor exists (the constructor without arguments). This kind of assumption is necessary, because you have to know how to create the object of the class of your interest.
If you know, that you have constructor that takes some specific parameters (of specific types) you can pass the parameter types to the getDeclaredConstructor method. For example, for class Integer that has a constructor with one int argument the following will print "5":
Integer i = Integer.class.getDeclaredConstructor(int.class).newInstance(5);
System.out.println(i);
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).
public interface Shape {
void draw();
}
class Square implements Shape {
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
class ShapeFactory {
//use getShape method to get object of type shape
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//get an object of Square and call its draw method.
Shape shape1 = shapeFactory.getShape("Square");
//call draw method of square
shape1.draw();
}
}
I got this code while learning design pattern and in this code, the return type of the getShape method is Shape (an interface).
So can an interface type be set as a return type of another method?
It is actually a good practice since you are programming for an Interface rather than Classes, what hides the details of the implementation and makes your code a lot easier to be maintained. Imagine this: you have an Interface X, two Classes that implement it (A and B) and another Class (C) that has a method called foo(). Since both classes A and B implement X, the return of foo() can be X what allows you to return both A or B objects.
In Java, when you have a Class that implements an Interface, an instance of that Class is also an instance of that Interface, that's why you can use an Interface as a return type.
To test what I said, you can create an Interface called MyInterface and a Class TestClass that implements MyInterface. If you create an instance of TestClass (let's say "myClass"), if you compile and run this code, you can check it:
if (myClass instanceof MyInterface) {
System.out.println("Hey, I'm an instance of MyInterface!");
}
So, can an interface type be set as a return type of another method?
Yes, in Java, one can always declare the return value of any method to be interface type. To quote the specification (emphasis mine):
An interface declaration introduces a new reference type whose members are classes, interfaces, constants, and methods. This type has no instance variables, and typically declares one or more abstract methods; otherwise unrelated classes can implement the interface by providing implementations for its abstract methods. Interfaces may not be directly instantiated.
In Java, there are two kinds of types:
Primitive types (byte, short, int, long, float, double, and boolean only)
Reference types (can be arbitrarily many)
Thus, when you have an interface Shape, you can declare methods whose return type (of Reference kind) is Shape. Since Shape is an interface, you can not direct instantiate it since it is abstract (if you do Shape abstractShape = new Shape(); you will get a compiler error: Shape is abstract; cannot be instantiated). In this regard, the return type declaration is analogous to variable type declaration.
There is nothing specific to the Factory design pattern here, although it is of particular importance in implementing a Factory. In general, whenever you believe that coding to interfaces is a good practice in a particular functionality, declaring return types to be interfaces enables that practice.
This is fundamental to the factory method pattern:
a factory method typically returns an interface type,
and the specific class that will be returned is a hidden implementation detail.
A classic example of this is the various factory methods in java.util.Collections, for example emptyList, singletonList, and so on.
These methods return List type, and the implementation is completely hidden.
Another good example is the factory methods in java.util.EnumSet,
with return type EnumSet, which is an abstract class.
Depending on the size of the underlying enum type, the methods will return a RegularEnumSet instance if the underlying enum type contains 64 or fewer elements (as most enum types do), or else a JumboEnumSet instance.
These are two different implementations of EnumSet. The exact type is irrelevant to clients, an implementation detail that can be hidden.
This is one way of abstraction, "Hiding Actual implementation".
Say I have two classes where SubClass inherits from (extends) SuperClass.
What is the difference between:
SuperClass obj1 = new SubClass();
and:
SubClass obj2 = new SubClass();
Both will look to the constructor of the Superclass and initialise it (the correct one, obviously). Both have access to the superclass implementations. But one is (as far as I am aware) a subclass wrapped in a superclass (the first example) and the other is a subclass object (the second example).
How will this effect the way code is run and interpreted?
What are the real world issues that a developer needs to be aware of regarding how these two objects differ?
Thanks in advance for any help!
The only difference with initializing it as a superclass is that if the subclass implementation has methods which the superclass does not, they will not be accessible via this object reference.
But "internally", this is still an instance of the subclass; so, if you call a method defined in the superclass but the subclass has overriden it, it is the subclass' method which is called: the JVM looks up methods from the more specific to the more general.
As a convoluted example, let us take Object and String:
final Object o = "Hello!"; // in fact this calls new String("Hello!")
o.toString(); // <-- uses String's .toString(), not Object's
// Can't do that: String defines .subString() but Object does not
o.subString(1);
It may help to think what the compiler knows about and what the runtime knows and a simple example:
public class Product {
public double getPrice() {...}
}
public class Book extends Product() {
public int getPageCount() {...}
}
and a simple program:
Product p = new Product();
p.getPrice(); // OK
p.getPageCount(); // compiler error
Book b = new Book();
b.getPrice(); // OK
b.getPageCount(); // OK
Product pb = new Book();
pb.getPrice(); // OK
pb.getPageCount(); // compiler error
// but we can still use the getPageCount() of pb;
((Book)pb).getPageCount(); // compiles
// however if pb was not a Book then you would get a runtime error (ClassCastException)
You can test for the actual class by:
if (pb instanceof Book) {
((Book)pb).getPageCount();
}
This is often necessary when developing classes, but if your code has a lot of instanceof it probably needs rethinking.
SuperClass obj1 = new SubClass();
What you're seeing here is a type of substitutability. What this means is, let's say you make another sub class of SuperClass, SiblingClass. Without using the superclass reference type, we would have to change more code, getters and setters, collections that might want to use it. By referencing them as the supertype, all you need to do is pass in the new SiblingClass object on construction.
I am having some confusion about extended classes. I think the best way to explain what I want to do is with some skeleton code:
abstract class Player
{
public int solve()
{ // One method of solving problem
}
}
class otherPlayer extends Player
{
public char solve(int num)
{ //Different method of solving same problem
}
}
// I suspect this is a wrong way to create Player
Player first = new otherPlayer;
// Because this gives me an error...
first.solve(5)'
// And this uses the super class's method of solving problem
first.solve();
// I don't want to do this though...
otherPlayer first = new otherPlayer;
// Because I actually define the Players in a method
// that returns a type Player():
private Player genPlayer()
{ // Take input from keyboard
Player newPlayer;
if (specific set of answers)
newPlayer = new otherPlayer();
else newPlayer = new Player();
return newPlayer;
}
My understanding of extended classes is limited. If I say "TypeA var = new TypeB", and TypeB extends TypeA, it seems that var only has access to methods in the TypeA class. What does it do, then to say it is a new TypeB? Why is that even a legal way to instantiate a variable? And how would you recommend I restructure this program so I can make it work (I'd prefer to keep the method, so I don't have to make a mess every time I create a Player)?
I really just want to know how to create an extended class as if I were a person who knew what he was doing.
You need to do something like:
abstract class Player {
abstract void solve(int num);
}
class OtherPlayer extends Player {
void solve(int num) {
//...
}
}
That is, to call a method through variables of type Player, at least its signature must be declared on that class - and must be implemented in all subclasses. There is no way to call a method that may or may not exist in a subclass using a variable of the superclass type.
Imagine you could do this:
class Player {
// ...
}
class FooPlayer extends Player {
void solveInt(int num) {
// ...
}
}
class BarPlayer extend Player {
void solveString(String s) {
// ...
}
}
Player[] players = new[] {new FooPlayer(), new BarPlayer()};
// this is the sort of code you want to work
for (Player p : players) {
p.solveInt(123);
}
what's supposed to happen when the method is called on BarPlayer? As you can see, it doesn't make much sense to allow this.
While it's not very useful to do Player player = new FooPlayer() explicitly, it does let you not have to know which exact subtype of Player the value is. It's missing the point to look at the methods that are different between the subtypes - the point of polymorphism is that the same method (i.e. with the same signature) is implemented in a different way between the subclasses:
class Player {
abstract String greet();
}
class EnglishPlayer extends Player {
String greet() {
return "Hello";
}
}
class JapanesePlayer extends Player {
String greet() {
return "Konnichi wa";
}
}
The point of TypeA a = new TypeB() is programming to contract. It means you can change TypeB into any other type that extends TypeA and be guaranteed not to have to change any other line of your code.
first, you are getting an error in the instantiation syntax. It should be new otherPlayer(). Also classes should be capitalized in java.
I assume the code is within a method, otherwise it will not compile.
Finally, to answer your question why you extend a class, if otherPlayer had its own implementation solve() (no arguments) then which method would be called would depend on the instantiation you used, not on the variable type. In other words, first.solve() would call the method in otherPlayer, not in player.
extension is about superclasses and subclasses.
if typeA is a subclass of typeB, then you could say
typeA extends typeB, and typeA would inherit all of the methods of typeB
it only works one way, kind of like a child can inherit traits from their parents, but the parents don't inherit anything from the child
if you want a method in the subclass to behave differently than in the parent class, simply write a new method with the same name/parameters. subclass methods automatically override superclass methods. then, if you want to use the superclass version of a method, you can use the super keyword
Inheritance is something that happens when you extend a class, you need to figure out the common methods you want in your class and subclass and define any alternates in your subclass.
Check this out for more info: http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
you declared 'first' as a Player reference that is referencing an otherPlayer object. This is legal, but if you want otherPlayer behavior, you will have to typecat 'first':
((otherPlayer)first).solve(5)
First of all, you can't instantiate abstract classes, so you can't code newPlayer = new Player();.
Then, it's perfectly legal to write something like ClassA a = new ClassB(); as long as ClassB is a subclass of ClassA and ClassB is not an abstract class.
In the case you have a method in ClassB that overrides a method of ClassA, which one is called depends on the dynamic type of the object that is actually the type you used for instantiate that object, this is called Polymorphism. There is lot of material about this (Object Oriented Programming and Java) on the web, but I think a great place to start at, is the book Thinking in Java by Bruce Eckel, he offers the third edition for free at his site (http://www.mindview.net/Books/TIJ/).