Is there is any feasible solution to have private constructor in abstract class..please advise
public abstract class BaseClass
{
private String member;
private BaseClass(String member)
{
this.member = member;
}
... abstract methods...
}
abstract class can have a private constructor. But that class cannot be extended by another class. Instead of adding a static inner class inside the abstract class and extends that abstract class.
abstract class Base{
public abstract void set();
private Base(){
System.out.println("Private Constructor!");
}
static class Derived extends Base{
public void set(){
System.out.println("set() method implemented!");
}
}
public static void main(String[] args){
new Base.Derived().set();
}
}
This defeats the purpose of abstract classes:
An abstract class must be subclassed to be used.
If a method is private, the subclass can't see it.
∴ It's effectively unreachable.
So, no.
EDIT #yshavit has found a hole in this logic which is very true - have a look at his comment (which should probably be an answer to the question?).
Related
public abstract class MyAbstractClass{
public MyAbstractClass(){
System.out.println("MyAbstractClass Constructor");
}
}
Can anyone help me with this problem?
You could use super() in the child class which extends this abstract class.
For ex:
public class MyAbstractClassImpl extends MyAbstractClass {
public MyAbstractClassImpl() {
super();
}
public static void main(String[] args) {
MyAbstractClassImpl obj = new MyAbstractClassImpl();
}
}
You can not call directly the constructor of an abstract class, i.e. you are not allowed to create instances of an abstract class. The constructor(s) should actually be protected and not public. So either you have an anonymous class overriding the abstract parts or a non-abstract sub-class of your abstract class. Then the constructor is explicitly called via super() as mentioned in the other posts.
Try using super() in a child class.
public abstract class MyAbstractClass{
public MyAbstractClass(){
System.out.println("MyAbstractClass Constructor");
}
}
public class Child extends MyAbstractClass{
public Child() {
super();
System.out.println("Child!");
}
public static void main(String[] args) {
new Child();
}
}
I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().
Java allows to assign subclass instances to class-typed fields, for example:
public class BaseClass {
}
public class SubClass extends BaseClass {
}
public class Example {
private BaseClass field1;
public void assign(SubClass subclass) {
field1 = subclass; // is OK
}
}
Java allows also to use interfaces as types. If we have an interface Fooable,
public interface Fooable {
void foo();
}
our Example class can have a field of type Fooable,
Fooable field2;
That is, it is possible to assign to field2 an instance of any class implementing Fooable interface.
But what if I want to tell the compiler that field3 has to be both an instance of BaseClass and implementation of Fooable interface? So that, if there is a class
public class FooSubClass extends BaseClass implements Fooable {
#Override
public void foo() {
// TODO
}
}
, I could assign to field3 instances of FooSubClass but not of SubClass?
Is it possible without using generics of any sort?
You can't do it like you are trying to.
You would need to define another class, perhaps an abstract class would suit you here:
public class abstract AbstractSubClass extends BaseClass implements Fooable {
...
}
Then FooSubClass:
public class FooSubClass extends AbstractSubClass {
...
}
Then your field is:
private AbstractSubClass field1;
Which will accept FooSubClass but not SubClass
Its the only way the compiler can guarantee that field1 will actually have implementations of all the required methods.
Here is a textbook example to illustrate:
public class Bird() {
public void eat() {
....
}
}
public interface FlyingBehaviour() {
void fly();
}
public abstract class FlyingBird extends Bird implements FlyingBehaviour() {
...
}
public class Eagle extends FlyingBird {
...
}
public class Penguin extends Bird {
...
}
FlyingBird bird = new Eagle();
bird.fly();
FlyingBird bird = new Penguin(); //Compilation Error - Penguins cant fly!
There is no way in java to ensure a object field inherits/implements two different classes.
Assuming you have control of all the objects here, the easiest fix would be for your base class to implement Fooable.
Since you are using a assign-method for setting the fields, you can check if it is correct type of object using instanceof in that method.
public void assign(BaseClass baseClass) {
if (baseClass instanceof foo)
field3 = baseClass;
}
You may throw an exception if class not implementing foo is provided.
edit:
Doh, didn't see that the fix should be for compile-time.
abstract class Base {
...
public class Inner {
private final String ownerClassName;
public Inner() {
...
}
}
public static class Super1 extends Base{
...
}
public static class Super2 extends Base{
...
}
}
I would like Inner.Inner() to set ownerClassName to the type of the enclosing class instance, e.g. "Super1" or "Super2".
How can this be done?
Base.this.getClass().getName()
First remove final from ownerClassName, make it private and provide only get method if you want.
Then follow the code:
Inner() {
ownerClassName = Base.this.getClass().getSimpleName();
}
This is more of a puzzle than question. I have the following code:
public class PrivateBaseConstructor {
public static class BaseClass {
private BaseClass() {
}
}
public static class DerivedClass extends BaseClass {
public DerivedClass() {
super(); // 1*
}
}
}
Here the call for super(); at 1* is allowed even though the base class constructor is private. If we write the classes as separate classes in same package:
BClass.java
public class BClass {
private BClass() {
}
}
DClass.java
public class DClass extends BClass {
public DClass() {
super(); // 2*
}
The compiler rightly gives an error at 2* since the base class constructor is not visible.
Why doesn't the compiler throw an error in my first scenario when both the classes are declared static within one class?
if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1
Because nested classes can see each others members. This has nothing to do with the static declarations. See the following example of your code with just nested inner classes (not static).
public class PrivateBaseConstructor {
public class BaseClass {
private BaseClass() {}
}
public class DerivedClass extends BaseClass {
public DerivedClass() {
super(); // 1*
}
}
public static void main(String[] args)
{
new PrivateBaseConstructor(). new DerivedClass();
}
}
Read more about nested classes here: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Because anything declared inside a class can access its private members, including inner classes. However, if you run PMD on your class, you'll find it suggests you change the visibility of the constructor to not-private.