Using an extend from a class or use composition - java

I have a abstract class called user and I'm wondering if i have to add another class that requires a user does it need to extend from the class below or do i need to reuse the user class via composition, all help is greatly appreciated.
public abstract class User implements Serializable {
protected String userName;
protected String emailAddress;
protected Date dob;
protected Password password;
// Initialisation Constructor
public User(String userName, String emailAddress,
int d, int m, int y,
String cPW, String uEPW, int noTries){
this.userName = username;
this.emailAddress = emailAddress;
this.dob = new Date(d, m, y);
}
this.password = new Password(cPW, uEPW, noTries);
// Assume that User also has ==>
// 1. a toString() method,
// 2. an equals() method, and
// 3. appropriate set() and get() methods
}

Its not clear why this class needs to be marked as abstract. An abstract class is one that cannot be instantiated, but you have written a constructor suggesting that it can?
Since an abstract class can't be instantiated on its own the only way it can be used is via inheritance.
In this scenario though, it would seem that your User class should not be abstract, and therefore other classes can simply use it via composition.
In general, prefer composition over inheritance where it makes sense, and if there is a need for inheritance, prefer to inherit purely abstract interfaces rather than classes containing implementation.

Inheritance is an "is-a" relationship.
Composition is a "has-a" relationship.
So if the new class is for example, Admin - An admin is-a user so use inheritance.
If the new class is something like UserAccount - use composition. The account is not a user but is associated with one.

Related

Why is this class better suited to be abstract instead of concrete?

Why is this Student class (a class which creates new student objects and assigns them unique ID's) better suited to be an abstract class rather than a concrete class? Each student object created is assigned it's own unique ID right, so why not just have the implementation for the graduate() method inside the class itself rather than implemented by an inherited class?
public abstract class Student {
protected int id;
private static int lastID = 0;
protected String firstName;
protected String familyName;
public Student(String firstName, String familyName) {
id = Student.nextID();
this.firstName = firstName;
this.familyName = familyName;
}
private static int nextID() {
return ++lastID;
}
public String toString() {
return firstName + " " + familyName;
}
// Generate string containing graduation information
public abstract String graduate();
}
The point would be: if you have various sub classes of Student, each one coming with a distinct differentiating attribute, say "major class".
Thus: this model would only allow students with a distinct "major class", therefore it would be meaningful to prevent creating "raw" Student objects that lack the corresponding "attribute".
But you have to understand: the reasons that determine how exactly you build your object model (which classes are abstract, and which ones are not) are coming out of what you intend to model.
In other words: the person writing this abstract Student class deemed that doing it exactly like this would be the best fit to the underlying requirements. In a different context, Student might very will be not abstract.
Generally a student class is written as abstract because of the types of students that you will have. i.e, high school, college, etc.
Some students have information that others don't. For instance, a college student may have a dorm number where a high school student wouldn't. The abstract class allows you to have more flexibility and not lock in a singular definition for student.

Java use 2 different object types as a field in a class

I have a class that can take different objects as a field to serve a similar purpose as below;
public class Project {
private int id;
private String title;
private String description;
private Implementer implementer;
.....
}
The implementer can be an individual (with fields such as firstName, lastName etc) or a company (with fields like companyName, industry etc). How do I make the implementer reference these two types (Individual and company). Note I do not want them to extend a common base class as they have no common fields.
Thanks
Create a marker interface:
public interface Implementor {
}
Change classes to implement this interface:
public class Company implements Implementor {
...
}
public class Individual implements Implementor {
...
}
Now both of the following assignments are valid:
Implementor implementor;
...
implementor = new Company();
implementor = new Individual();

Using composition as a workaround for inheritance in realm (android)?

In my app, I am using realm as a database platform. Realm has been great thus far- super easy to use, make queries, etc.-though, I have two qualms with it that I am trying to work around.
1) Realm does not support inheritance in model object classes which extend RealmObject.
- I am wondering if any developers out there have used composition as a workaround to the inheritance issue and if its worked for them.
- In other words, say I have a class "car" which extends RealmObject and then I have other classes such as "honda", "toyota", etc. Does it make sense to make separate car objects for each of these which contain either a honda, toyota, etc.?
2) Realm only supports getters and setters in model object classes
- My current workaround for this is by creating static methods within the model object classes.
- In other words, say I want to modify a honda's color, I would call something such as, Honda.updateColor(honda, blue).
- ^ Is this sloppy, or is this essentially the only way to handle such methods.
Really any feedback would be great!
A workaround I've used (in a nutshell)
Composition + Interface inheritance would allow you to get some polymorphism benefits back to your realmObjects.
Some code demonstration
interface IPerson {
String getName();
}
class Person extends RealmObject implements IPerson {
String name;
#Override
public String getName() {
return name;
}
}
interface IWorker extends IPerson {
int getSalary();
}
class Worker extends RealmObject implements IWorker {
Person person;
int salary;
#Override
public String getName() {
return person.getName();
}
#Override
public int getSalary() {
return salary;
}
}
Note
PrimaryKeys unfortunately have to be duplicated.
Check this answer of mine to get more details about this workaround.

Implementing a common interface from through different classes Java

I have the method here to add users to a database, based on given arguments (username, password, etc...)
public boolean addUser(String username, String password,
String f_name, String l_name, String email)
{
try
{
pstmnt = conn.prepareStatement("INSERT INTO users VALUES (user_id_increment.nextval,?,?,?,?)");
//do stuff...
And one here to add User objects to an ArrayList
public boolean addUser(User username)
{
if(users.contains(username))
//do stuff...
However, I'm trying to implement both cases through a common interface:
public interface Admin_DAO {
public void addUser();
//other methods...
I'm not sure how I could do this so that both classes can implement the same interface, given that they require different arguments.
Any ideas?
You can't implement an interface method with multiple different signatures.
Now that I've got that out of the way, let me clarify. An interface includes method signatures. You cannot implement that interface by changing the method signatures, because that fundamentally changes how Java sees the method. Java considers two methods with different signatures to be just as different as if they had different names. So you could write a class with two different addUser methods, but only one of them will override the method from the interface.
If your methods require totally different information, they probably shouldn't be implementing the same interface. However, if they require essentially the same information but in a different format, then you should write an interface that accepts a common format for that information, and then they can both implement it. So for instance, if it turns out that a User looks basically like this:
public User(String username, String password, String f_name, String l_name, String email) {
}
Then you can make your interface accept User objects.
public interface Admin_DAO {
public void addUser(User u);
}
And then you can implement that as needed in your different classes.
Change your Admin DAO to accept a User data object to accommodate any future changes to the number of arguments that you need to pass without affecting the public interface.
public interface AdminDAO {
public boolean addUser(User user);
}
Then implement this method as an overload in your User DAO. I also suggest that you store or pass your passwords around as char[] to prevent interning (addition into the Java string pool).
public class UserDAO implements AdminDAO {
public boolean addUser(User user) {
return addUser (user.getUsername(), user.getPassword(),
user.getFName(), user.getLName(), user.getEmail());
}
public boolean addUser(
String username, char[] password,
String f_name, String l_name, String email) {
// ...
}
}
EDIT : (extending an interface in respone to OP's comments below)
public interface IUser {
public boolean addUser(User user);
}
public interface AdminDAO extends IUser {
// other DAO methods
}
public class UserDAO implements AdminDAO {
// ...
}
public class UserUtil implements IUser {
public boolean addUser(User user) {
return addUser (user.getUsername(), user.getPassword(),
user.getFName(), user.getLName(), user.getEmail());
}
public boolean addUser(
String username, char[] password,
String f_name, String l_name, String email) {
// ...
}
}
Wrap the arguments in an interface.
public interface IUser{
String getName();
String getPassword();
//etc
}
Then have your Admin_DAO accept IUsers.
public interface Admin_DAO{
void addUser(IUser user);
boolean contains(IUser user);
}
This allows abstraction of Admin_DAO implementation details. It could be a database, or just an in memory datastructure. Having it accept data wrapped in an interface lets you pass in the same type of objects.
Ideally, there should be two classes. As the information used for both the method is same. You interface should look like this :
interface Admin_DAO{
public void addUser(User user);
}
And you should have two separate classes implementing this interface:
class AddUserToList implements Admin_DAO{
public void addUser(User user){
//add user to list
}
class addUserToDB implements Admin_DAO{
public void addUser(User user){
//add user to list
}
Each class should actually serve one purpose.
Short answer You cannot.
Here are a couple of my favorite paragraphs from GoF Design Patterns book. The text below should clear any query you have. You may want to read it a couple of times.
Every operation declared by an object specifies the operation's name,
the objects it takes as parameters,and the operation's return
value.This is known as the operation's signature.The set of all
signatures defined by an object's operations is called the interface
to the object. An object's interface characterizes the complete set of
requests that can be sent to the object. Any request that matches a
signature in the object's interface may be sent to the object.
A type is a name used to denote a particular interface. We speak of an
object as having the type "Window" if it accepts all requests for the
operations defined in the interface named "Window." An object may
have many types, and widely different objects can share a type.Part
of an object's interface may be characterized by one type, and other
parts by other types.Two objects of the same type need only share
parts of their interfaces. Interfaces can contain other interfaces as
subsets. We say that a type is a subtype of another if its interface
contains the interface of its supertype. Often we speak of a subtype
inheriting the interface of its supertype.
Interfaces are fundamental in object-oriented systems. Objects are
known only through their interfaces.There is no way to know any thing
about an object or to ask it to do anything without going through its
interface. An object's interface says nothing about its
implementation-different objects are free to implement requests
differently.

Why do we need constructors and private members in the abstract class?

Why do we need constructors and private members in the abstract class? It is not like we are ever going to create an instance of that class.
You will create instances, just instances of a derived class. Those derived classes will still need to call constructors, and can still call members of the abstract class - which may in turn use private members.
Here's an example (not a terribly useful one, but just to show the basic idea...)
public abstract class NamedObject
{
private final String name = name;
protected NamedObject(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
public class Computer extends NamedObject
{
private final int processorSpeed;
public Computer(String name, int processorSpeed)
{
super(name); // See, the constructor is useful
this.processorSpeed = processorSpeed;
}
public String toString()
{
return getName() + " (" + processorSpeed + ")";
}
}
I can't say I write abstract classes that often, generally preferring composition to inheritance, but when I do create them I certainly use constructors and private members.
Abstract classes provide a partial implementation of some interface. It's perfectly reasonable to consider that you might want to provide part of that implementation and disallow client code (concrete subclasses) from accessing the specifics - i.e. an extension of the principle of encapsulation.
Marking some members as private forces the inheriting class to call protected methods to access that partial implementation; providing a constructor allows for subclasses to initialise the parent's encapsulated state during their own construction.
Unlike an interface, an abstract class that defines data fields is in fact instantiated in the sense that these data fields are allocated. It is just that they are never instantiated on their own, they are instantiated as part of something bigger - the subclass. So when the subclass is built, the supertype is built as well, which is why you would need a constructor.
Depending on your hierarchy, your abstract class may have a meaning and state. For example, if your application is a school you may have the notion of a person (that has a name and an SSN), but you would have different subtypes for students and for faculty. Because both types of people share certain state structure (name and SSN) you would have both classes extend the Person class. But you would never simply instantiate a person directly.
In addition to Jon's answer, I'd like to mention that abstract classes still go well with composition, if you keep the subclass tree shallow. I.e. it is great for providing a common base class for a few closely related objects, but not for creating a gigantic tree of subclasses.
Why do you need private class? I think that you are confusing abstract classes with interfaces. Unlike interfaces, abstract classes can hold functionality. For example:
public class AbstractBase{
private int num;
public AbstractBase(int number){
this->num = number;
}
public int method(){
return ( this->num * this->templateMethod());
}
public abstract int templateMethod();
}
public class ConcreteDerived extends AbstractBase{
public ConcreteDerived(){
super(4);
}
public int templateMethod(){
return number; //number is the result of some calculation
}
}
In this example, you´ll never explicitly instantiate AbstractBase, but by declaring members and constructors, you can customize the functionality of your classes (this is called template method).
Assuming you're doing ad hoc code or prototyping, you do instantiate abstract classes (or maybe even interfaces) from time to time. They're called anonymous inner classes (one, two) and look like this:
// you have this...
public abstract class SomeClass {
public abstract String returnAString();
}
// ...and this...
public class OtherClass {
public void operate(SomeClass c) {
System.out.println(c.returnAString());
}
}
// ...so you do this:
OtherClass oc = new OtherClass();
// this is one of the reasons why you need to specify a constructor
oc.operate(new SomeClass() {
#Override
public String returnAString() {
return "I'm an anonymous inner class!";
}
});
This example is of course quite redundant but should expose the point. Some existing frameworks even rely on the heavy usage of this behaviour, namely Apache Wicket at least.

Categories

Resources