Abstract class with nested class, is this possible? - java

If I write an abstract class, then nest a class in the abstract class, will I have access to its methods in any subclasses of the abstract class? I cannot find the answer anywhere..

Of course, access modifiers on inner classes obey the same rules as on fields and methods. It does not matter whether your class is abstract or concrete, as long as the nested class is either public, protected or the subclass is in the same package and the inner class is package private (default access modifier), the subclass will have access to it.
public abstract class AbstractTest {
// all subclasses have access to these classes
public class PublicInner {}
protected class ProtectedInner {}
// subclasses in the same package have access to this class
class PackagePrivateInner {}
// subclasses do not have access to this class
private class PrivateClass {}
}

class Abstract {
modifier1 class Nested { modifier2 int i = 0; }
Abstract() {
Nested n = new Nested();
n.i = 1;
}
}
class Sub extends Abstract {
Sub() {
Nested n = new Nested();
// have access as long you not choose "private"
// for `modifier1` or `modifier2`:
n.i = 5;
}
}

If the nested class is at least protected, we can access its methods (as long as the methods are public or we are in the same package and they are not private).
But you could have tried this out yourself easily :-)

Related

Extending a generic class into a static inner class

I am having issues extending an inner class with a generic abstract class.
I get an Non-static field cannot be referenced from a static context which is odd because the class itself is static, not necessarily the field value.
This is basically what I have:
// AbstractFoo.java
public abstract class AbstractFoo extends FrameLayout {
// Some logic
}
// AbstractBar.java
public abstract class AbstractBar<T> {
int someNumber;
// Some logic
}
// Foo.java
public class Foo extends AbstractFoo {
// Some logic
// Foo.InnerFoo.java
public static class InnerFoo extends AbstractBar<InnerFoo> {
public InnerFoo() {
super.someNumber = 5; // Compiler error HERE
}
}
}
For some reason I cannot access someNumber from InnerFoo. From my understanding this shouldn't cause any issues. The classes I'm extending btw is from an external library.
This is also all done with Android where minimum SDK is 24.
Thanks for the help!
The fields defined in your classes do not have an explicit access modifier which would use the default access modifier and limit the visibility to classes within the same package.
You should make the fields in AbstractBar as protected -
public abstract class AbstractBar<T> {
protected int someNumber;
}

how to access the outer class members in subclass wherin inner class is inherited

//below class is the example where in subclass extends the innerclass and from the subclass i am trying to access the methods of outer class i.e encapsulating class of inner class.
package innerClass;
public class outterclass {
private int outer=24;
protected int get_outer(){
return outer;
}
protected static class innerclass{
private int outer=25;
protected int get_outer(){
return outer;
}
}
}
package innerClass;
public class subclass_B extends outterclass.innerclass {
void parent_class_info_fetch(){
System.out.println(get_outer());
//i want to access the outer class get_outer method and how do i achieve that?
}
public static void main(String[] args) {
InheritanceStaticInnerClass_B isb=new InheritanceStaticInnerClass_B();
isb.parent_class_info_fetch();
}
}
Your innerclass is not an inner class. It is a static nested class and bears no special relationship to its enclosing class. You cannot reach an instance of the enclosing class because no such instance is available to innerclass or its subclasses.
If innerclass was indeed inner, then you would have to instantiate it with an enclosing instance:
outterclass outer = new outerclass();
subclass_B b = outer.new subclass_B();
Then, in parent_class_info_fetch() you could write
outterclass.this.get_outer()
to reach that method.
Of course, there would be several layers of bad practices in such code, so consider this just an academic execrise.
You should also learn about the basic naming conventions in Java.
The class outterclass.innerclass is a static class field, which means you don't necessarily have an enclosing instance of outterclass. On the other hand, the method get_outer of outterclass is an instance method, so you'll need the enclosing instance to call it.
With the class hierarchy you have, you'd have to make get_outer static (which requires making outer static as well).

What is an anonymous inner class?

When I tried to do some sample on an abstract class in Java I accidentally got some thing like anonymous inner class in Eclipse.
I have pasted the piece of code below. I don't understand how the abstract class is related to anonymous class.
package com.Demo;
abstract class OuterClass {
abstract void OuterClassMethod();
}
public abstract class InnerClass extends OuterClass {
public static void main(String[] args) {
InnerClass myInnerClass = new InnerClass() {
#Override
void OuterClassMethod() {
int OuterClassVariable = 10;
System.out.println("OuterClassVariable" + " " + OuterClassVariable);
}
};
}
}
A anonymous class is an "in-line" concrete implementation of a class, typically (but not necessarily) of an abstract class or an interface. It is technically a subclass of the extended/implemented super class.
Google for more.
In your example, your class (InnerClass) extends class (OuterClass) and implementing their abstract methods which is the typical behavior of extending an abstract class. In the same way if your class implementing any interfaces you have to override their abstract methods. This is the way to implement Anonymous inner class.
Basically, an anonymous class is an implementation that has no name -- hence the "anonymous" bit.
This particular bit is what makes your class anonymous:
InnerClass myInnerClass = new InnerClass() {
#Override
void OuterClassMethod() {
int OuterClassVariable = 10;
System.out.println("OuterClassVariable" + " " + OuterClassVariable);
}
};
In normal class instantiations, you would just use:
InnerClass myInnerClass = new InnerClass();
but in this case, you are specifying a new implementation of that class, by overriding a function (OuterClassMethod()) within it. In other instances of InnerClass, OuterClassMethod() will still have its original implementation, because you only adapted this particular instance of InnerClass, and did not store this new implementation in a new class.
If you don't want anonymous classes, do this instead:
Somewhere, specify AnotherInnerClass to extend InnerClass, and to override that function:
class AnotherInnerClass extends InnerClass {
#Override
void OuterClassMethod() {
int OuterClassVariable = 10;
System.out.println("OuterClassVariable" + " " + OuterClassVariable);
}
};
And then instantiate it as such:
AnotherInnerClass myInnerClass = new AnotherInnerClass();

Can we create public static abstract class in java?

I was searching in google for something and I got a code like
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
It's a nested class but wondering how it could be accessible ?
It must be a nested class: the static keyword on the class (not methods within it) is only used (and syntactically valid) for nested classes. Such static member classes (to use Java in a Nutshell's common nomenculture) hold no reference to the enclosing class, and thus can only access static fields and methods within it (unlike non-static ones; see any summary of nested classes in Java (also known as inner classes).
It can be accessible like this:
public class EnclosingClass {
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
EnclosingClass.LocationResult locationResult = ...
Only nested classes can be static. By doing so you can use the nested class without having an instance of the outer class.
So you could create a class extending it using extends Mainclass.LocationResult and use it with Mainclass.LocationResult instance = ...

Protected nested class not accessible to derived classes in other package

Here is what I'm trying to accomplish
File 1: ./net/Class1.java
package net;
public class Class1
{
protected static class Nested
{
}
}
File 2: ./com/Class2.java
package com;
import net.Class1;
public class Class2 extends Class1
{
Nested nested = new Nested();
}
Here is the error I'm getting
>javac ./net/Class1.java ./com/Class2.java
.\com\Class2.java:7: error: Nested() has protected access in Nested
Nested nested = new Nested();
Is this error expected? Am I doing something wrong?
Problem
Few important facts (which many people forget or are not aware of):
default constructors (including ones for static and non-static nested classes) have same visibility as visibility of class which they belong to. So in case of protected class Nested{...} its default constructor is also protected.
element with protected visibility can be accessed only from class which
belongs to same package as class which declared that element,
extends (explicitly or implicitly) class which declared it.
Your Class2 extends Class1 so it only have access to members of Class1 (including access to Nested type). But since it
doesn't extend Nested (even implicitly, it only inherits access to it since it is protected)
doesn't belong to same package as Nested
it can't access protected elements from Nested class (including constructors).
Solution:
To solve that problem make Nested constructor public by either
explicitly creating no-argument constructor of Nested class with public modifier:
package net;
public class Class1 {
protected static class Nested {
public Nested(){
//^^^^^^
}
}
}
making Nested class public (its default constructor will also become public - see point 1.)
package net;
public class Class1 {
public static class Nested {
//^^^^^^
}
}

Categories

Resources