Let's say that I have an interface, and all classes that implement that interface also extend a certain super class.
public class SuperClass {
public void someMethod() {...}
}
public interface MyInterface {
void someOtherMethod();
}
//many (but not all) sub classes do this
public class SubClass extends SuperClass implements MyInterface {
#Override
public void someOtherMethod() {...}
}
Then if I'm dealing with an object of type MyInterface and I don't know the specific sub class, I have to hold two references to the same object:
MyInterface someObject = ...;
SuperClass someObjectCopy = (SuperClass) someObject; //will never throw ClassCastException
someObjectCopy.someMethod();
someObject.someOtherMethod();
I tried making the interface extend the super class, but it's a compiler error:
public interface MyInterface extends SuperClass {} //compiler error
I also thought of combining the interface and the super class into an abstract class like so:
public abstract class NewSuperClass {
public void someMethod();
public abstract void someOtherMethod();
}
But then i can't have a sub class that doesn't want to implement someOtherMethod().
So is there a way to signify that every class that implements an interface also extends a certain class, or do I have no choice but to carry around two references to the same object?
I think that the only solution you have would be to have a reference to both, but this indicates that you have a design flaw somewhere. The reason I say is because you should think of an interface as something that your implementing classes will always need. For example, a Car and Airplane both need a Drive() interface. A design reconsideration is probably worth your time. However, if you still want to follow that path, you can do the following:
public class ClassA {
public void methodA(){};
}
public abstract class ClassB extends Class A{
public void methodB();
}
After you have the above setup, you can now reference an object that has the two methods by doing the following:
ClassB classB = new ClassB();
classB.methodA();
classB.methodB();
Now you don't actually have to actually use two pointers to the same object.
Related
I'm newbie to Java. I would like to ask different between the following interface examples?
public interface MyInterface {
public void doSomething();
}
like this
public class MyClass implements MyInterface {
public void doSomething {....}
}
and this
public class MyClass implements MyInterface {
protected MyInterface myInterface;
public MyClass (MyInterface myInterface) {
this.myInterface = myInterface;
}
public void doSomething () {
myInterface.doSomething();
}
}
In first case you implement an interface using a class and you implement the function doSomething in that class. you can call the doSomething function by creating an instance of the class MyClass
MyInterface obj = new MyClass();
obj.doSomething();
In second case, you wont be even able to instantiate an instance of the MyClass because it needs another instance of it-self or another class which implements that interface.
public class MyClass implements MyInterface {
public void doSomething {....}
}
MyClass implements the interface MyInterface. It means your class holds a concrete behavior that your interface promise. By implementing the interface your class guaranteed the MyClass has the concrete feature your interface abstracted in its declaration.
But I doubt you may not have a real scenario to implement an interface as well as create an instance of interface in a class. Second part of your question is one of the most famous design topic of inheritance vs composition. Chances of using both inheritance and composition together of an interface is barely rare.
The first two code are one interface and another class which implements the interface.
The third code is MyClass that implements MyInterface and creates a object reference to MyInterface named myInterface. The next part
public MyClass (MyInterface myInterface) {
this.myInterface = myInterface;
}
is a simple constructor and the next part
public void doSomething () {
myInterface.doSomething();
}
is calling of a method.
The first one is inheritance and the second one is composition. Inheritance is an "is-a" relationship, while composition is a "has-a".
For example, if there is a Pressable interface which represents everything that can be pressed, Button, Checkbox should implement it. If there is a Color class, the Button should have a composition relationship between the Color, since a Button should have a color, but a Button is not a type of Color.
A commonly known mistake is the java.util.Stack. Since a Stack is not a java.util.Vector, Stack should not inherit Vector.
An interface is an abstract type in Java and it specify a set of abstract methods that classes must implement. A class usually implement the interface as shown in your first example.
In your second example, even though MyClass is implementing the interface, the behaviour of doSomething method will depend on the instance of MyInterface implementation that it will get when instantiate MyClass object.
It is not possible to instantiate an interface. You will have to do something like below. Here MySecondClass implements the MyInterface.
MyClass m = new MyClass(new MyInterface()
{
#Override
public void doSomething()
{
// TODO Auto-generated method stub
}
});
MyClass m2 = new MyClass(new MySecondClass());
}
I have a concrete class which extends an abstract class, which in turn extends an abstract class. This top class implements an interface. Can I implement the interface method in the top abstract class, so that the concrete sub-class does not have to?
Also, if the interface method takes an Object type as it's parameter, can I have the implementation in the top abstract class take another type (which seems right to me), or would I have to use exactly the same method signature?
Can I implement the interface method in the top abstract class, so that the concrete sub-class does not have to?
Yes
Also, if the interface method takes an Object type as it's parameter, can I have the implementation in the top abstract class take another type (which seems right to me), or would I have to use exactly the same method signature?
It has to be the same signature. However, you can trick with generics, if you want to and if you explain your plan in more detail.
for your fist quetion
Can I implement the interface method in the top abstract class, so that the concrete sub-class does not have to?
you can and you should if its a common feature for all the subclasses.
below is the example for the same
interface X{
void show();
}
abstract class A implements X{
public void show(){
System.out.println("show");
}
}
abstract class B extends A{
}
class C extends B{
}
for your second question
No , signature must be same always.
so below program illustares it
interface X{
void print(Object obj);
}
abstract class A implements X{
#Override
public void print(Object obj) {
System.out.println("print");
}
}
below program wont compile if you change type in subclass
interface X{
void print(Object obj);
}
abstract class A implements X{
#Override
public void print(A obj) {
System.out.println("print");
}
}
I was wondering if it was possible to set a parameter to a method as an Object, which must be a extend one class and implement another. Here is an example: Let's say I have a class called ClassA and an interface called MyInterface.
public class ClassA {
/* code */
}
public interface MyInterface {
/* code */
}
Let's say somewhere else there is a class called ClassB, which both extends ClassA and implements MyInterface.
public class ClassB extends ClassA implements MyInterface {
/* code */
}
I could also have a ClassC, which also extends ClassA and implements MyInterface:
public class ClassC extends ClassA implements MyInterface {
/* code */
}
My question is this:
Let's say I have a method called method1, and in method1 I want to have a parameter which accepts an Object. Let's say I wanted this Object to either subclass ClassA or actually be ClassA itself. This is easy to do:
public void method1(ClassA parameter) {
}
Let's say I also wanted a method2, and in method2 I want to have a parameter which accepts anything which implements MyInterface. Again, this is easy:
public void method2(MyInterface parameter) {
}
But what if I wanted a method3, and I wanted to have a parameter which accepts only objects which either subclass ClassA or is ClassA itself, AND implements MyInterface, and so will accept both ClassB and ClassC, but not any class which only extends ClassA, or only implements MyInterface, or neither. Like:
public void method3 ([Something that extends ClassA implements MyInterface] parameter) {
/* code */
}
You can do the following:
public <A extends ClassA & MyInterface> void method3(A parameter) { ... }
But I don't think it's a good idea - if you have a concept of object that extends ClassA and implements MyInterface, it would be better to create a separate class or interface to represent that concept.
From your description, it seems as if you require another type of Object. One that both extends ClassA and implements MyInterface. Perhaps, even, this is an abstract class.
I would then use this new object as the parameter type for method3.
I don't understand why we can't do the following:
interface MyInterface extends Cloneable {}
class myClazz implements MyInterface {
public Object clone() { return null; }
}
class test{
public static void main(String[]a){
MyInterface o = new myClazz();
o.clone(); // IMPOSSIBLE
}
}
But this will work fine
interface Misc{
public void testM();
}
interface MyInterface extends Misc{}
class myClazz implements MyInterface {
public void testM() {}
}
class test{
public static void main(String[]a){
MyInterface o = new myClazz();
o.testM(); // OK
}
}
What's happen with Cloneable?
Thanks,
The Cloneable interfaces doesn't have any methods.
It's just a marker interface which the base Object.clone method (which is protected) checks for.
If you want a clone method, you need to declare it yourself.
This beacause the Cloneable interface is not a normal interface but more or less a tagging interface which ensures to the JVM that the clone method of the class that implements it is legal and actually working.
As the documentation states the Cloneable interface does not declare the signature of the clone method. That method is inherently inherited in any class you declare from the Object class but it is protected by default. This is why you should weaken this constraint by making it public in the middle interface MyInterface that you declare.
Take a look at this hint given in Java doc:
Note that this interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.
It's just because clone() isn't public in Object. If you declare public Object clone() in your interface -- in other words, if you make your first example like your second -- then your first example will work.
I was wondering if the next thing is possible for implementation:
Lets say I've got 2 interfaces while each one of them has 1 function header.
For example, iterface1 has function g(...) and interface2 has function f(...)
Now, I make a class and declaring that this class is implementing these 2 interfaces.
In the class I try doing the next thing:
I start implementing function g(...) and in it's implementation I make a local class that implements interface2 and I add to this class the implementation of f(...).
I'm not quite sure what you mean. I am picturing something like this:
interface Interface1
{
public void g();
}
interface Interface2
{
public void f();
}
class MyClass implements Interface1, Interface2
{
#Override
public void g()
{
class InnerClass implements Interface2
{
#Override
public void f()
{
}
}
}
}
Is that what you meant?
In this case, the answer is no. The inner class (InnerClass) works fine, but it doesn't count as an implementation of f for the outer class. You would still need to implement f in MyClass:
MyClass.java:11: MyClass is not abstract and does not override abstract method
f() in Interface2
Yes it is legal. However a class does not implement an interface because an inner class implements it. The class must implement the interface explicitly or declare itself as abstract.
Yes, it's legal. In the example you've given, your class should implement all methods of both interfaces, and your local class should implement all methods of interface2.