Is it possible to have a class defined like
public class MyClass
{
public void methodA(){} // Inherit
public void methodB(){} // Inherit
public void methodC(){} // Require override
}
and then have all classes which extend from MyClass to be required to override methodC() but just simply inherit methodA() and methodB()?
If it is possible, how does one do it? If it's not possible, can you propose an alternative solution to achieve a similar result?
EDIT:
I need a non-abstract class because I want to be able to instantiate this class too.
You would have to make your base class abstract.
public abstract class MyClass
{
public void methodA(){} // Inherit
public void methodB(){} // Inherit
public abstract void methodC(); // Require override
}
You cannot require an override of a non-abstract method.
Maybe you can do something similar to the template method pattern:
public final void methodC() { methodC1(); someMoreLogic(); methodC2();}
protected abstract void methodC1();
protected abstract void methodC2();
Here methodC encapsulates a fixed algorithm that calls into pieces that have to be supplied by the subclasses.
I don't think you do exactly what you want. Alternatively, create MyBaseClass as an abstract class with methodC() abstract implementations for methodA() and methodB(). Derive MyClass from it, adding an implementation for methodC(). Any classes that you do not want to have inherit that implementation should directly subclass MyBaseClass rather than MyClass.
If you want a method to be just inherited use final keyword. To force overriding make it abstract. However, only non-abstract child classes will have to override it.
AFAIK there is no way to force override a method in Java with out abstract.
You can achive with abstract class by making the method as abstract method.
one way to do it may be to use virtual keyword instead of abstract but it doesnt require to override, but you can do override. though so, you can instantiate.
another way and more recommended is to create an interface where you can indicate what the class requirements. it is something like abstract, you indicate what to require, but keep in mind interface is not a class. it's more like pointer. for more for interface click: https://docs.oracle.com/javase/tutorial/java/concepts/interface.html
So, java.lang.Thread is a concrete class that implements the Runnable interface. Therefore, it must be that Thread implements a public void run() method. Yet, when you extend Thread, like MyClass extends Thread { }, you are required to implement the run() method.
It stands to reason that there is a way to force overriding of a method without making the containing class abstract.
Related
Case 1:
I have an Interface Inter.java:
interface Inter
{
void abcd();
}
A base class:
class Base
{
void abcd()
{
System.out.println("Base abcd");
}
}
A Derived class:
class Use extends Base implements Inter
{
void abcd() //intentionally not using public
{
System.out.println("Use abcd");
}
public static void main(String[] args)
{
Use u = new Use();
u.abcd();
}
}
Now I compile it:
gyan##ns:~/Desktop$ javac Inter.java Base.java Use.java
Use.java:3: error: abcd() in Use cannot implement abcd() in Inter
void abcd()
^
attempting to assign weaker access privileges; was public
1 error
gyan##ns:~/Desktop$
That means the overridden method abcd() in the class Use is from the implemented interface "Inter" and not from the base class "Base".
Case 2:
We have a file Test.java containing following codes:
interface Ab
{
void run();
}
class A extends Thread implements Ab
{
public void run()
{
System.out.println("class A");
}
public static void main(String[] args)
{
A a = new A();
Thread t = new Thread(a);
t.start();
System.out.println("main method");
}
}
When we execute it we got:
gyan##ns:~/Desktop$ java A
main method
class A
gyan##ns:~/Desktop$
Since t.start() executed the method run(), that means method run() of the class Thread got overridden. But in the case 1 method abcd() of the interface "Inter" got overridden.
In case 1: Whose method abcd() is overridden in class Use? Class Base or interface Inter? Error says we are overriding the abcd() of interface Inter. But in case 2: It seems that we are not overriding the method run of interface Ab. Because we can execute the run() method by calling t.start(). Which is only possible if we are overriding the run() of class Thread.
The method in your class overrides the base class method and implements the interface, at the same time.
Overriding a method is not exactly the same as implementing an interface :
Overriding a method from a superclass means you are replacing its implementation. If you are not providing an overriding method, the implementation from the superclass (which can be empty) will be used.
When implementing an interface method, you are providing code for a simple declaration (without any implementation). If you declare a not-abstract class as implementing an interface, but don't provide an implementation for every method of the interface, compilation fails. This is less true in Java 8, where you can optionnally provide a default implementation in interfaces, but in this case any implementation from a superclass would win.
Implementations and overrides of a method can always extend its visibility, but not decrease it. This means :
a package-private (default visibility), or protected method in a superclass can be made public in the subclass
but a public method in a superclass cannot be made package-private or protected in the subclass.
Methods in an interface are always public, even if the "public" modifier is not specified in the interface. Hence, their implementations must also be public => that's the error you get in your case 1
As a side note, in your case 2, you are using threads wrong. Do not subclass Thread. Instead, create a class implementing the Runnable or Callable interface, and submit it to a thread pool (see classes in java.util.concurrent, or for a quick test use java 8's ForkJoinPool.commonPool().submit(myTask).
Both. Method overriding depends on the name and signature of the method not where it is defined. If defined on more than one ancestor, it overrides both.
Note: If defined as public in one and protected in another, it'll become public.
In the Inter interface, void abcd(); is the definition of an abstract method. All abstract methods are inherently public.
From {Defining an Interface},
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
So, while Inter said that abcd() was public, the actual implementation in Use is saying that the implementation of abcd() is package-private, which is a weaker access privilege. This should address your comment "//intentionally not using public".
Traditionally, abcd() should also use the annotation #Override (although it is not a hard requirement).
In your second example, Thread class provides a concrete implementation of run(). Given that A#run() is public, you have satisfied the requirement imposed by interface Ab regarding access specifiers. Then, A#run() went on to override Thread#run() - which is exactly how we would expect inheritance to behave.
To summarize, we just saw the difference between extends (extending or overriding class methods) and implements (contract that the given class provides an implementation for all the methods states in the interface). {This answer} goes into more depth about this and is an excellent read.
Let me know if any part of this answer needs more clarity.
I am told that: a class can extend a concrete superclass and override an implemented method to make it abstract.
If the method becomes abstract, then the corresponding superclass should become abstract too.
Is this correct? If so, is it meaningful to make the superclass or the method in superclass to become abstract?
To contain abstract methods the class itself must also be declared abstract.
Abstract methods can be used where behaviour is specific to each subclassing object. Although this can also be achieved through interfaces, you may prefer to use an abstract class as they can also contain already implemented methods, or you may wish to declare fields which are not static and final. Beware that when a class becomes abstract it can no longer be instantiated.
Read more about abstract classes here.
Whether or not you make your class abstract if it contains abstract methods is not a choice, it is a must. You cannot have a non-abstract class that has abstract methods.
Whether or not you should declare a method abstract or implement it in your super class comes down to your concrete use case. Is there a default behavior that makes sense for all possible concrete implementations of the super class? Then you might want to implement it. If that's not the case, declare it abstract and let the sub classes take over.
I am told that: a class can extend a concrete superclass and override an implemented method to make it abstract.
If the method becomes abstract, then the corresponding superclass should become abstract too.
Is this correct?
I think it's incorrect.
Take the following code for example.
public class Father {
public void print() {
System.out.println("Father");
}
}
public abstract class Son extends Father {
#Override
public abstract void print(); /* no need to abstract the superclass */
// and other abstract or concrete methods
}
public class Grandson extends Son {
#Override
public void print() {
System.out.println("Grandson");
}
}
I have two methods in an interface:
public interface MyInterface {
public void methodOne();
public void methodTwo();
}
public class MyClass implements MyInterface{
public void methodOne(){
//implementation code
}
public void methodTwo(){
//implementation code
}
}
Can I restrict one of them while implementing the interface?
You must implement all methods of your interface, unless the class implementing the interface is abstract.
If by restrict you mean that you want to predefine one or more of the methods, then you can use an abstract class instead of the interface. Abstract methods in an abstract class are methods that must be implemented by any class that extends the abstract class. Non-abstract methods are actually implemented in the abstract class, itself.
For example,
public abstract class MyClass
{
abstract void methodOne();
void methodTwo()
{
//implementation code
}
}
public class MyOtherClass extends MyClass
{
void methodOne()
{
//implementation code
}
}
Here's a reference for Abstract Classes and Methods.
EDIT 1 (in response to comment):
I'm not really sure what you mean by a burden. All I'm saying is that if you want all methods to be implemented by the class, then use an interface.
If you only want some of the methods implemented by a class, then you can either use an abstract class instead of the interface
or
If it makes sense, have an abstract class implement the interface (partially) and then have the remainder of the methods implemented by whatever extends the abstract class.
Both approaches are reasonable. It depends on what you really need to do.
EDIT 2 (in response to additional comments):
Providing one user class with additional features seems like the perfect application for just extending the "normal user class" with a "super user" class that has the additional features. If you need an interface for the "super user" class, you can create an interface that extends the interface implemented by the "normal user" class.
No you have to implement all methods if your class implements an interface.
Unless it is abstract.
Check this discussion for more details.
You can use an abstract class; they do not need to implement all the entire interface. However, they cannot be instantiated. You must implement all methods in order to instantiate an implementation of an interface.
Except the abstract class, you are bound to implements all methods of interface.
You can not put restriction on Interface, but YES you can achieve In Abstract class and NO in concrete class.
Couple of solutions :
Either mark the class as abstract. But in that case you cannot instantiate your implementing class.
Simply add black implementation in your class.
Not sure what you mean by "restrict". You have to implement the method. However, you could simply do
public void method1(someargs) {
throw new UnsupportedOperationException();
}
as is done by many Collection implementations.
Suppose we have one class implements Interface extends abstract class with same abstract function in both Interface and abstract class. Then class inherit which function Interface or abstract class and why.
Like:
public class A extends B implements I
{
public void set()
{
// Some code here
}
}
Interface:
public interface I {
public void set();
}
abstract Class:
public abstract class B
{
public abstract void set();
}
Both. As long as the functions signatures match, the compiler will accept this "double"-inheritance. Keep in mind implementing interface's methods is only a "contract" your class has to verify to be compilable. Implementing the interface only means "my concrete class has to have a method set()". Extending the abstract class B means "my concrete class inherits the method set() from its superclass, and as it's defined as abstract, it needs to implement it". When both these propositions match (as per your example), all is fine.
If there is a difference in the signature of the functions between the interface and the abstract class, your concrete class must then implement both versions.
BTW, slightly off-topic, try to avoid abstract classes as much as you could. If an abstract class has only abstract methods, then it should be an interface. If it has some code in some of its method, then you should probably think about refactoring it to use composition rather than inheritance. Inheritance is evil ;)
It doesn't matter to know from which the method will be inherited because the method in both Interface and Abstract class are abstract meaning no implementation is given.
So all you have to ensure in your concrete class that you must implement all the method defined in the interface but not implemented in the abstract class . AND implement all the abstract methods defined in its superclasses (even if they are not defined in an interface) (from Guillaume)
I have a class, let's say
public class GeneralClass<T> {
methodA() {...}
methodB() {...}
methodC() {...}
}
and I'm deriving from this class
public class MoreSpecificClassString extends GeneralClass<String> {
methodD() {...}
methodE() {...}
methodF() {...}
}
public class MoreSpecificClassInt extends GeneralClass<Integer> {
methodX() {...}
methodY() {...}
methodZ() {...}
}
Now, what I would like to know if it is possible to force the subclasses of GeneralClass to override only one method, such as methodA?
Thanks
Yes. Make methodA abstract and make GeneralClass an abstract class. If you want to prohibit overriding methodB and methodC, mark them as final.
Edit
If on the other hand you want to be able to provide a default implementation of methodA, and also require subclasses to override it, you are essentially violating the Liskov Substitution Principle. You need to reevaluate why you require this design, because it smells pretty bad. For example, there would be absolutely nothing preventing your subclass from just overriding your method like this:
#Override
public void methodA() {
super.methodA();
}
And if the re-implementation can just call the super class' default implementation, what was the point in forcing it to be overridden in the first place?
It's for this reason (among others) that it's not possible to provide a default implementation and require subclasses to override it. Rethink your design.
Yes, make GeneralClass an abstract class, with implementations for the other methods.
Example:
abstract class ABC {
abstract int methodA();
final int methodB() { ... implementation ...}
}
For forcing just a one - make this method abstract ?
You have several tools available:
You can declare a method (and the base class) abstract. Concrete classes will be forced to implement the method.
Declare non-overrideable methods final. Derived classes cannot override these methods.
Combine 1 & 2: declare a method final and have it delegate part of its work to an abstract method. (This pattern is often used with an empty method instead of an abstract method to implement so-called "hooks" into otherwise fixed logic.)