This question already has answers here:
Why is there a private access modifier in an abstract class in Java, even though we cannot create an instance of an abstract class?
(5 answers)
Closed 5 years ago.
What is the use of writing a private method inside an abstract class, and can we write public static inside that class? Please give an example.
You can use any kind of method in an abstract class. The only difference between an abstract class and a normal one is that the abstract class contains methods which have no body:
public abstract Foo {
public void foo() {
bar();
}
private void bar() {
doSomething();
}
protected abstract void doSomething();
}
So while bar() has no idea what doSomething() really does, it knows that it will exist eventually and how to call it.
This is enough for the compiler to create the byte code for the class.
we can have our implementation in abstract class and so the private method
For Example :
public abstract class AbstractDAO{
public void save(){
validate();
//save
}
private void validate(){ // we are hiding this method
}
}
But an abstract method can never be private , it must be public or protected , otherwise the subclass won't be able to define it
Related
This question already has answers here:
Is there a way to make sure classes implementing an Interface implement static methods?
(9 answers)
Closed 2 years ago.
Coming from Python and Objective-C land, I may not fully understand what static methods are in Java, I think of them as "methods that operate on all members of the class" or "class-specific methods that are available when you don't have an instance of that class."
But is there a syntax for saying: "This abstract superclass requires each concrete subclass to implement this static method"? I know that static abstract isn't permitted, but it would conceptually be something like this:
public abstract class Lander {
#RequireImplmentationInSubclass // clearly my made-up name...
static abstract boolean probe(Radio radio);
}
public class MarsLander extends Lander {
static boolean probe(Radio radio) {
// ... some MarsLander specific implementation
}
}
public class LunarLander extends Lander {
static boolean probe(Radio radio) {
// ... some LunarLander specific implementation
}
}
update
... and somewhere else, a factory method does something like:
if (MarsLander.probe(radio)) {
... create an instance of MarsLander and work with it
} else if (LunarLander.probe(radio)) {
... create an instance of LunarLander and work with it
}
In my application, creating an instance invokes a lot of machinery, so I need to call probe() on a class method before I create an instance of the class.
I looked over Is there a way to make sure classes implementing an Interface implement static methods? and most of the responses were "why would you want to do that?".
I hope this example makes it clear(er). Perhaps there's' a more Java-esque way to remind the developer that a class-visible probe() method is required?
There is no way to require a static method.
But you can create a factory class with non-static methods:
public abstract class LanderFactory<L extends Lander> {
public abstract L createLander();
public abstract boolean probe(Radio radio);
}
You can even have a registry of LanderFactory implementations, so they effectively act as singletons:
public abstract class LanderFactory<L extends Lander> {
private static final Map<Class<? extends Lander>,
LanderFactory<? extends Lander>> registry
= Map.of(MarsLander.class, new MarsLanderFactory(),
LunarLander.class, new LunarLanderFactory());
public static LanderFactory<? extends Lander> getInstance(
Class<? extends Lander> type) {
LanderFactory<? extends Lander> factory = registry.get(type);
if (factory == null) {
throw new IllegalArgumentException("No factory known for " + type);
}
return factory;
}
public abstract L createLander();
public abstract boolean probe(Radio radio);
}
public class MarsLanderFactory extends LanderFactory<MarsLander> {
#Override
public MarsLander createLander() {
return new MarsLander();
}
#Override
public boolean probe(Radio radio) {
// ...
}
}
public class LunarLanderFactory extends LanderFactory<LunarLander> {
#Override
public LunarLander createLander() {
return new LunarLander();
}
#Override
public boolean probe(Radio radio) {
// ...
}
}
"methods that operate on all members of the class"
This is not right. static methods operate on no members of a class.
Use of this is prohibited in static contexts.
I feel your question itself has the answer you are looking for. static abstract doesnt exists because on one hand you want it to behave differently (based on if it is a LunarProbe or a MarsProbe) and on the other hand you want it to be independent of the instance of LunarProbe and MarsProbe. static abstract contradicts itself.
Besides
static boolean probe() {
// ... some MarsLander specific implementation
// what goes here? you dont have access to any instance of this class.
}
static abstract violates a tenet of OOP called polymorphism.
I tried your code(and other things surrounding this), and I'd like to tell you there's a way but I don't think there is.
I would instead recommend using a utility class that supports this static functionality you're looking for.For example, a LanderUtility class that has static methods in it might solve this in a reasonable way.
Mostly though, I don't think of using static methods in that way in Java. The real power in what is going on with this abstract class is that you can count on(somewhat) a certain type of behavior from a child. Notably, for this to matter, the child needs to be instantiated in the first place and you can use a normal, non-static method and have the child implement that instead.
In Java, static methods is allowed to be invoked directly on class references. It does not matter whether it is a abstract class or a normal class.
Due to this reason, static and abstract modifiers can't be used together. Otherwise, what would be the output of this code if the lander method is not implemented ? That's why it is illegal.
Lander.probe();
But, I think we can throw an exception from our super class static method with some hint in the exception message. We can enforce implementation of the static method.
public abstract class Lander {
static boolean probe() {
throw new RuntimeException("Oh oh !!! Why am I here ??");
}
}
public class MarsLander extends Lander {
static boolean probe() {
// ... some MarsLander specific implementation
}
}
public class LunarLander extends Lander {
static boolean probe() {
// ... some LunarLander specific implementation'
}
}
That way, if there is a Lander implementation which has not implemented a static probe method, the probe method will get inherited but this will throw a run time exception.
Methods can't be both abstract and static, because abstract methods have to be overridden, and static methods in Java cannot be overridden. Which class implementation of a static method is used is determined at compile time. You can declare a static method with the same signature in a subclass, but it is not considered overriding because there won’t be any run-time polymorphism. The static method of the superclass is 'masked' in the subclass. If a derived class defines a static method with the same signature as a static method in the base class, the method in the derived class hides the method in the base class.
This question already has answers here:
What is the difference between public, protected, package-private and private in Java?
(30 answers)
Closed 2 years ago.
Suppose i have the following class structure. If i execute the child class, it will print both.
Inside Public method
Inside Private method
Could anyone explain the reason how the private method code is reachable to m1 ?
class Base
{
public void m1()
{
System.out.println("Inside Public method");
m2();
}
private void m2()
{
System.out.println("Inside Private method");
}
}
public class Child extends Base
{
public static void main(String[] args)
{
Child ob = new Child();
ob.m1();
}
}
Private variables/methods are accessible by everything within the class.
Protected variables/methods are accessible by everything within that package and any subclasses.
Public variables/methods are accessible by everything.
A private method is only visible in the class scope. The method m1 is in the same class as the private method m2 even if the m1 method is inherited.
You can do this with a reflection, what you can see here:
Method method = c.getDeclaredMethod("m2", null);
method.setAccessible(true);
method.invoke(obj, null);
Any way to Invoke a private method?
Private methods can be called by any method inside the class it is contained.
You can't call m2 method directly outside of the Base class scope, but you can call it indirectly through less restricted methods like public or protected.
Like you did with m1 method.
The caller class could not call m1 directly, but it will certain execute it. This is known as encapsulation. You use it to hide implementation details that doesn't matter for the caller.
This question already has answers here:
Creating the instance of abstract class or anonymous class
(8 answers)
abstract class and anonymous class [duplicate]
(2 answers)
Closed 3 years ago.
I have been reading this guide on inner classes and came across this interesting example of an anonymous class.
So, by default we cannot instantiate an abstract class, e.g.
abstract class AnonymousInner {
public abstract void mymethod();
}
public class Outer_class {
public static void main(String args[]) {
AnonymousInner inner = new AnonymousInner();
inner.mymethod();
}
}
Gives an error stating that we cannot instantiate an abstract class.
But doing it this way is fine -
abstract class AnonymousInner {
public abstract void mymethod();
}
public class Outer_class {
public static void main(String args[]) {
AnonymousInner inner = new AnonymousInner() {
public void mymethod() {
System.out.println("This is an example of anonymous inner class");
}
};
inner.mymethod();
}
}
So I am a bit lost how the second example is working.
It's because you're making an anonymous class - you're defining in place an implementation of your abstract class without a name, that can be used only here and then instantiating this (concrete) class. More about it here.
Other example would be using lambdas everywhere, where functional interface is needed, for example in streams:
stream.filter(a -> a.isTrue)...
// or
stream.filter(ClassA::isTrue)...
Here lambda and method reference are treated as implementations of Predicate.
Here, you are creating an object of the inner class that extends the abstract class. You can decompile the class file generated and see it for yourself.
This is the class that will be generated after the code compiles. (I've decompiled the class and it will look something like this :
final class Outer_class$1
extends AnonymousInner
{
public void mymethod()
{
System.out.println("This is an example of anonymous inner class");
}
}
You can clearly see that the inner class is providing an implementation for the abstract class.
Just extending the question..
Same method in abstract class and interface
Suppose a class implements an interface and extends an abstract class and both have the same method (name+signature), but different return types. Now when i override the method it compiles only when i make the return type same as that of the interface declaration.
Also, what would happen if the method is declared as private or final in the abstract class or the interface?
**On a side note. Mr. Einstein stuck to this question for an abominable amount of time during an interview. Is there a popular scenario where we do this or he was just showing off?
If the method in abstract class is abstract too, you will have to provide its implementation in the first concrete class it extends. Additionally, you will have to provide implementation of interface. If both the methods differ only in return type, the concrete class will have overloaded methods which differ only in return type. And we can't have overloaded methods which differ only in return type, hence the error.
interface io {
public void show();
}
abstract class Demo {
abstract int show();
}
class Test extends Demo implements io {
void show () { //Overloaded method based on return type, Error
}
int show() { //Error
return 1;
}
public static void main (String args[]) {
}
}
No, same method names and parameters, but different return types is not possible in Java. The underlying Java type system is not able* to determine differences between calls to the methods at runtime.
(*I am sure someone will prove me wrong, but most likely the solution is considered bad style anyways.)
Regarding private/final: Since you have to implement those methods, neither the interface method nor the abstract method can be final. Interface methods are public by default. The abstract method can't be private, since it must be visible in the implementing class, otherwise you can never fulfill the method implementation, because your implementing class can't "see" the method.
With Interfaces the methods are abstract and public by default ,
so they cant have any other access specifier and they cant be final
With abstract class , abstract methods can have any access specifier other than private and because they are abstract they cant be final
While overriding , the method signature has to be same ; and covariant(subclass of the declared return type) return types are allowed
A class cannot implement two interfaces that have methods with same name but different return type. It will give compile time error.
Methods inside interface are by default public abstract they don't have any other specifier.
interface A
{
public void a();
}
interface B
{
public int a();
}
class C implements A,B
{
public void a() // error
{
//implementation
}
public int a() // error
{
//implementation
}
public static void main(String args[])
{
}
}
I have a Java problem with nested classes.
My first class structure looked like this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private interface NestedClass {
public void method();
}
private class NestedClass1 {
public void method() {
}
}
private class NestedClass2 {
public void method(){
}
}
}
But now I want these method() methods to be static because they should be principally.
I cannot make them static without having them in a static class, but that's no problem, I made the classes static, they should be anyway.
It looks like this right now:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static interface NestedClass {
public void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But then the trouble begins. A static method does not inherit correctly from a non-static interface method, as I get this message This static method cannot hide the instance method from TopClass.NestedClass in Eclipse.
When I make the interface method static, it gives me this error: Illegal modifier for the interface method method; only public & abstract are permitted
So I thought of an abstract class, and tried this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static abstract class NestedClass {
public static abstract void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But again, seemingly abstract methods cannot be declared static: The abstract method method in type NestedClass can only set a visibility modifier, one of public or protected.
Leaving the static away (in the abstract class method), errors this on the method methods in the NestedClass1 & 2: This static method cannot hide the instance method from TopClass.NestedClass.
Isn't there any way to declare some kind of superstructure for covering static methods?
EDIT:
The problem I actually try to solve it the lack of possibility of Java for storing references to methods. So instead I have those classes everyone with just one method, but to store them in a List f.e. they must be able to be "caught" by a superstructure.
I got the hint to try anonymous classes or enums, gonna try that now.
Interfaces and statics don't go together. At all. There is no Java support for creating / imposing patterns on static methods.
A static method declaration must always be followed by a definition. It cannot be implemented by subclasses.
I think you're just not approaching your problem right. Try a different approach!
Make NestedClass an interface NestedInterface and store your different implementations as anonymous classes implementing this interface:
public static final NestedInterface firstNested = new NestedInterface() {
#Override
public void method() {
// ...
}
};
Make NestedClass an enumeration NestedEnum and store your different implementations as enumeration values implementing an abstract method from the enumeration. This only works if you have a fixed number of implementations you which to choose from and you do not want to accept NestedClass implementations from outside sources.
public enum NestedEnum {
FIRST {
#Override
public void method() {
// ...
}
};
public abstract void method();
}
EDIT: In reply to your comment:
The classes itself are static as well..
static in the context of a nested class means that this class can be instantiated without an instance of the containing class.
A regular nested class such as in your first example can be instantiated through TopClass.this.new NestedClass1(). Normally you'd simply write new NestedClass1() from within the constructor or an instance method of TopClass, but in this verbose form you can clearly see the dependence on TopClass.this. This can also be seen from any method of NestedClass1, as you have access to the containing class with TopClass.this.
A static nested class such as in your second example can be instantiated through new TopClass.NestedClass1(). Once again, you could just write new NestedClass1() but the verbose form clearly shows that the construction only depends on TopClass and is not associated with an instance of TopClass. You could even create an instance from an outside class using the same snippet new TopClass.NestedClass1() without ever creating a TopClass instance.
I suggest you take a look at this question on inner classes and static nested classes.
The fact the your interface/abstract class is nested is irrelevant to the problem.
You just can't. There is no way in Java to enforce some class to implement static methods. Just cry and surrender and use instance methods.
static abstract is a contradiction. Static methods are not like other languages' class methods. When you make a static method it goes on a single class, it doesn't get inherited by or have its implementation deferred to subclasses.
You don't explain why you want these methods to be static. If you want these methods to be defined by subclasses then they shouldn't be.