For a project, I have following classes:
SuperClass
Subclass 1
Subclass 2
The two subclasses extend the superclass.
Now, I need a third class with the EXACT behaviour (read, same overriden method implementations) of both SubClass 1 and Subclass 2.
Because Subclass 1 overrides only 1 method in SuperClass, and Subclass 2 doesn't override that method, I want to make the third class inherit Superclass and just implement it with the methods of Subclass 1 and Subclass 2. Now, is this good OO-design? I see no other solution because multiple inheritance in Java just isn't possible. Are there any alternatives?
Java8 introduced default and static methods for interfaces. To a certain degree, that allows for multiple inheritance. But most likely, the correct solution would be to rework your design.
You see, inheritance is not about code re-use. It is about creating useful abstractions; and make good use of polymorphism for example.
In your case: maybe those functionalities could/should be put into smaller interfaces; and then segregated into their own, independent classes. And then you use composition of objects instead of inheritance to build the thing you need.
Here is an example using Java 8's default methods as #GhostCat mentioned. I don't see anything wrong with this OO design per se. Whether or not it's appropriate to your use case depends on the details of the problem you're solving.
public class Main {
public static void main(String... args) {
SuperClass sc = new SubClass3();
sc.foo(); // overridden foo
sc.bar(); // overridden bar
}
interface SuperClass {
default void foo() {
System.out.println("default foo");
}
default void bar() {
System.out.println("default bar");
}
}
interface SubClass1 extends SuperClass {
#Override
default void foo() {
System.out.println("overridden foo");
}
}
interface SubClass2 extends SuperClass {
#Override
default void bar() {
System.out.println("overridden bar");
}
}
static class SubClass3 implements SubClass1, SubClass2 {}
}
Related
Is abstraction possible without inheritance? This is my code
abstract class whatever
{
abstract void disp1();
abstract void disp2();
abstract void disp3();
}
class what {
void disp1()
{
System.out.println("This is disp1");
}
}
public class threeClasses {
public static void main (String args[])
{
what obj =new what();
obj.disp1();
}
}
Please note above, how i:
did not extend the class "what" from abstract class "whatever" and yet the code runs perfectly with no errors
Did not declare class "what" as abstract (since it's not declaring the other two methods disp2() and disp3())
I am very confused. Please help.
You aren't using whatever (and Java naming conventions should be respected). The idea behind an abstract class (and inheritance) is that there is an interface contract. Let's examine it with a more practical example,
abstract class Whatever {
abstract void disp1();
void disp2() {
System.out.println("disp2");
}
void disp3() {
System.out.println("disp3");
}
}
Then make What extend it. Override two methods for demonstration (the annotation is a useful compile time safety check)
class What extends Whatever {
#Override
void disp1() {
System.out.println("This is disp1");
}
#Override
void disp2() {
System.out.println("This is disp2");
}
}
Finally, invoke methods on a What instance through the Whatever contract
public static void main(String args[]) {
Whatever obj = new What();
obj.disp1();
obj.disp2();
obj.disp3();
}
Which outputs
This is disp1
This is disp2
disp3
Note that What is providing the implementation for disp1 and disp2 while Whatever provides disp3.
There is no relationship between your abstract class and your concrete class. Whatever your definition of "abstraction", it actually represents a relationship between types. The abstract keyword does not establish that relationship between classes, it represents that relationship, and not by itself. The relationship needs to be extended from both sides.
abstract is a declaration from one side about a promise that must be kept, for an inheriting type either to implement abstract methods or to ask for that promise from its inheriting types.
The other side makes the promise by being a class that inherits from the abstract type. Without inheritance, the concrete type loses the is-a connection.
You will get the compiler error you're complaining about missing if you correct one major mistake you made. You failed to use the #Override annotation. Always use the #Override annotation when you intend to override a method, or you will forever enjoy just the sort of bug you show here.
I think what he meant was if we can implement abstract class's method without inheriting abstract class.
You might be thinking if we can do it with composition/association/aggregation relation.
To that, I will answer: NO because you can't create an object of abstract class as in these relations you have to make object or reference of the object.
So, the only way to implement abstract methods is through inheritance.
I am programming a simple platformer game, and I have several types of platforms. I created a class for the most simple type and made the rest subclasses, with the only difference between each class being the value of their variables (so they all share the same variable and method names).
In my collision detection, I loop through a HashMap. Within that HashMap are ArrayLists of the instances of each class. But when I use a nested loop to loop through try to call their methods implicitly, I have found that I cannot access these methods without explicitly declaring which class I want to call the method from.
I have done research, although the only way I can see of doing this is to loop through the instances of each class separately, meaning one loop per class; I would rather not do this, since it would be a lot more code than I feel is necessary.
In order to be able to call a common method on classes of different types you need to give your objects a common supertype declaring the common method - i.e. they should have a common superclass, or implement a common interface.
Interfaces provide an easier way of declaring common functionality, because a class can implement multiple interfaces, but it can extend only one class.
Provide an interface with the common method, then declare the map to use objects of that interface, i.e.
interface CommonInterface {
void commonMethod(int arg);
}
class One implements CommonInterface {
public void commonMethod(int arg) {
...
}
}
class Two implements CommonInterface {
public void commonMethod(int arg) {
...
}
}
Here is what you can do now:
Map<String,CommonInterface> myMap = new HashMap<>();
myMap.put("one", new One());
myMap.put("two", new Two());
for (Map.Entry<String,CommonInterface> e : myMap.entrySet()) {
System.out.println(e.getKey());
CommonInterface c = e.getValue();
c.commonMethod(123);
}
Simple, make each platform class implement an IPlatform interface or extand a base class. Look up java polymorphism and interfaces.
Are your subclasses overriding the common methods from the super class?
In other words, are your subclass' common methods declared in your simpler class?
If it is the case, you can simply call the method as if it is a simple class:
public abstract class Fruit {
public abstract void method();
}
public class Apple extends Fruit {
#Override
public void method() {
System.out.println("I'm an apple");
}
}
public class Orange extends Fruit {
#Override
public void method()
System.out.println("I'm an orange");
}
}
Using this you can simply call your method from any fruit, since it has your method declared. No need to know which fruit it is. The following code:
Fruit fruit = new Orange();
fruit.method();
will output: "I'm an orange".
Java 8 introduces the concept of default methods. Consider the following interface with a default method :
public interface IDefaultMethod {
public abstract void musImplementThisMethod();
public default void mayOrMayNotImplementThisMethod() {
System.out.println(" This method is optional for classes that implement this interface ");
}
}
And a class that implements this interface :
public class DefaultMethodImpl implements IDefaultMethod {
#Override
public void musImplementThisMethod() {
System.out.println("This method must be implementd ");
}
#Override
public void mayOrMayNotImplementThisMethod() {
// TODO Auto-generated method stub
IDefaultMethod.super.mayOrMayNotImplementThisMethod();
}
}
I have a question about the readability of the following call in the mayOrMayNotImplementThisMethod :
IDefaultMethod.super.mayOrMayNotImplementThisMethod();
I understand that the reason for explicitly specifying the interface name in the above call is to avoid confusion in case multiple interfaces implemented by the class have the same method. What I don't understand is the meaning of the super keyword in this context. When we say IDefaultMethod.super, what exactly are we referring to here? Wouldn't IDefaultMethod.mayOrMayNotImplementThisMethod() be more readable than IDefaultMethod.super.mayOrMayNotImplementThisMethod()? Removing the super keyword makes it more readable at the cost of distinguishing between a static or non static method call.
I will try to contribute to the discussion by following my own reasonings about this.
Using Classes
First, let's see how this work with simple Java classes:
class Barney {
void foo() { System.out.println("Barney says foo"); }
}
class Fred extends Barney {
#Override void foo() { super.foo(); }
}
In this case if we invoke the method foo in a Fred instance it will ask for the implementation of the foo method in its super class and execute that one.
Evidently, none of these others would work:
#Override void foo() { foo(); } //means this.foo() so infinite recursion
#Override void foo() { Barney.foo(); } //means a static method
There is a third configuration that we could do:
class Barney {
void foo() { System.out.println("Barney says foo"); }
class Fred extends Barney {
#Override void foo() { Barney.this.foo(); }
}
}
In this case if we invoke foo in a instance of Fred, since this instance would have a bond with its enclosing instance, this invocation would invoke the foo method in the enclosing instance of Barney.
For instance
new Barney().new Fred().foo();
So, the use of Barney.this here is used to navigate between instances in an inner/outer relation.
Using Interfaces
Now let's try to repeat the same ideas with interfaces.
interface Barney {
default void foo() { System.out.println("Barney says foo"); }
}
interface Fred extends Barney {
#Override default void foo() { Barney.super.foo(); }
}
As far as I can tell, this is exactly the same thing as with classes, it is just that in this case since an interface can inherit from more than one interface we simply qualify the super keyword with the name of the interface we are targeting in this case.
The meaning is the same, we want to invoke the "implementation" of the foo method in the super interface explicitly named.
As with classes, the following would not work:
#Override default void foo() { super.foo(); } //can't be sure of which interface
#Override default void foo() { this.foo(); } //infinite recursion
#Override default void foo() { Barney.foo(); } //static method
#Override default void foo() { Barney.this.foo(); } //not an inner class relation
So, the logical choice here is Interface.super.method().
A question here would be whether we cab ever have a use case like Interface.this.method when using interfaces.
Not really, because interfaces represent a static context, therefore there is never a concept like that of inner classes between interfaces. So this is never possible.
interface Barney {
default void foo() { System.out.println("Barney says foo"); }
interface Fred extends Barney {
#Override default void foo() { Barney.this.foo(); }
}
}
Basically, this is not possible because the code above does not mean that an instance of Fred would need to exist within the context of an instance of Barney. This is just a static inner interface and instances of it can exist independently of any instances of the parent interface.
So, that's why this would not be a good choice.
So, as you can see, after all this the use of super kind of makes sense, or at least I hope I have explained myself well enough to convey that idea.
This is simply an extension to default methods of the usual approach to accessing members of superclasses (JLS 15.11):
The form T.super.Identifier refers to the field named Identifier of the lexically enclosing instance corresponding to T, but with that instance viewed as an instance of the superclass of T.
Essentially, there can be ambiguity about which member is being referred to when a class has more than one ancestor (whether because of default methods or just because it has multiple superclasses in a hierarchy). The super keyword is the analog of Outer.this in an inner class; it means that you want to get "this, but the stuff I would see inside the body of that superclass instead of the member inside this subclass".
super refers to a class or interface you inherit from. It is means you want to call a method ignoring the fact it has been overridden.
If you used this you would be referring to this class (or a sub-class) and thus have infinite recursion.
Java 8 interfaces also have static methods.
If you say,
IDefaultMethod.mayOrMayNotImplementThisMethod();
Then it is a way to call static method, which also seems correct as it is similar to how we access static members of class.
For default method, if 'super' is not used then they might have used 'this', which does not make sense as 'this' belongs to class where we are making method call.
My opinion is, you are correct as it does not provide good readability but seems it is as per language design.
In the Collection Interface I found a method named removeIf() that contains its implementation.
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
I want to know if there is any way to define method body in an interface?
What is the default keyword and how does it work?
From https://dzone.com/articles/interface-default-methods-java
Java 8 introduces “Default Method” or (Defender methods) new feature, which allows developer to add new methods to the interfaces without breaking the existing implementation of these interface. It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method.
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public class ClassAB implements A {
}
There is one common question that people ask about default methods when they hear about the new feature for the first time:
What if the class implements two interfaces and both those interfaces define a default method with the same signature?
Example to illustrate this situation:
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public interface B {
default void foo(){
System.out.println("Calling B.foo()");
}
}
public class ClassAB implements A, B {
}
This code fails to compile with the following result:
java: class Clazz inherits unrelated defaults for foo() from types A and B
To fix that, in Clazz, we have to resolve it manually by overriding the conflicting method:
public class Clazz implements A, B {
public void foo(){}
}
But what if we would like to call the default implementation of method foo() from interface A instead of implementing our own.
It is possible to refer to A#foo() as follows:
public class Clazz implements A, B {
public void foo(){
A.super.foo();
}
}
Those methods are called default methods. Default method or Defender method is one of the newly added features in Java 8.
They will be used to allow an interface method to provide an implementation used as default in the event that a concrete class doesn't provide an implementation for that method.
So, if you have an interface, with a default method:
public interface Hello {
default void sayHello() {
System.out.println("Hello");
}
}
The following class is perfectly valid:
public class HelloImpl implements Hello {
}
If you create an instance of HelloImpl:
Hello hello = new HelloImpl();
hello.sayHello(); // This will invoke the default method in interface
Useful Links:
Updated Oracle Tutorial
Everything about Java 8
Defender Methods
I did a bit of research and i found the following. Hope this helps.
Existing problem
Normal interface methods are declared as abstract and must be defined in the class that implements the interface. This 'burdens' the class implementer with the responsibility to implement every declared method. More importantly, this also means that extending an interface is not possible after 'publication'. Otherwise, all implementers would have to adapt their implementation, breaking backwards source and binary compatibility.
Solution adopted in Java 8
To cope with these problems, one of the new features of JDK 8 is the possibility to extend existing interfaces with default methods. Default methods are not only declared, but also defined in the interface.
Important points to note
Implementers can choose not to implement default methods in
implementing class.
Implementers can still override default
methods, like regular non-final class methods can be overridden in
subclasses.
Abstract classes can even (re)declare default methods
as abstract, forcing subclasses to reimplement the method (sometimes
called 're-abstraction').
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class? Therefore having object A which uses the interface and object B which does not use it.
Thanks
Updated:
Assuming you have a Professor class and this class implements an interface called Employer, which has employ(rAssist x) abstract method.
Now I want to instantiated 2 objects from the Professor class implementing this interface Object A - Professor can employ a research assistant and Object B - Professor cannot employ research assistants.
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class?
No, if class C implements the interface, then all instances of C will provide the methods declared in the interface.
What you can do is something like
class MyClass implements MyInterface {
#Override
void interfaceMethod() {
System.out.println("Interface method");
}
}
and then do
MyClass x = new MyClass();
MyClass y = new MyClass() {
#Override
void interfaceMethod() {
throw new UnsupportedOperationException();
}
};
In effect, x supports the use of interfaceMethod while y does not. Note however that...
The usage of y.interfaceMethod is not prevented at compile-time, i.e. it will not be enforced by the type system.
With this solution, you are in fact creating an (anonymous) subclass of MyClass and assigning an instance of it to y.
Do you mean you want class A and Class B to implement a common Interface but you dont want to implement all methods in Class B?
An Interface in simple terms means it is sort of a contract and all the classes which implement it should follow that contract.So if you want Class B to implement the interface , Class B should also follow the same contract. But if you dont want to implement any methos you can always do this.
class ISampleInterface {
void sampleMethod();
void optionalMethod();
}
Class A implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
//Your Implementation
}
}
class B implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
throw new UnsupportedMethodException();
}
}
No, that's not the point of an Interface.
An Interface is contract that guarantees that implementations WILL implement it's signature
The idea of interface is to establish a obligation for the class that implements the interface.
If your's is a requirement, you can use the java.lang.reflect.Method reflection class to change the visibility of the method at runtime. However, this is not a clean way.
1. Interfaces were introduced in Java because Multiple Inheritance was not allowed in Java.
2. But as far as Design Pattern are concerned, following are the uses..
- To implement certain Roles.
Consider Dog a Super class, but then Pet dog and Wild dog can be interfaces, which
can be implemented by the Sub Classes of Dog class.
- Used when Behaviors keeps changing.
Consider you have a Class Drawing, and paint method() in it, now paint can be stroking, shading, etc...
You must Encapsulate such behaviors in an Interface or an Abstract class.