there is no default constructor available in Conferenceable [duplicate] - java

I know I'm asking some serious 101 question here...
I have some class Foo and a class Bar that extends Foo. In Foo I have a constructor that takes a set of parameters that it sets to its fields. Deriving classes such as Bar will typically not need to modify this. Now my IDE is giving me "There is no default constructor available in Foo". From a bit of Googling this appears to be because "constructors are not inherited". So all nice and well, but how do I now get this to work without duplicating this constructor in every deriving class? I'm assuming there is a more sane approach?

Use the super constructor:
public Bar(int a, double b, ...) {
super(a, b, ...);
}

So all nice and well, but how do I now get this to work without duplicating this constructor in every deriving class?
You do need to duplicate the constructor signatures - if you want the subclass to have constructors with the same signatures. But you don't need to duplicate the code - you just chain to the superclass constructor:
public Bar(int x, int y) {
super(x, y);
// Any subclass-specific code
}
Of course if you can work out the superclass parameters from a different set of parameters, that's fine. For example:
public Bar(int x) {
super(x, x * 2);
// Any subclass-specific code
}
You really need to work out what information is required to construct a Bar - that should dictate your constructors.
If this is a problem, it's possible that you're overusing inheritance. It's hard to say for sure without any idea of what your actual classes are, but you should look at using composition instead of inheritance. It's no panacea, but it can avoid this sort of thing.

No, there's no more "sane" approach. If your base class has no default constructor, then you must explicitly call the correct constructor from all the children classes.
Note this doesn't mean children classes need to have the exact same constructor than base class. For example this is perfectly valid:
class Foo {
protected int a;
protected int b;
protected Foo(final int a, final int b) {
this.a = a;
this.b = b;
}
}
class Bar extends Foo {
protected Bar() {
super(0,0);
}
}

The problem is solved with this:
class Foo{
Foo(int a, int b){}
}
class Bar extends Foo{
//Here must be a constructor OR declare a constructor in Foo without parameters
Bar(){super(1,1)} //this is an example
}
Other solution is:
class Foo{
Foo(int a, int b){}
Foo(){}
}
class Bar extends Foo{
}
Remember that if have a constructor with parameters in the SuperClass (in this case Foo), the implicit constructor on the child class (in this case Bar), always will have a implicit call to "Super()" (always have to be one unless explicit).

This error could also happen because you are calling your super constructor last. You might have to move it to be the first statement:
public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
mFragmentList = fragmentList;
super(manager);
}
public SectionsPagerAdapter(FragmentManager manager, List<Fragment> fragmentList) {
super(manager); --> this should come first
mFragmentList = fragmentList;
}

JVM will not provide a default constructor if you have provided one due to design reasons. What you can do define constructor in Bar with same signature and call super().
public Bar(int x,int y) {
super(x,y);
}

If parameters are not required and/or have default values then you can define default constructor (without parameters):
class Foo
{
public final int DEFAULT_A = 42;
protected int a;
protected int b;
public Foo(final int a, final int b)
{
this.a = a;
this.b = b;
}
// Is equal to new Foo(Foo.DEFAULT_A, 0);
public Foo()
{
this.a = this.DEFAULT_A;
}
}
class Bar extends Foo {}
class PiBar extends Bar
{
public final int DEFAULT_A = Math.PI;
}

Related

How to change the type of a variable of a super class in a subclass?

I am trying to create a constructor in a subclass, but I want to change one of its "inherited" variables to something more appropriate for the subclass without changing the functionality of the superclass (specifically, I am trying to change the type of the variable from a String to an Object I made in another class). Problem is, I can't directly change or access the variable because it is private in the superclass and there is no setters for this variable.
Is there some other way to effectively override the superclass constructor so I can modify this "inherited" variable without editing the superclass? Or should I not be inheriting from the superclass in this case, even though all the other methods would remain mostly untouched?
Essentially, what I want to do is something like this:
//This should not be changed
public class Super
{
private SomeArrayObject<String> o;
private String a;
private SomeObject b;
public Super(String a, SomeObject b)
{
this.a = a;
this.b = b;
o = new SomeArrayObject<String>();
}
public void someMethod()
{
//Does something
}
}
public class Sub
{
private SomeArrayObject<ObjectFromOtherClass> o; //Notice the diff?
public Sub(String a, SomeObject b)
{
super(a, b);
o = new SomeArrayObject<ObjectFromAnotherClass> o;
}
}
As a quick note, there is no "default constructor" in the superclass, so I can't just use super() and fill in the variables as needed.
I can see your problem. You can't modified it because is private right? and it's ok to be private variable, but in this such of cases, you can change the visibility of the variable to protected, so the subclass can see it and modify it.
Edit:
Seeing the new info, you have to do a few little changes more, add a generic, and makke the variable protected, an create a new generic class:
public class SuperClassGen<A> {
protected ArrayList<A> o;
private String a;
private int b;
public SuperClassGen(String a, int b) {
this.a = a;
this.b = b;
this.o = new ArrayList<A>();
}
}
public class SuperClass extends SuperClassGen<String> {
public SuperClass(String a, int b) {
super(a, b);
}
}
public class SubClass extends SuperClassGen<ObjectFromOtherClass> {
public SubClass(String a, int b) {
super(a, b);
}
}
That will allow change the type from the subclass in the constructor, without

java calling method before super

Assuming I have a super class that has 3 parameters in it's constructor and i am inheriting this class that also has a constructor with 3 parameters, and I want to call the super class constructor but before I want to do some logic on the sub class first, I can call a static method that receives those 3 parameters but I have to return only one, so this is the solution I came up with
public class someClass extends SuperClass {
public someClass(int a,int b,int c) {
super(func(a,b,c),b,c);
}
public static int func(int a,int b,int c){
//usage a b c
return a;
}
}
It seems a bit ugly and I was wondering if there is a better solution to use the parameters myself and then call super regularly. Note that i cannot change the Super class or that usages of the sub classes and therefore factory Design Pattern
To get the logic out of your constructor, you can easily create a factory method in your subclass:
public class SomeClass extends SuperClass {
private SomeClass(int a, int b, int c) {
super(a, b ,c);
}
public static SomeClass create(int a, int b, int c){
// calculate a for constructor
return new SomeClass(a, b, c);
}
}
Then you can create instances as follows:
SomeClass someClass = SomeClass.create(1, 2, 3);
In Java you are not allowed to execute another statement before the call to super. The trick you mentioned works, but you cannot refactor your code to have the call to func in a statement before the call to super.
In my experience, issues like this often hint at some design issue. Maybe you can solve the underlying problem by re-thinking about the responsibilities of the two involved classes.
You could also use the builder pattern
public class SomeClass extends SuperClass {
public static class Builder {
private int a, b, c;
public Builder withA(int a) {
this.a = a;
return this;
}
public Builder withB(int b) { ... }
public Builder withC(int c) { ... }
public SomeClass build() {
// logic goes here
return new SomeClass(...)
}
}
// hide this from public use, use Builder instead
protected SomeClass(int a, int b, int, c) {
super(a, b, c);
}
}
SomeClass someClass = new SomeClass.Builder().
withA(1).
withB(2).
withC(3).
build();

How can I get the data fields from subclass not superclass?

I have a super class named TestSuper
public class TestSuper {
int a = 0;
}
and I have 2 sub classes named TestSub and TestSub2 that extend TestSuper
public class TestSub extends TestSuper{
int a=1;
}
public class TestSub2 extends TestSuper{
int a=2;
}
in my main class i created a method that takes in a type TestSuper and returns the a value of it and in the main i display it on the console
public class Main {
public static void main(String[] args){
System.out.println(test(new TestSub())+" "+test(new TestSub2()));
}
public static int test(TestSuper b){
return b.a;
}
}
but the output is "0 0" instead of "1 2", what do I do?
You need to cast the reference so say which one you want.
public static int test(TestSuper b){
return b instanceof TestSub ? ((TestSub) b).a :
b instanceof TestSub2 ? ((TestSub2) b).a :
b.a;
}
If this seems needlessly complicated, it is. You should use polymorphism instead.
public class TestSuper {
int a = 0;
public int getA() { return a; }
}
public class TestSub extends TestSuper {
int a = 1;
public int getA() { return a; }
}
public class TestSub2 extends TestSuper {
int a = 2;
public int getA() { return a; }
}
public static int test(TestSuper b) {
return b.getA();
}
First understand the difference between hiding and overriding: https://docs.oracle.com/javase/tutorial/java/IandI/override.html
Then create a getter method in the base-class which you can override in the subclass.
You can look into the theory behind this, and then do the only reasonable thing -forget about writing such kind of code.
In good OOP you consider your fields to be part of your "secret" internal implementation. You don't use fields of sub classes in the super class context. Period.
You are even very conservative about making a field protected in the superclass and to use that in subclasses.
When you call test method like this:
test(new TestSub())+" "+test(new TestSub2())
You use upcasting. Upcasting seperates interface and implementation for an object. But for seperating interface and implementation and achieving true implementation in polymorphism, you must use polymorphic structures. The instance variables aren't polymorphic. Because of this, actually you call a variable which is in TestSuper class.
Only instance methods are polymorphic.

Java constructor with and without "this" before attributes

Maybe this question was asked here before, but I couldn't find it here.
It is basic question for Java developers, but here it goes: lets say I have class A with attribute a. What is the difference between these 2 constructors:
public abstract class A
{
protected String a;
public A()
{
a = "text";
}
}
The second one:
public abstract class A
{
protected String a;
public A()
{
this.a = "text"; //Here is the same with this
}
}
In the case you've given, there's no difference. Typically this is used to disambiguate between instance variables and local variables or parameters. For example:
public A(String a) {
this.a = a; // Assign value from parameter to local variable
}
or
public void setFoo(int foo) {
this.foo = foo;
}
Some people prefer to always use this.variableName to make it clearer to anyone reading the code; personally I find that if the class is well designed and the methods are short enough, it's usually clear enough already and the extra qualification just adds cruft. YMMV.
There is no difference in your specific case. But let's think about a constructor with an argument which has the same name as an attribute:
public abstract class A {
protected String a;
public A(String a) {
this.a = a;
}
}
In that specific case, this.a is referring to the a attribute of class A, while a is referring to the local parameter
There is no difference at all, unless there is shadowing involved:
public abstract class A
{
protected String a;
public A(String a)
{
this.a = a; // assign external one to inner
}
}
vs
public abstract class A
{
protected String a;
public A(String a)
{
a = a; // assign inner one to inner one
}
}
From docs and with your same example ,
The most common reason for using the this keyword is because a field is shadowed by a method or constructor parameter.
There is no difference between the constructor this reference is used to automatically pass address of the caller object.

"has private access" error with generics

I had a problem I could actually solve myself, but I still don't understand why my original code doesn't work, or if there is a more elegant solution than the one I found. I'm presenting a simplified version of my code here.
Consider the following abstract superclass X:
public abstract class X{
private int i;
public void m1(X x){
x.i = 1;
m2(x);
}
public abstract void m2(X x);
}
When m1 is called, we manipulate a private field of X of the instance passed, and then we call m2 with that instance.
I have several subclasses of X, they are all alike in the sense that they also declare private members which they manipulate. In order to achieve that, they always need to make a cast at the beginning of m2. Here is one of them:
public class Y extends X{
private int j;
public void m2(X x){
Y y = (Y) x;
y.j = 0;
}
}
But - I can guarantee that every call of m1 of an instance of a subclass of X will always have a parameter that is of the same type, e.g. when I have an instance of Y, the parameter of the method m1 will always be another instance of Y.
Because of that guarantee, I wanted to make the cast unnecessary, by introducing generics. This is how I want my subclasses to look like:
public class Y extends X<Y>{
private int j;
public void m2(Y y){
y.j = 0;
}
}
How does the superclass X have to look like now? My first try was that:
public abstract class X<T extends X<T>>{
private int i;
public void m1(T x){
x.i = 1;
m2(x);
}
public abstract void m2(T x);
}
But - that doesn't work, when I compile this, I get the following error:
X.java:6: error: i has private access in X
That's usually what you get you try to access the private members of another class. Obviously, Java doesn't recognise that T is always an instance of X as well, although I used "T extends X" in the declaration.
I fixed X like this:
public abstract class X<T extends X<T>>{
private int i;
public void m1(T x){
X<?> y = x;
y.i = 1;
m2(x);
}
public abstract void m2(T x);
}
At least I'm not using casts any more - but why is this extra assignment necessary? And why didn't the original code work? Also, I found it strange I had to use X<?> and could not use X<T>.
I believe we can reduce your question down to: Why does the following example fail to compile?
public class Foo {
private final String bar = "bar";
public <T extends Foo> void printFoo(T baz) {
System.out.println(baz.bar); //bar is not visible
}
}
It's a great question, and it sure took me by surprise. But we can actually remove Generics from the equation by noting that this doesn't work either:
public class Foo {
private final String bar = "bar";
public void printFoo(SubFoo baz) {
System.out.println(baz.bar); //bar is not visible
}
}
class SubFoo extends Foo {
}
In other words, the issue is that you're dealing with a subclass of Foo, not Foo itself. In the case of T, we don't know which subclass, but we know it is a subclass, or Foo.
As you've already figured out, the solution (surprisingly, at least to me) is to upcast:
System.out.println(((Foo)baz).bar);
Or for the Generic case:
public <T extends Foo> void printFoo(T baz) {
System.out.println(((Foo)baz).bar);
}
Is the cast so bad? Not really. It's certainly as good or better than avoiding the cast with an intermediate variable. As with any upcast, I would assume it would be removed by the compiler. It exists only as a hint to the compiler. We certainly don't have to worry about the safety of the cast, because the erasure of T is already Foo.
I can only assume this restriction is required so as to be clear about the access...since SubFoo could redeclare bar itself, it could become ambiguous which bar is being referred to, and so the cast is necessary. This is demonstrated in this complicated example:
public class Foo {
private final String bar = "hello";
static class SubFoo extends Foo {
private final String bar = "world";
}
public <T extends SubFoo> void printFoo(T baz) {
// System.out.println(baz.bar); // doesn't compile
System.out.println(((Foo)baz).bar); //hello
System.out.println(((SubFoo)baz).bar); //world
}
public static void main(String[] args) {
new Foo().printFoo(new SubFoo()); //prints "hello\nworld"
}
}
In this regard, it serves more as a qualifier than as a cast.

Categories

Resources