views:

223

answers:

2

I have classes SearchToUser and getFilesToWord. GetFilesToWord must inherit SearchToUser fields. Extending works if an empty construction in SearchToUser-class, otherwise:

cannot find symbol
symbol  : constructor SearchToUser()
location: class SearchToUser
public class GetFilesToWord extends SearchToUser{
       ^
1 error
make: *** [all] Error 1

I cannot understand why the empty constructor is required for extending.

[Added]

-- ALERT ERRR! USE COMPOSITION! Left as an "bad" example -- Composition VS Inheritance

It works but can you spot some weaknesses? Could I make the searchTerm private, create public method for it, create object of SearchToUser for the parameter in GetFilesToWord?

SearchToUser.java

public class SearchToUser {
   public static GetFilesToWord geader;
   public static String searchTerm;

   SearchToUser(String s){
       searchTerm=s.trim().toLowerCase();
       files=geader.getFilesToWord(s);
   }
   ...
}

GetFilesToWord.java

public class GetFilesToWord extends SearhToUser{
    public GetFilesToWord(){super(SearchToUser.searchTerm){
    ...
}
+2  A: 

Technically it's not... but if you don't explicitly provide a constructor in GetFilesToWord that explicitly calls the superclass constructor, Java will automatically insert a call to the no-argument superclass constructor. But if there isn't a no-argument superclass constructor, Java doesn't know what values to provide for the argument, and it can't automatically insert the call. You then have to manually call the superclass constructor with whatever values are appropriate.

The reason there needs to be a call to the superclass constructor at all is that, to put it one way, the operation of constructing a GetFilesToWord includes within it the operation of constructing a SearchToUser. For example, if you had instance variables in SearchToUser, they would need to be initialized when you create a GetFilesToWord as well as when you create just a plain SearchToUser.

David Zaslavsky
+13  A: 

The superclass doesn't need an empty constructor specifically. The subclass simply needs to call a constructor in the superclass. If the superclass has a public or protected no-arg constructor, this is called automatically, otherwise you need to be explicit.

Default constructor

public class Super {
}

public class Sub extends Super {
}

Here, Super specifies no constructor so one is added. Same for Sub. The above really looks like this:

public class Super {
  public Super() {
  }
}

public class Sub extends Super {
  public Sub() {
    super();
  }
}

Explicit no-arg constructor

public class Super {
  public Super() {
  }
}

public class Sub extends Super {
}

This is legal. A constructor is added to Sub that calls Super's default constructor.

Explicit constructor with arguments

public class Super {
  public Super(int i) {
  }
}

public class Sub extends Super {
}

This is a compile error like you have. Because Super has a constructor, no no-arg constructor is added automatically by the compiler. The way to deal with this is:

public class Super {
  public Super(int i) {
  }
}

public class Sub extends Super {
  public Sub() {
    super(0); // <-- explicit constructor call
  }
}
cletus
Can the parameter in the last thing "super(0)" be a variable? So every time you call GetFilesToWord, it changes according to the searchTerm.
HH
yes, but with the proviso that super(x) is called as the first line in the constructor.
Sanjay Manohar
@Sanjay: Does it imply you must use "static" field in order to call super with the value from SearchToUSer?
HH
@HH the `super()` call has to be the first line of the subclass's constructor. If so, the argument can come from an argument to `Sub`'s constructor or wherever.
cletus