Why nested abstract class in java - java

I am wondering what does it mean to have a nested abstract class ? for example,
abstract class A{
abstract class B{
}
}
Are there any use cases or scenario that we might need such as design ? or is there something useful in such pattern ? and why Java allows us to do it ?

In design, you want the base class class A to present only an interface for its derived classes. This means, you don’t want anyone to actually instantiate an object of the base class. You only want to upcast to it (implicit upcasting, which gives you polymorphic behavior), so that its interface can be used. This is accomplished by making that class abstract using the abstract keyword. In other hand you want to use only part of functionality of class A so you create class B (as child) to reduce the coupling or implementation dependencies between systems and prevent duplicates.
But bear in mind when you define an inner class, code without inner classes is more maintainable and readable. When you access private data members of the outer class, the JDK compiler creates package-access member functions in the outer class for the inner class to access the private members. This leaves a security hole. In general we should avoid using inner classes. Use inner class only when an inner class is only relevant in the context of the outer class and/or inner class can be made private so that only outer class can access it. Inner classes are used primarily to implement helper classes like Iterators, Comparators etc which are used in the context of an outer class. About abstract class, it should be abstract to helpers, suppose your helpers should be too complicated to write abstract form for them.
In your case, I don't remember extensive usage of nested abstract classes, maybe in Swing world.

abstract classes are used to provide a partial implementation of a class for inheritance. it allows you to define the scheme of a class without providing the full definiton, so that it can be specified in a child class. it works somewhat like a Interface in that you can perform any operation specified in the abstract class upon an instance of any classes derived from it. Nested abstracted classes are designed to be inherited by other inner classes (even anonymous ones I think) but not by classes defined outside the outermost class.
public class HelloEveryone{
abstract class Hello{
void SayHello(){
System.out.println("Hello!");
}
abstract void SayHelloAlt();
}
public class HelloWorld extends Hello{
public void SayHelloAlt(){
System.out.println("HelloWorld!");
}
}
public class HelloUniverse extends Hello{
public void SayHelloAlt(){
System.out.println("HelloUniverse!");
}
}
void Go(){
ArrayList<Hello> hellos = new ArrayList<Hello>();
hellos.add(new HelloWorld());
hellos.add(new HelloUniverse());
for (Hello h : hellos){
h.SayHello();
h.SayHelloAlt();
}
}
}
static void main(){
HelloEveryone hello = new HelloEveryone();
hello.Go();
}

Related

Abstract Class Vs. [Interface+Inheritance] in Java

In context of Java, could a class replace the need of extending an abstract class by extending another non-abstract class and implementing an interface together, both of which combined have all the methods(abstract and implemented), of an abstract class?
In context of Java, could a class replace the need of extending an
abstract class by extending another non-abstract class and
implementing an interface together, both of which combined have all
the methods(abstract and implemented), of an abstract class?
Can it? Yes
Should it? No
An abstract class can be replaced by a concrete one, but you will be altering your system.
Do remember: an abstract class can not be instantiated, nor should it be, since it's not 'concrete enough' to make sense for your business. (If it does, it shouldn't have been an abstract class to begin with)
If you make it concrete, you risk that developers will use instances of the (what-should-be) abstract class.
If you change it the way you propose:
public void doSomething(MyAbstractClass instance){
// here we know there is an implementation provided by a subclass
}
would become
public void doSomething(MyShouldBeAbstractClass instance){
// here they can pass instances of the base class, which might have unsupported methods
}
For instance:
public String getConcreteInformation(){
throw new UnsupportedOperationException("Should be called on a child class");
}
and could lead to a lot of nasty bugs

Abstract inner class within non-abstract outer class

I have a super-class A with an abstract inner-class Inner, with another class B that extends A. Why doesn't A force B to implement the abstract inner-class?
I've already looked here, but it only specifies abstract methods in non-abstracts classes. Does the same principle apply here?
public class A {
...
abstract class Inner {
...
}
}
public class B extends A {
...
// Isn't forcing me to implement Inner
}
In many situations, there is no need to implement A.Inner. I was recently working with a UI-free browser library for Java. They had a class Element with subclasses like Anchor, Input, Span, Script, Style. Surely you wouldn't want to be forced to implement, for example, all the subclasses of Element? This is particularly true when the superclass is a member of someone else's code. Said superclass may have private methods referring to private subclasses.
An inner class, whether it's abstract or not, is basically syntactic sugar for a class that has a built-in reference to an instance of another class, its enclosing class. The fact that it is nested simply adds potential accessibility restrictions. Other than that, it's just like any other class (minus a few other restrictions on static members).
Because it would be a pointless restriction unless some code in B tried to instantiate A.Inner, in which case the existing rule would already catch it.
If you define a new concrete class that extends an abstract class, it has to implement the methods. But you haven't defined a new concrete class that extends Inner. You've defined a new class B that extends A; in a sense, B inherits the Inner class, but it's still abstract. (You can say B.Inner in some contexts, but from my testing it appears that the compiler treats it the same as A.Inner.)

Access not allowed to a static inner interface

I have the following situation.
package A;
class SampleClass
{
static interface sampleInterface
{
....
}
}
Now when I try to import the sampleInterface from another package , jDev says 'access not allowed'. What could be the problem?
Currently, the interface is seen as package-private (there's no visibility modifier, so that's the default). Place public on the outer class and the interface, and it will become visible to other classes.
Just be careful - if you get caught in a situation where you have to do this:
public class Alpha extends Alpha.IAlpha {
public void doNothing();
public static interface IAlpha {
public void doNothing();
}
}
...you'll have an issue with cyclic inheritance, and your class won't compile. In fact, you won't be able to use the interface at all.
Keep these rules in mind for exposing interfaces, classes, or enums:
If you only need an inner class, interface, or enum for that particular object, then it's fine to declare it as static.
If you need a class, interface, or enum accessible from anywhere but that object, then it's best to move it out of the inner class, and into its own file.
In general, interfaces are seen as APIs to conform by - there's really no benefit in having them as nested unless the scope of them is extremely narrow.
Change visibility of the class and the interface to public. It will work for sure.
When you declare a class without a access specifier it is by package-default. This means you can access that class in that package only.
If you want to access class from another package, make class public, i.e.
public class SampleClass
Similarly, in your case, as you want to access the Interface as well, you have to make that interface public as well.
This will solve your problem.

Inner class in interface that must be implemented by the "implementor"

I have this interface:
public interface ISectionListItem {
public int getLayoutId();
public void setProps(View view, int position);
}
But i want all the classes who implements this interface be forces to have a static class inside them. I thought of:
public interface ISectionListItem {
public int getLayoutId();
public void setProps(View view, int position);
static class ViewHolder {};
}
But that dosn't force the classes to "add unimplemented inner classes". Anyway to accomplish this? Is it even possible?
Thanks :)
The point of an interface is that you're defining a contract, not an implementation. If you really need to have an instance then you'd want to do something like
public ViewHolder getViewHolder();
and define a viewholder interface. Again, the idea is that you're not creating an implementation, you're expressing a contract.
This is not possible by the nature of interfaces. An interface defines the public behavior of objects; if a class implements an interface, that means that all instances of that class obey the contract defined by the interface. For this reason interfaces can't contain static members. (There's an exception to this rule, but at this point you shouldn't care about that.)
Be careful of your terminology: static member classes are not inner classes. Static member classes are like normal classes, except that they live in a different namespace. Static member classes are not members of the instances of the containing class, just as any static class member is not part of the "instance template". An inner class is by definition not static.
So, why can't we declare a genuine (i.e. non-static) inner class in an interface? That's because in an interface you can only define the behavior of objects, not how they are composed. The whole point (and beauty) of interfaces is that they separate the behavior ("what does it do") from the implementation ("how is it done"). For that reason you can't declare inner classes in an interface, just as you can't declare fields in an interface.
I don't know what you're trying to do, but you might want to try the following. Let's call your original interface MyInterface.
Define an extra interface SomeType
Have your inner class implement SomeType
Declare a method like public SomeType getInnerClassInstance() (a terrible method name) in MyInterface
Note that MyInterface instances aren't forced to actually return an instance of an inner class as a result of getInnerClassInstance(). This is a nice thing, because you're not bound to a specific implementation.
You can't force someone to create an inner class.
Depending on what you want to do your best best is probably adding a method getViewHolder() to the interface and create another interface which specifies the behaviour of a ViewHolder.

What's the advantage of having public static inner classes of an interface/class?

I've noticed the following code pattern while browsing through some sources of my project's 3rd party libraries:
public interface MyInterface {
public static class MyClass1 implements MyInterface { ... }
public static class MyClass2 implements MyInterface { ... }
public static class MyClass3 implements MyInterface { ... }
}
Or this one:
public class MyBaseClass {
public static class MyClass1 extends MyBaseClass { ... }
public static class MyClass2 extends MyBaseClass { ... }
public static class MyClass3 extends MyBaseClass { ... }
}
Real life examples:
SwingX: org.jdesktop.swingx.decorator.HighlightPredicate (Source)
Substance: org.pushingpixels.substance.api.renderers.SubstanceDefaultTableCellRenderer (Source)
What's the advantage of having a code structure like this?
My first thought was "aggregation", but the same thing could be achieved using plain old packages. So when/why is it better to use public inner classes instead of a package?
I think this is reasoned by aggregation, maybe they're also not worth it to create a top level class. I do this sometimes if something is to small to create a package (to separate them from others) but the corresponding classes should only used within the context of the top level class. In my opinion this is a design decision.
The decorator pattern may be a nice example, they can be applied on the top-level class but are maybe so simple they're not worth it to be also top-level. You can easily show the ownership by using them as inner classes.
That's not that visible at first glance with packages. You directly see the dependent class/interface.
Further it's possible to access the private fields of a class, this could be useful and is more fine-grained than the package private scope.
One use I can think of is to provide ready-made implementations of the interface, publicly available to anyone, but still conceptually tied to the mother interface.
This makes sense only if the interface is simple (thus the inner implementation classes are small), there aren't too many of them, and most of the interface clients actually need them. Otherwise they clutter up the source file, making it harder to understand.
As far as classes and their inner classes are concerned (doesn't apply to interfaces) one difference is that the inner classes might use private members of the outer class, which is not the case if they were 'siblings' (separate top-level classes).
Example:
public class MyBaseClass {
private static String staticField = "outer";
public static class MyClass1 extends MyBaseClass {
public MyClass1() {
MyBaseClass.staticField = "inner1";
}
}
}
This won't work if you moved the MyClass out of the outer class.
Doing it this way can save you some extra source code files and makes it possible to give the class a nice hierarchical name, i.e. org.foo.bar.XY.Default instead of org.foo.bar.DefaultXY
An inner interface has to be static in order to be accessed. The interface isn't associated with instances of the class, but with the class itself, so it would be accessed with Foo.Bar, like so.
I think the reason of public static inner class is an additional tool or utility for "base" class.
When I asked my teacher about this many years ago, he replied that this way you can expose a totally different interface for the same object. Suppose that you have
public class MyBaseClass {
public static class MyClass1 {
public int myClassMethod1() {...}
public int myClassMethod2() {...}
}
...
public void myBaseMethod1() {...}
public void myBaseMethod2() {...}
}
Because instances of MyClass1 have access to the internals of MyBaseClass, you can expose the same internal behavior as an instance of MyClass1 or as an instance of MyBaseClass as you needed, even if the methods defined in both classes are totally different.
I never needed to use that, but is really interesting.

Categories