I am having a problem understanding the best practises for creating classes and subclasses of them using inheritance.
Lets say, I want to implement 3 type of users in my project
Admin, User and Contact
Contact This is a user (with fullname, email, telephone, and other contact details) created by Admin or User and they CANNOT login to the system. Imagine they are only members of the private phonebook of each user.
User This is a user (again with fullname, email, telephone, and other contact details) which can be created by Admins. They can create Contacts but NOT other Users, and they CAN login to the system. They also can (and should) be members of the Admins' Phonebook.
Admin This is a user (again with fullname, email, telephone, and other contact details). They can create Users and/or Contacts and (of cource) they can login to the system (To keep things simple, lets say that these users are to be created through the submittion of a web form)
The (simplified) attributes for them are:
Contact: email, telephone, city, owner_id, date_in
User: email, telephone, city, owner_id, password, date_in
Admin: email, telephone, city, password, date_in
the database table (users) is something like:
I an not sure wow I should use the inheritance... Is the following scheme correct?
class Contact{
}
class User extends Contact{
}
class Admin extends User{
}
Some other problems: There should be a method in Admin and User that can create new users (lets name it create_user()). But each of them, should do different checks and allow for different options, and insert different type of things to the Database. What is the best practice to do so? Write a generic to the parent class and call it through the subclasses and then update the entry from the subclasses with the extra data? (eg: the Admins should also store the password to the database)
UPDATE: maybe I was not clear enough...
There is going to be PLENTY of common methods, irrelevant to the type of the user, and this is why I want inheritance. I also want a common db table.
My main problem here, is how to implement common methods that need to de different stuff... For example, this is the user_create() for class "User"
function user_create($email, $telephone){
dbquery("insert into users ....");
return insert_id();
}
I wonder if it would be nice practice to implement the same method for Admin like this:
function user_create($email, $telephone, $user_type, $password=''){
$new_id = parent::user_create($email, $telephone);
if (user_type == 'User'){
query("UPDATE users SET type='User', password='$password' WHERE id='$new_id'");
}
return $new_id;
}
That looks okay, although User as the base class would probably be a better prospect since the term is more generic and thus a wider application.
If you are going to have a set of classes that are going to be utilising the same method names but different implementations then you are better off using an interface. Something like:
Interface User
{
public function create();
}
class Contact implements User
{
public function create(){}
}
class Admin implements User
{
public function create(){}
}
.. and so on.
I, personally, would scrap the idea of extending each class and have an interface which acts as the relationship between the three.
interface Person
{
const CONTACT = 1;
const USER = 2;
const ADMIN = 3;
public function get_name();
public function get_mail();
public function get_city();
public function get_role();
...
}
class User implements Person
{
....
}
class Admin implements Person
{
....
}
class Contact implements Person
{
public function get_role()
{
return Person::CONTACT;
}
...
}
class John extends Contact
{
...
}
$john = new John;
$john->get_city();
if($john instanceof Person && $john->get_role() === Person::CONTACT)
{
...
}